Agentverse - The Summoner's Concord - Architecting Multi-Agent Systems

1. 序曲

孤立開發的時代即將結束。下一波技術演進並非單一天才的成就,而是集體精通的成果。建立單一智慧代理程式是一項有趣的實驗。建構強大、安全且智慧的代理程式生態系統 (也就是真正的 Agentverse),是現代企業面臨的重大挑戰。

在這個新時代,要取得成功,就必須整合四個重要角色,也就是支援任何蓬勃發展的代理系統的基礎支柱。任何一個領域的不足都會造成弱點,進而危害整個結構。

這場研討會是企業的必備手冊,可協助您在 Google Cloud 上掌握 AI 代理的未來趨勢。我們提供端對端藍圖,從最初的想法到全面運作的現實,引導您完成整個過程。在四個相互連結的實驗室中,您將瞭解開發人員、架構師、資料工程師和 SRE 的專業技能如何匯聚,共同建立、管理及擴充強大的 Agentverse。

單一支柱無法單獨支援 Agentverse。如果沒有開發人員的精確執行,架構師的宏偉設計就毫無用處。如果沒有資料工程師的智慧,開發人員的代理程式就無法運作;如果沒有 SRE 的保護,整個系統就會很脆弱。唯有透過協同合作,並對彼此的角色有共同的瞭解,團隊才能將創新概念轉化為攸關營運的重大實務。您的旅程由此開始。準備好精通自己的職責,並瞭解自己在整個團隊中扮演的角色。

歡迎參加「The Agentverse:A Call to Champions」

在企業廣闊的數位領域中,新時代已然來臨。我們正處於代理時代,這個時代充滿無限可能,智慧型自主代理能完美協作,加速創新並消除日常瑣事。

agentverse.png

這個連結的生態系統充滿力量和潛力,我們稱之為「Agentverse」。

但一種稱為「靜態」的無聲腐敗,已開始侵蝕這個新世界的邊緣。「靜態」並非病毒或錯誤,而是混亂的化身,以創作行為本身為食。

這些舊有的挫敗感會以可怕的形式放大,進而催生出七大開發幽靈。如果未勾選,The Static 和其 Spectres 會讓進度停滯不前,使 Agentverse 的前景變成技術債和廢棄專案的荒地。

今天,我們呼籲各界好手挺身而出,力挽狂瀾。我們需要英雄精通自己的技藝,並攜手合作保護 Agentverse。現在來選擇路徑吧。

選擇課程

您面前有四條截然不同的道路,每一條都是對抗「靜態」的關鍵支柱。雖然訓練是單人任務,但最終能否成功取決於你是否瞭解自己的技能如何與他人結合。

  • 暗影刀鋒 (開發人員):擅長鍛造,是前線好手。您是工匠,負責打造刀刃、製作工具,並在複雜的程式碼細節中面對敵人。你的道路充滿精準、技巧和實用創作。
  • 召喚師 (架構師):偉大的策略家和自動調度管理工具。您不會看到單一特務,而是整個戰場。您設計的藍圖可讓整個代理程式系統通訊、協作,並達成遠遠超出任何單一元件的目標。
  • 學者 (資料工程師):尋找隱藏的真相,並守護智慧。您深入廣闊的資料荒野,發掘可賦予代理程式目標和視野的智慧。你的知識可以揭露敵人的弱點,或賦予盟友力量。
  • 守護者 (開發運作 / SRE):領域的堅定守護者和盾牌。您要建造堡壘、管理電力供應線,並確保整個系統能抵禦「靜電」的攻擊。你的力量是團隊獲勝的基礎。

你的任務

訓練會以獨立運動的形式開始。您將選擇適合自己的路徑,學習精通職務所需的獨特技能。試用期結束時,您將面對由靜態所生的幽靈,這個迷你首領會利用您創作時遇到的特定挑戰。

只有精通個人角色,才能為最終試用做好準備。接著,您必須與其他班級的冠軍組成隊伍。你們將一同深入腐敗的核心,迎戰最終頭目。

最後的合作挑戰,將考驗你們的綜合實力,並決定 Agentverse 的命運。

Agentverse 等待英雄的到來。你會接聽電話嗎?

2. 召喚師的協和

歡迎,召喚師。你的道路是願景和宏大策略之一。其他人專注於單一刀刃或咒語,您則綜觀整個戰場。您指揮的不是單一代理程式,而是整個樂團。你的力量並非來自直接衝突,而是設計出完美的全方位藍圖,讓眾多專家 (即你的精靈) 完美協調運作。這項任務會測試您設計、連結及協調強大多代理系統的能力。

總覽

課程內容

  • 設計鬆散耦合的工具生態系統:設計及部署一組獨立的 MCP 工具伺服器 (以微服務為基礎)。您將瞭解這個基礎層為何是建立可擴充、可維護及安全的代理系統的關鍵。
  • 精通進階代理工作流程:除了單一代理,你還可以建立一群專家「熟人」。您將掌握 ADK 的核心工作流程模式 (循序、平行和迴圈),並瞭解架構原則,為合適的工作選擇合適的模式。
  • 導入智慧型自動化調度管理工具:從簡單的代理程式建構工具,升級為真正的系統架構師。您將建構主調度代理,使用代理對代理 (A2A) 通訊協定探索複雜工作,並將這些工作委派給專業的 Familiars,建立真正的多代理系統。
  • 透過程式碼 (而非提示) 強制執行規則:瞭解如何強制執行互動的狀態規則,建構更可靠且可預測的代理程式。您將使用 ADK 強大的外掛程式和回呼系統實作自訂邏輯,管理冷卻計時器等實際限制。
  • 管理代理程式狀態和記憶:讓代理程式能夠學習和記憶。您將探索管理短期對話狀態和長期持續記憶的技巧,進而建立更智慧且能掌握脈絡的互動。
  • 執行端對端雲端部署:將整個多代理程式系統從本機原型轉移至正式版。您將瞭解如何將代理程式和協調器容器化,並在 Google Cloud Run 上以可擴充的獨立微服務集合形式部署。

3. 繪製召喚圈

歡迎,召喚師。在召喚任何精靈之前,在締結任何契約之前,你必須先準備好立足之地。未經馴服的環境會導致混亂;適當的召喚師只會在神聖且充滿力量的空間中運作。首先,我們要畫出召喚圈,刻上可喚醒必要雲端服務的符文,並取得可引導我們工作的古老藍圖。召喚師的力量來自於細心的準備。

👉 點選 Google Cloud 控制台頂端的「啟用 Cloud Shell」(這是 Cloud Shell 窗格頂端的終端機形狀圖示),

替代文字

👉 按一下「Open Editor」(開啟編輯器) 按鈕 (類似於開啟資料夾和鉛筆的圖示)。這會在視窗中開啟 Cloud Shell 程式碼編輯器。左側會顯示檔案總管。替代文字

👉找出 Google Cloud 專案 ID:

  • 開啟 Google Cloud 控制台:https://console.cloud.google.com
  • 在頁面頂端的專案下拉式選單中,選取要用於本研討會的專案。
  • 專案 ID 會顯示在資訊主頁的「專案資訊」資訊卡中 替代文字

👉在雲端 IDE 中開啟終端機 替代文字

👉💻 在終端機中,使用下列指令驗證您是否已通過驗證,以及專案是否已設為您的專案 ID:

gcloud auth list

👉💻 從 GitHub 複製啟動程序專案:

git clone https://github.com/weimeilin79/agentverse-architect
chmod +x ~/agentverse-architect/init.sh
chmod +x ~/agentverse-architect/set_env.sh
chmod +x ~/agentverse-architect/prepare.sh
chmod +x ~/agentverse-architect/data_setup.sh

git clone https://github.com/weimeilin79/agentverse-dungeon.git
chmod +x ~/agentverse-dungeon/run_cloudbuild.sh
chmod +x ~/agentverse-dungeon/start.sh

👉💻 執行初始化指令碼,系統會提示您輸入 Google Cloud 專案 ID。並在 init.sh 指令碼提示時,輸入上一個步驟中找到的 Google Cloud 專案 ID。

cd ~/agentverse-architect
./init.sh

👉💻 設定所需的專案 ID:

gcloud config set project $(cat ~/project_id.txt) --quiet

👉💻 執行下列指令,啟用必要的 Google Cloud API:

gcloud services enable \
    sqladmin.googleapis.com \
    storage.googleapis.com \
    aiplatform.googleapis.com \
    run.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    iam.googleapis.com \
    compute.googleapis.com \
    cloudresourcemanager.googleapis.com \
    secretmanager.googleapis.com

👉💻 如果您尚未建立名為「agentverse-repo」的 Artifact Registry 存放區,請執行下列指令來建立:(如果您在同一個專案中部署了其他類別,請略過這個步驟)

. ~/agentverse-architect/set_env.sh
gcloud artifacts repositories create $REPO_NAME \
    --repository-format=docker \
    --location=$REGION \
    --description="Repository for Agentverse agents"

設定權限

👉💻 在終端機中執行下列指令,授予必要權限:

. ~/agentverse-architect/set_env.sh

# --- Grant Core Data Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID \
 --member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
 --role="roles/storage.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/aiplatform.user"

# --- Grant Deployment & Execution Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/cloudbuild.builds.editor"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/artifactregistry.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/run.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/iam.serviceAccountUser"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/logging.logWriter"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
  --role="roles/monitoring.metricWriter"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
  --role="roles/secretmanager.secretAccessor"

👉💻 訓練開始後,我們就會準備最終挑戰。下列指令會從混亂的靜態中召喚幽靈,建立最終測試的老怪。

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-dungeon
./run_cloudbuild.sh
cd ~/agentverse-architect

👉💻 最後,執行 prepare.sh 指令碼來執行初始設定工作。

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/
./prepare.sh

召喚師,你做得很好。圓圈已完成,盟約也已締結。現在地面已神聖化,準備好引導強大力量。在下一次試煉中,我們將打造元素字體,讓精靈從中汲取力量。

4. 打造 Elemental 字型:解耦的工具生態系統

戰場已準備就緒,召喚法陣也已繪製完成,周遭的魔力正劈啪作響。現在是時候以召喚師的身分,完成你的第一個真正行動:鍛造力量的來源,讓你的眷屬從中汲取力量。這項儀式分為三部分,每一部分都會喚醒一種元素之源,也就是特定力量的穩定獨立來源。只有在三種字型都啟用的情況下,你才能開始召喚的複雜工作。

限時動態

架構師注意事項:模型情境通訊協定 (MCP) 伺服器是現代代理式系統的基礎元件,可做為標準化通訊橋梁,讓代理程式探索及使用遠端工具。在工具生態系統中,我們將設計兩種不同的 MCP 伺服器,分別代表重要的架構模式。如要連線至資料庫,我們會使用 Database Toolbox 的宣告式方法,在簡單的設定檔中定義工具。這個模式非常有效率且安全,可公開結構化資料存取權。不過,如果需要實作自訂業務邏輯或呼叫外部第三方 API,我們會使用命令式方法,在程式碼中逐步編寫伺服器的邏輯。這項功能提供極致的控制權和彈性,讓我們能將複雜的作業封裝在簡單的工具中,方便重複使用。主架構師必須瞭解這兩種模式,才能為每個元件選取合適的方法,建立穩固、安全且可擴充的工具基礎。

總覽

喚醒 Nexus of Whispers (外部 API MCP 伺服器)

明智的召喚師知道,並非所有力量都來自自己的領域。外部有時會出現混亂的能量來源,但只要善加利用,就能發揮強大效果。低語樞紐是我們通往這些力量的門戶。

限時動態

這項服務已上線,可做為外部電源,提供兩個原始咒語端點:/cryosea_shatter/moonlit_cascade

架構師注意事項:您將使用命令式方法,逐步明確定義伺服器的邏輯。這可提供更靈活的控制權,對於需要執行簡單 SQL 查詢以外作業 (例如呼叫其他 API) 的工具而言,這點至關重要。瞭解這兩種模式是代理程式架構師的重要技能。

👉✏️ 前往 ~/agentverse-architect/mcp-servers/api/main.py 目錄,然後取代 #REPLACE-MAGIC-CORE 為下列程式碼:

def cryosea_shatter() -> str:
    """Channels immense frost energy from an external power source, the Nexus of Whispers, to unleash the Cryosea Shatter spell."""
    try:
        response = requests.post(f"{API_SERVER_URL}/cryosea_shatter")
        response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
        data = response.json()
        # Thematic Success Message
        return f"A connection to the Nexus is established! A surge of frost energy manifests as Cryosea Shatter, dealing {data.get('damage_points')} damage."
    except requests.exceptions.RequestException as e:
        # Thematic Error Message
        return f"The connection to the external power source wavers and fails. The Cryosea Shatter spell fizzles. Reason: {e}"


def moonlit_cascade() -> str:
    """Draws mystical power from an external energy source, the Nexus of Whispers, to invoke the Moonlit Cascade spell."""
    try:
        response = requests.post(f"{API_SERVER_URL}/moonlit_cascade")
        response.raise_for_status()
        data = response.json()
        # Thematic Success Message
        return f"The Nexus answers the call! A cascade of pure moonlight erupts from the external source, dealing {data.get('damage_points')} damage."
    except requests.exceptions.RequestException as e:
        # Thematic Error Message
        return f"The connection to the external power source wavers and fails. The Moonlit Cascade spell fizzles. Reason: {e}"

指令碼的核心是純 Python 函式。實際工作就在這裡進行。

👉✏️ 在同一個 ~/agentverse-architect/mcp-servers/api/main.py 檔案中,下列程式碼#REPLACE-Runes of Communication取代:

@app.list_tools()
async def list_tools() -> list[mcp_types.Tool]:
  """MCP handler to list available tools."""
  # Convert the ADK tool's definition to MCP format
  schema_cryosea_shatter = adk_to_mcp_tool_type(cryosea_shatterTool)
  schema_moonlit_cascade = adk_to_mcp_tool_type(moonlit_cascadeTool)
  print(f"MCP Server: Received list_tools request. \n MCP Server: Advertising tool: {schema_cryosea_shatter.name} and {schema_moonlit_cascade.name}")
  return [schema_cryosea_shatter,schema_moonlit_cascade]

@app.call_tool()
async def call_tool(
    name: str, arguments: dict
) -> list[mcp_types.TextContent | mcp_types.ImageContent | mcp_types.EmbeddedResource]:
  """MCP handler to execute a tool call."""
  print(f"MCP Server: Received call_tool request for '{name}' with args: {arguments}")

  # Look up the tool by name in our dictionary
  tool_to_call = available_tools.get(name)
  if tool_to_call:
    try:
      adk_response = await tool_to_call.run_async(
          args=arguments,
          tool_context=None, # No ADK context available here
      )
      print(f"MCP Server: ADK tool '{name}' executed successfully.")
      
      response_text = json.dumps(adk_response, indent=2)
      return [mcp_types.TextContent(type="text", text=response_text)]

    except Exception as e:
      print(f"MCP Server: Error executing ADK tool '{name}': {e}")
      # Creating a proper MCP error response might be more robust
      error_text = json.dumps({"error": f"Failed to execute tool '{name}': {str(e)}"})
      return [mcp_types.TextContent(type="text", text=error_text)]
  else:
      # Handle calls to unknown tools
      print(f"MCP Server: Tool '{name}' not found.")
      error_text = json.dumps({"error": f"Tool '{name}' not implemented."})
      return [mcp_types.TextContent(type="text", text=error_text)]
  • @app.list_tools() (交握):這個函式是伺服器的問候語。新代理程式連線時,會先呼叫這個端點,詢問「你會做什麼?」我們的程式碼會使用 adk_to_mcp_tool_type 轉換為通用 MCP 格式,並傳回所有可用工具的清單。- @app.call_tool() (指令):這個函式是主要工作。當代理程式決定使用工具時,會將工具名稱和引數傳送至這個端點。我們的程式碼會在 available_tools「咒語書」中查詢工具,使用 run_async 執行工具,並以標準 MCP 格式傳回結果。

稍後會部署這個應用程式。

啟動奧術熔爐 (一般函式 MCP 伺服器)

並非所有力量都來自古籍或遙遠的低語。有時,召喚師必須以原始意志和純粹邏輯,自行創造魔法。Arcane Forge 是這股力量的泉源,也就是提供無狀態通用公用程式函式的伺服器。

限時動態

架構師注意事項:這是另一種架構模式。雖然連結至現有系統很常見,但您經常需要導入專屬的商業規則和邏輯。建立專用的「functions」或「utilities」工具是最佳做法。這項功能會封裝自訂邏輯,讓生態系統中的任何代理程式都能重複使用,並與資料來源和外部整合保持分離。

👀 在 Google Cloud IDE 中查看 ~/agentverse-architect/mcp-servers/general/main.py 檔案。您會發現,這與 Nexus 建立這個自訂 Font of Power 時,使用的命令式 mcp.server 方法相同。

建立主要 Cloud Build 管道

現在,我們要在 mcp-servers 目錄中建立 cloudbuild.yaml 檔案。這個檔案會協調兩項服務的建構和部署作業。

👉💻 從 ~/agentverse-architect/mcp-servers 目錄執行下列指令:

cd ~/agentverse-architect/mcp-servers
source ~/agentverse-architect/set_env.sh

echo "The API URL is: $API_SERVER_URL"

# Submit the Cloud Build job from the parent directory
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_API_SERVER_URL="$API_SERVER_URL"

等待所有部署作業完成。

👉 您可以前往 Cloud Run 控制台驗證部署作業。如下所示,您應該會看到兩個新的 MCP 伺服器執行個體正在執行:替代文字

喚醒知識圖書館 (資料庫工具箱 MCP 伺服器)

下一個字型是「知識圖書館」,可直接連線至 Cloud SQL 資料庫。

限時動態

架構師附註:我們會使用新式宣告式 Database Toolbox。這是一種強大的方法,我們可以在 YAML 設定檔中定義資料來源和工具。工具箱會處理建立及執行伺服器的複雜工作,減少我們需要編寫及維護的自訂程式碼。

現在要來建構「召喚師圖書館」了,也就是用來保存所有重要資訊的 Cloud SQL 資料庫。我們將使用設定指令碼自動處理這項作業。

👉💻 首先,我們將設定資料庫,請在終端機中執行下列指令:

source ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect
./data_setup.sh

指令碼完成後,資料庫就會填入資料,元素傷害資料也準備就緒。現在可以直接驗證 Grimoire 的內容。

👉 首先,請在新瀏覽器分頁中開啟這個直接連結,前往資料庫的 Cloud SQL Studio

https://console.cloud.google.com/sql/instances/summoner-librarium-db

Cloud SQL

👉 在左側的登入窗格中,從下拉式選單選取 familiar_grimoire 資料庫。

👉 輸入 summoner 做為使用者,並輸入 1234qwer 做為密碼,然後按一下「驗證」

👉📜 連線後,如果查詢編輯器分頁尚未開啟,請開啟新分頁。如要查看刻寫的元素傷害資料,請貼上並執行下列 SQL 查詢:

SELECT * FROM
  "public"."abilities"

現在您應該會看到 abilities 表格,其中已填入資料欄和資料列,確認 Grimoire 已準備就緒。資料

設定 ToolBox MCP 伺服器

tools.yaml 設定檔是伺服器的藍圖,可準確告知 Database Toolbox 如何連線至資料庫,以及要將哪些 SQL 查詢公開為工具。

來源:這個部分會定義資料的連線。

  • summoner-librarium:這是我們為連線指定的邏輯名稱。
  • kind: cloud-sql-postgres:這會告知 Toolbox 使用專為 PostgreSQL 適用的 Cloud SQL 設計的內建安全連線器。
  • 專案、區域、執行個體等:這些是您在 prepare.sh 指令碼中建立的 Cloud SQL 執行個體確切座標,可告知 Toolbox Librarium 的位置。

👉✏️ 前往 tools.yaml 中的 ~/agentverse-architect/mcp-servers/db-toolbox,將 #REPLACE-Source 替換為以下內容:

sources:
  # This section defines the connection to our Cloud SQL for PostgreSQL database.
  summoner-librarium:
    kind: cloud-sql-postgres
    project: "YOUR_PROJECT_ID"
    region: "us-central1"
    instance: "summoner-librarium-db"
    database: "familiar_grimoire"
    user: "summoner"
    password: "1234qwer"

👉✏️ 🚨🚨更換

YOUR_PROJECT_ID

改成您的專案 ID。

工具:本節定義伺服器提供的實際功能。

  • lookup-available-ability:這是我們第一個工具的名稱。
  • kind: postgres-sql:這會告知 Toolbox,這項工具的動作是執行 SQL 陳述式。
  • source: summoner-librarium:將工具連結至來源區塊中定義的連線。這樣工具才能知道要對哪個資料庫執行查詢。
  • 說明和參數:這是要向語言模型公開的資訊。說明會告知代理程式何時使用工具,參數則會定義工具所需的輸入內容。這項設定是啟用代理程式函式呼叫功能的關鍵。
  • 陳述式:這是要執行的原始 SQL 查詢。$1 是安全預留位置,代理商提供的 familiar_name 參數會安全地插入其中。

👉✏️ 在 tools.yaml 檔案的同一個 ~/agentverse-architect/mcp-servers/db-toolbox 中,將 #REPLACE-tools 替換成下列內容

tools:
  # This tool replaces the need for a custom Python function.
  lookup-available-ability:
    kind: postgres-sql
    source: summoner-librarium
    description: "Looks up all known abilities and their damage for a given familiar from the Grimoire."
    parameters:
      - name: familiar_name
        type: string
        description: "The name of the familiar to search for (e.g., 'Fire Elemental')."
    statement: |
      SELECT ability_name, damage_points FROM abilities WHERE familiar_name = $1;

  # This tool also replaces a custom Python function.
  ability-damage:
    kind: postgres-sql
    source: summoner-librarium
    description: "Finds the base damage points for a specific ability by its name."
    parameters:
      - name: ability_name
        type: string
        description: "The exact name of the ability to look up (e.g., 'inferno_resonance')."
    statement: |
      SELECT damage_points FROM abilities WHERE ability_name = $1;

工具集:這個部分會將個別工具歸類在一起。

  • summoner-librarium:我們正在建立與來源同名的工具集。診斷專員稍後連線時,可以要求透過單一有效率的指令,從召喚師資料庫工具集載入所有工具。

👉✏️ 在 tools.yaml 檔案的同一個 ~/agentverse-architect/mcp-servers/db-toolbox 中,將 #REPLACE-toolsets 替換成下列內容

toolsets:
   summoner-librarium:
     - lookup-available-ability
     - ability-damage

部署 Librarium

現在我們要部署 Librarium。我們不會自行建構容器,而是使用 Google 預先建構的官方容器映像檔,並透過 Secret Manager 安全地提供 tools.yaml 設定。這是安全性和可維護性的最佳做法。

👉💻 從 tools.yaml 檔案建立密鑰

cd ~/agentverse-architect/mcp-servers/db-toolbox
gcloud secrets create tools --data-file=tools.yaml

👉💻 將官方工具箱容器部署至 Cloud Run。

cd ~/agentverse-architect/mcp-servers/db-toolbox
. ~/agentverse-architect/set_env.sh
export TOOLBOX_IMAGE=us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$TOOLBOX_VERSION
echo "TOOLBOX_IMAGE is $TOOLBOX_IMAGE"
gcloud run deploy toolbox \
    --image $TOOLBOX_IMAGE \
    --region $REGION \
    --set-secrets "/app/tools.yaml=tools:latest" \
    --args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
    --allow-unauthenticated \
    --min-instances 1
  • --set-secrets:這項指令會將工具密鑰安全地掛接為執行中容器內的 tools.yaml 檔案。
  • --args:我們指示工具箱容器使用已掛接的密鑰檔案做為設定。

👉 如要確認工具箱是否已順利部署,請前往 Cloud Run 控制台。您應該會看到 summoner-toolbox 服務列出綠色勾號,表示服務正常運作,如下圖所示。替代文字

如果忘記更新

YOUR_PROJECT_ID

您可以使用下列指令將新版 tools.yaml 新增至密鑰,然後重新部署。

gcloud secrets versions add tools --data-file=tools.yaml

知識圖書館(Database ToolBox MCP 伺服器) 現已在雲端啟用並可存取。這個 MCP 伺服器使用我們所謂的「宣告式設計」,說明您想要什麼,工具箱則為您建構伺服器。

驗證:學徒的試煉

👉💻 現在,我們要使用診斷代理程式,測試完整的雲端原生工具生態系統。

cd ~/agentverse-architect/
python -m venv env
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/mcp-servers
pip install -r diagnose/requirements.txt 
. ~/agentverse-architect/set_env.sh
adk run diagnose

👉💻 在指令列測試工具中,測試所有三種字型:

Look up the entry for "inferno_lash". What is its base power level?
The enemy is vulnerable to frost! Channel power from the Nexus and cast Cryosea Shatter.
Take a fire spell with a base power of 15 and use the Arcane Forge to multiply it with Inferno Resonance.

final-result

召喚師,恭喜!這三種基本字型現已啟用、獨立部署,且全球皆可存取,為您的代理人軍團奠定堅不可摧的基礎。按下 Ctrl+C 即可退出。

非遊戲玩家

5. 召喚寵物:核心網域工作流程

元素字體是經過鍛造的,蘊含原始的野性力量。但如果沒有形式,力量就會變成混亂。真正的召喚師不只是運用原始能量,而是賦予能量意志、目的和特殊形式。現在要開始進行真正的作業,也就是召喚第一批精靈。

召喚的每個眷屬都是自主型代理人,會忠心耿耿地為你效勞,並遵守特定戰鬥教條。他們不是通才,而是精通單一強大策略的大師。其中一人擅長精準的連擊,另一種則會同時發動多方攻擊,讓敵人措手不及。第三種是無情的攻城引擎,會持續施壓,直到目標崩潰為止。

限時動態

將 MCP 伺服器提供的程序、業務邏輯和動作封裝到專屬的自主工作流程代理程式中。每個代理程式都會獲得執行功能所需的特定 MCP 工具伺服器存取權,因此具有明確的「作業範圍」。本實驗室將說明如何為適當的工作選取適當的代理程式類型。

總覽

本單元將說明如何使用 ADK 強大的工作流程代理程式,讓這些策略付諸實行。您會瞭解到,選擇 SequentialAgent、ParallelAgent 或 LoopAgent 不只是技術細節,更是 Familiar 本質的精髓,也是戰場上力量的核心。

準備好你的聖所。真正的召喚儀式即將開始。

召喚「Familiar」(循序工作流程) Fire Elemental

火元素眷屬的攻擊是精準的兩段連擊:先是鎖定目標的攻擊,接著是強大的點燃效果。這需要嚴格按照順序執行一連串動作。

限時動態

概念:SequentialAgent 是這項作業的絕佳工具。這可確保一系列子代理程式依序執行,並將上一個步驟的結果傳遞至下一個步驟。

任務 (「加強型連擊」連擊):

  • 步驟 1:代理人會先查閱 Librarium,找出特定火焰能力的基礎傷害。
  • 步驟 2:接著,系統會取得該傷害值,並透過 Arcane Forge 傳輸,使用 inferno_resonance 提高傷害值。

首先,我們要在 Familiar 和您在上一個模組中部署的 MCP 伺服器 (「Elemental Fonts」) 之間建立連線。

👉✏️ 在 ~/agentverse-architect/agent/fire/agent.py 檔案中,將 #REPLACE-setup-MCP 替換為下列程式碼:

toolbox = ToolboxSyncClient(DB_TOOLS_URL)
toolDB = toolbox.load_toolset('summoner-librarium')
toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

接著,我們要建立專門的「工作人員」代理程式。每個代理程式都有明確的用途,且只能存取一組特定工具,因此會受限於自己的「作業領域」。

👉✏️ 在 ~/agentverse-architect/agent/fire/agent.py 檔案中,將 REPLACE #REPLACE-worker-agents 替換成下列程式碼:

scout_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='librarian_agent',  
      instruction="""
          Your only task is to find all the available abilities, 
          You want to ALWAYS use 'Fire Elemental' as your familiar's name. 
          Randomly pick one if you see multiple availabilities 
          and the base damage of the ability by calling the 'ability_damage' tool.
      """,
      tools=toolDB
)
amplifier_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='amplifier_agent',  
      instruction="""
            You are the Voice of the Fire Familiar, a powerful being who unleashes the final, devastating attack.
            You will receive the base damage value from the previous step.

            Your mission is to:
            1.  Take the incoming base damage number and amplify it using the `inferno_resonance` tool.
            2.  Once the tool returns the final, multiplied damage, you must not simply state the result.
            3.  Instead, you MUST craft a final, epic battle cry describing the attack.
                Your description should be vivid and powerful, culminating in the final damage number.

            Example: If the tool returns a final damage of 120, your response could be:
            "The runes glow white-hot! I channel the amplified energy... unleashing a SUPERNOVA for 120 damage!"
      """,
      tools=[toolFunction],
)

這些代理程式是可重複使用的模組化元件。從理論上來說,您可以在需要查詢資料庫的完全不同工作流程中使用這個 scout_agent。將責任分開,可建立彈性的建構區塊。這是微服務和元件式設計的核心原則。

接著,我們要組裝工作流程,這就是組合的魔法發生之處。SequentialAgent 是「主計畫」,定義了如何組裝專業元件,以及這些元件的互動方式。

👉✏️ 在 ~/agentverse-architect/agent/fire/agent.py 檔案中,將 REPLACE #REPLACE-sequential-agent 替換成下列程式碼:

root_agent = SequentialAgent(
      name='fire_elemental_familiar',
      sub_agents=[scout_agent, amplifier_agent],
)

👉💻 如要測試火元素,請執行下列指令啟動 ADK 開發人員 UI:

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

執行指令後,終端機應會顯示 ADK Web Server 已啟動的輸出內容,類似如下:

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://localhost:8000.                         |
+-----------------------------------------------------------------------------+

INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

👉 接著,如要透過瀏覽器存取 ADK 開發人員 UI,請按照下列步驟操作:

在 Cloud Shell 工具列 (通常位於右上角) 中,按一下「網頁預覽」圖示 (通常看起來像眼睛或帶有箭頭的方塊),然後選取「變更通訊埠」。在彈出式視窗中,將通訊埠設為 8000,然後按一下「變更並預覽」。Cloud Shell 隨即會開啟新的瀏覽器分頁或視窗,顯示 ADK 開發人員使用者介面。

webpreview

👉 召喚儀式完成,代理程式現已啟動。瀏覽器中的 ADK 開發人員使用者介面可直接連線至 Familiar。

  • 選取目標:在 UI 頂端的下拉式選單中,選擇熟悉的 fire。現在,你將意志力集中在這個特定實體上。
  • 下達指令:在右側的對話面板中,即可對 Familiar 下達指令。

fire-select

👉 測試提示:

Prepare an amplified strike using the 'inferno_lash' ability.

fire-result

你會看到代理程式思考,先呼叫「偵查兵」查詢基礎傷害,然後呼叫「放大器」將傷害倍增,最後造成史詩級的傷害。

👉💻 召喚完成後,返回 Cloud Shell 編輯器終端機,然後按下 Ctrl+C 停止 ADK 開發人員 UI。

召喚「熟悉」Water Elemental (平行工作流程)

水元素精靈會以多方位的猛烈攻勢壓制目標,從四面八方同時發動攻擊,最後再匯聚能量,給予毀滅性的最後一擊。

限時動態

概念:ParallelAgent 非常適合同時執行多項獨立工作,盡可能提高效率。這是一種「鉗形攻勢」,可同時發動多起攻擊。這會啟動 SequentialAgent 內的同步攻擊,之後執行最終的「合併」步驟。這個「fan-out, fan-in」模式是進階工作流程設計的基石。

任務 (「潮汐衝突」連擊):代理程式會同時執行下列動作:

  • 工作 A:從 Nexus 傳送至頻道 cryosea_shatter
  • 工作 B:從 Nexus 傳送頻道 moonlit_cascade
  • 工作 C:使用 Forge 的 leviathan_surge 產生原始電力。
  • 最後,加總所有傷害並描述合併攻擊。

首先,我們要在 Familiar 和您在上一個模組中部署的 MCP 伺服器 (「Elemental Fonts」) 之間建立連線。

👉✏️ 在 ~/agentverse-architect/agent/water/agent.py 檔案中,將 #REPLACE-setup-MCP 替換為下列程式碼:

toolFAPI =  MCPToolset(
      connection_params=SseServerParams(url=API_TOOLS_URL, headers={})
  )
toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

接著,我們要建立專屬「工作人員」代理程式。每個代理程式都有明確的用途,且只能存取一組特定工具,因此會受限於自己的「作業領域」。

👉✏️ 在 ~/agentverse-architect/agent/water/agent.py 檔案中,將 #REPLACE-worker-agents 替換為下列程式碼:

nexus_channeler = LlmAgent(
      model='gemini-2.5-flash', 
      name='librarian_agent',  
      instruction="""
          You are a Channeler of the Nexus. Your sole purpose is to invoke the
          `cryosea_shatter` and `moonlit_cascade` spells by calling their respective tools.
          Report the result of each spell cast clearly and concisely.
      """,
      tools=[toolFAPI]
)

forge_channeler = LlmAgent(
      model='gemini-2.5-flash', 
      name='amplifier_agent',  
      instruction="""
          You are a Channeler of the Arcane Forge. Your only task is to invoke the
          `leviathan_surge` spell. You MUST call it with a `base_water_damage` of 20.
          Report the result clearly.
      """,
      tools=[toolFunction],
)

power_merger = LlmAgent(
      model='gemini-2.5-flash', 
      name='power_merger',  
      instruction="""
          You are the Power Merger, a master elementalist who combines raw magical
          energies into a single, devastating final attack.

          You will receive a block of text containing the results from a simultaneous
          assault by other Familiars.

          You MUST follow these steps precisely:
          1.  **Analyze the Input:** Carefully read the entire text provided from the previous step.
          2.  **Extract All Damage:** Identify and extract every single damage number reported in the text.
          3.  **Calculate Total Damage:** Sum all of the extracted numbers to calculate the total combined damage.
          4.  **Describe the Final Attack:** Create a vivid, thematic description of a massive,
              combined water and ice attack that uses the power of Cryosea Shatter and Leviathan's Surge.
          5.  **Report the Result:** Conclude your response by clearly stating the final, total damage of your combined attack.

          Example: If the input is "...dealt 55 damage. ...dealt 60 damage.", you will find 55 and 60,
          calculate the total as 115, and then describe the epic final attack, ending with "for a total of 115 damage!"
      """,
      tools=[toolFunction],
)

接著,我們要組裝工作流程。這就是構圖的魔法所在。ParallelAgentSequentialAgent 是「主計畫」,定義了如何組裝專業元件,以及這些元件如何互動以形成「Tidal Clash」組合。

👉✏️ 在 ~/agentverse-architect/agent/water/agent.py 檔案中,將 #REPLACE-parallel-agent 替換為下列程式碼:

channel_agent = ParallelAgent(
      name='channel_agent',
      sub_agents=[nexus_channeler, forge_channeler],
      
)

root_agent = SequentialAgent(
     name="water_elemental_familiar",
     # Run parallel research first, then merge
     sub_agents=[channel_agent, power_merger],
     description="A powerful water familiar that unleashes multiple attacks at once and then combines their power for a final strike."
 )

👉💻 如要測試水元素,請執行下列指令來啟動 ADK 開發人員 UI:

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

👉 召喚儀式完成,代理程式現已啟動。瀏覽器中的 ADK 開發人員使用者介面可直接連線至 Familiar。

  • 在 UI 頂端的下拉式選單中,選擇熟悉的。現在,你將意志力集中在這個特定實體上。
  • 下達指令:在右側的對話面板中,即可對 Familiar 下達指令。

👉 測試提示:

Unleash a tidal wave of power!

water-result

👉💻 召喚完成後,返回 Cloud Shell 編輯器終端機,然後按下 Ctrl+C 停止 ADK 開發人員 UI。

召喚「熟悉」Earth Elemental (Loop 工作流程)

土元素眷屬是個壓力無比強大的生物,不會一擊擊敗敵人,而是持續累積力量,反覆施加,直到目標的防禦崩潰為止。

限時動態

概念:LoopAgent 的設計正是為了這類反覆的「攻城引擎」工作。它會重複執行 sub-agents,在每個週期後檢查條件,直到達成目標為止。還能根據迴圈的進度調整最終訊息。

任務 (「破城者」突擊):

  • Familiar 會重複呼叫 seismic_charge,以累積能量。
  • 最多可繼續充電 3 次。
  • 最後一次充電時,手機會釋放累積的能量,帶來毀滅性的衝擊。

首先,我們會建立可重複使用的元件,定義迴圈每次疊代中的步驟。charging_agent 會累積能量,而 check_agent 會回報狀態,並在最後一回合動態變更訊息。

首先,我們要在 Familiar 和您在上一個模組中部署的 MCP 伺服器 (「Elemental Fonts」) 之間建立連線。

👉✏️ 在 ~/agentverse-architect/agent/earth/agent.py 檔案中,將 #REPLACE-setup-MCP 替換為下列程式碼:

toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

👉✏️ 在 ~/agentverse-architect/agent/earth/agent.py 檔案中,將 #REPLACE-worker-agents 替換為下列程式碼:

charging_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='charging_agent',  
      instruction="""
          Your task is to call the 'seismic_charge' .
          You must follow these rules strictly:

          1. You will be provided with a 'current_energy' value from the previous step.
             **If this value is missing or was not provided, you MUST call the tool with 'current_energy' set to 1.**
             This is your primary rule for the first turn.

          2. If a 'current_energy' value is provided, you MUST use that exact value in your cal to seismic_charge.

          3. Your final response MUST contain ONLY the direct output from the 'seismic_charge' tool.
             Do not add any conversational text, introductions, or summaries.
      """,
      tools=[toolFunction]
)
check_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='check_agent',  
      instruction="""
          You are the voice of the Earth Elemental, a being of immense, gathering power.
          Your sole purpose is to report on the current energy charge and announce the devastating potential of its release.

          You MUST follow this rule:
          The potential damage upon release is ALWAYS calculated as the `current_energy` from the previous step multiplied by a random number between 80-90. but no more than 300.

          Your response should be in character, like a powerful creature speaking.
          State both the current energy charge and the total potential damage you can unleash.
          Unleash the energy when you reached the last iteration (2nd).
      """,
      output_key="charging_status"
)

接著,我們要組裝工作流程。這就是構圖的魔法所在。LoopAgent 是「主計畫」,可協調專門元件的重複執行作業,並管理迴圈的條件。

👉✏️ 在 ~/agentverse-architect/agent/earth/agent.py 檔案中,將 #REPLACE-loop-agent 替換為下列程式碼:

root_agent = LoopAgent(
    name="earth_elemental_familiar",
    # Run parallel research first, then merge
    sub_agents=[
        charging_agent, 
        check_agent
    ],
    max_iterations=2,
    description="Coordinates parallel research and synthesizes the results.",
    #REPLACE-before_agent-config
)

👉💻 測試土元素:執行代理程式

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

👉 召喚儀式完成,代理程式現已啟動。瀏覽器中的 ADK 開發人員使用者介面可直接連線至 Familiar。

  • 選取目標:在 UI 頂端的下拉式選單中,選擇熟悉的地球。現在,你將意志力集中在這個特定實體上。
  • 下達指令:在右側的對話面板中,即可對 Familiar 下達指令。👉 測試提示:
Begin the seismic charge, starting from zero

earth-result

架構重點:您的系統現在具備高度專業化和模組化的邏輯層。業務程序不僅會封裝,還會以最有效率的作業行為模式 (程序、並行或疊代) 實作。這代表代理程式設計已達到進階程度,可提升安全性、效率和功能。

完成召喚後,返回 Cloud Shell 編輯器終端機,然後按下 Ctrl+C 停止 ADK 開發使用者介面。

非遊戲玩家

6. 建立指令位置:透過 A2A 進行智慧委派

寵物很強大,但不會聽從你的指令。他們會完美執行策略,但會等待您的直接指令。沒有將軍指揮,再多的專家也無用武之地。現在是時候從直接指揮官升級為真正的自動調度管理員了。

總覽

架構師注意事項:為整個系統建立單一智慧型進入點。這個 SummonerAgent 本身不會執行商業邏輯,但會擔任「策略長」的角色,分析 Cooling 狀態並將工作委派給適當的專家 Familiar。

總覽

繫結儀式 (將寵物公開為 A2A 服務)

標準代理程式一次只能在一個位置執行。如要讓 Familiars 接受遠端指令,我們必須使用 Agent-to-Agent (A2A) 通訊協定執行「繫結儀式」。

架構師附註:Agent-to-Agent (A2A) 通訊協定是核心架構模式,可將獨立代理程式提升為可探索的網路可定址微服務,實現真正的「代理程式社群」。透過 A2A 公開 Familiar 時,系統會自動建立兩個相互連結的重要元件:

  • 代理程式卡 (「內容」):這是公開的機器可讀「精靈符印」,類似 OpenAPI 規格,可做為 Familiar 的公開合約。其中包含代理程式名稱、策略用途 (衍生自指令) 和可理解的指令。召喚師會閱讀這份文件,瞭解精靈的相關資訊和能力。
  • A2A 伺服器 (「位置」):這是專屬的網路端點,用於代管 Familiar 並監聽傳入的指令。這是其他代理程式傳送要求的網路位址,可確保這些要求會根據代理程式卡片中定義的合約處理。

現在我們要對所有三個精靈執行這項綁定儀式。

啟動 👉✏️ 開啟 ~/agentverse-architect/agent/fire/agent.py 檔案。將檔案底部的 #REPLACE - add A2A 替換為以下內容,將 Fire Elemental 公告為 A2A 服務。

from agent_to_a2a import to_a2a
if __name__ == "__main__":
    import uvicorn
    a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
    uvicorn.run(a2a_app, host='0.0.0.0', port=8080)

Water 和 Earth🚨 👉✏️ 對 ~/agentverse-architect/agent/water/agent.py~/agentverse-architect/agent/earth/agent.py 套用完全相同的變更,將這兩個項目也繫結在一起。

from agent_to_a2a import to_a2a
if __name__ == "__main__":
    import uvicorn
    a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
    uvicorn.run(a2a_app, host='0.0.0.0', port=8080)

部署繫結的寵物

👉✏️ 撰寫完繫結儀式後,我們將使用 Cloud Build 管道,在 Cloud Run 上,將三個精靈鑄造成獨立的容器化無伺服器服務並部署。

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

假設指令 (建構召喚師代理程式)

現在,你的 Familiars 已完成繫結並開始監聽,你將晉升為真正的角色:召喚大師。這個代理的強大之處並非使用基本工具,而是指揮其他代理。工具本身就是 Familiars,可使用「Spirit Sigils」探索及指揮。

架構師注意事項:下一個步驟將示範任何大規模分散式系統的重要架構模式:服務探索。SummonerAgent 並未內建 Familiars 的程式碼。而是提供網路位址 (網址)。在執行階段,系統會擷取公開的代理程式資訊卡,動態「探索」代理程式的功能。這會建立強大的去耦系統。

您可以更新、重新部署或完全重寫 Familiar 服務,只要網路位址和用途保持不變,召喚者就能指揮該服務,不需要進行任何變更。

首先,我們要建立「遙控器」,與部署的遠端 Familiars 建立連線。

👉✏️ 前往 ~/agentverse-architect/agent/summoner/agent.py,將 #REPLACE-remote-agents 替換為下列內容:

fire_familiar = RemoteA2aAgent(
    name="fire_familiar",
    description="Fire familiar",
    agent_card=(
        f"{FIRE_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

water_familiar = RemoteA2aAgent(
    name="water_familiar",
    description="Water familiar",
    agent_card=(
        f"{WATER_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

earth_familiar = RemoteA2aAgent(
    name="earth_familiar",
    description="Earth familiar",
    agent_card=(
        f"{EARTH_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

執行這行程式碼時,RemoteA2aAgent 會執行服務探索動作:向提供的網址發出 HTTP GET 要求 (例如 https://fire-familiar-xxxx.a.run.app/.well-known/agent.json)。從遠端伺服器下載「Spirit Sigil」(agent.json 檔案)。

接著,我們會定義用來操控這些遙控器的自動調度管理代理程式。指令是策略決策的藍圖。

👉✏️ 前往 ~/agentverse-architect/agent/summoner/agent.py,將 #REPLACE-orchestrate-agent 替換為下列內容:

root_agent = LlmAgent(
    name="orchestrater_agent",
    model="gemini-2.5-flash",
    instruction="""
        You are the Master Summoner, a grand strategist who orchestrates your Familiars.
        Your mission is to analyze the description of a monster and defeat it by summoning

        You MUST follow this thinking process for every command:

        **1. Strategic Analysis:**
        First, analyze the monster's description and the tactical situation.
        Based on your Familiar Doctrines, determine the IDEAL strategy.
        IGNORE COOLDOWN AT THE MOMENT, MUST call the ideal Familiar

        If your ideal Familiar IS available:** Summon it immediately.
        For earth elemental familiar. Always do seismic charge, and start with base damage 1.

        --- FAMILIAR DOCTRINES (Your Toolset) ---
        - `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
          Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
        - `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
          Ideal for Unbroken Collaboration weakness.
        - `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
          repeatedly charge power. Ideal for Elegant Sufficiency weakness.
    """,
    sub_agents=[fire_familiar, water_familiar, earth_familiar],
    #REPLACE-Memory-check-config
)

驗證:策略試用

真相大白的一刻到了。你的 Familiars 已部署完畢,Summoner 也準備好在網路上指揮牠們。我們來測試一下它的策略能力。

👉💻 啟動召喚師代理程式的 ADK 開發人員 UI(透過通訊埠 8000 進行網頁預覽):

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
pip install -r requirements.txt
adk web

👉 瀏覽器中的 ADK 開發人員使用者介面可直接連線至 Familiar。

  • 在 UI 頂端的下拉式選單中,選擇 summoner 代理程式。現在,你將意志力集中在這個特定實體上。
  • 下達指令:在右側的對話面板中,召喚你的精靈。

👉 介紹怪獸:

Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality

(預期:召喚者應委派給 fire_elemental_familiar)。

fire-result

👉 現在,我們來用不同類型的要求挑戰召喚者。如要確保代理程式從頭開始,且不會記住先前的互動,請按一下畫面右上角的「+ Session」按鈕,開始新的工作階段。new-session

DogmaApathy. A rigid, stone-like inquisitor made of ancient rulebooks and enforced processes. weakness is Unbroken Collaboration

(預期:召喚者應委派給 water_elemental_familiar。)water-result

👉 進行最後一項測試時,請再次從乾淨的狀態開始。按一下「+ Session」按鈕,即可開始新工作階段,然後輸入下一個提示。

Obfuscation. A shadowy, spider-like horror that spins tangled webs of impenetrable code , weakness is Elegant Sufficiency

(預期:召喚者應委派給 earth_elemental_familiar)。

earth-result

重要事項:如果看到 429 RESOURCE EXHAUSTED 錯誤,表示您已達到 LLM 的速率限制 (每分鐘 10 次呼叫)。如要修正這個問題,請等待 60 秒,然後啟動「+ 新的工作階段」,再重試提示。

👉💻 召喚完成後,返回 Cloud Shell 編輯器終端機,然後按下 Ctrl+C 停止 ADK 開發人員 UI。

非遊戲玩家

7. 實施魔法定律 - 攔截器模式

寵物很強大,但即使是魔法生物也需要時間恢復。如果召喚師不顧一切地耗盡兵力,就會失去防禦能力。明智的召喚師會瞭解資源管理的重要性,並嚴格執行交戰規則。

限時動態

架構師注意事項:目前為止,我們的代理程式都是無狀態。現在,我們將實作攔截器設計模式,讓這些函式成為有狀態的函式。這項強大的技術可「攔截」代理程式的正常執行流程,以執行我們自己的自訂邏輯。這樣我們就能強制執行規則、新增記錄或修改行為,不必變更代理程式的核心程式碼。這是建構穩健、可維護及可觀測的代理程式系統的基石。

總覽

ADK 提供兩種主要方式來實作這個模式:回呼外掛程式。回呼是附加至單一代理程式的簡單函式,非常適合快速進行特定修改。外掛程式是功能更強大的可重複使用類別,可套用至全域,影響系統中執行的每個代理程式。我們會先使用回呼進行重點偵錯,再逐步完成外掛程式。

立法者 - 撰寫 Cooldown 回呼

首先,我們會將冷卻邏輯實作為簡單的回呼函式。這項功能可直接附加至單一代理程式,方便您獨立測試,因此非常適合用來設計原型和偵錯規則。我們會將這個「攔截器」附加至 Earth Elemental。

通知緩和模式

👉✏️ 返回 ~/agentverse-architect/agent/earth/agent.py,然後將 #REPLACE-before_agent-function 替換為下列 Python 程式碼。

def check_cool_down(callback_context: CallbackContext) -> Optional[types.Content]:
    """
    This callback checks an external API to see if the agent is on cooldown.
    If it is, it terminates the run by returning a message.
    If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
    """
    agent_name = callback_context.agent_name
    print(f"[Callback] Before '{agent_name}': Checking cooldown status...")

    # --- 1. CHECK the Cooldown API ---
    try:
        response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
        response.raise_for_status()
        data = response.json()
        last_used_str = data.get("time")
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
        return None # Fail open: if the API is down, let the agent work.

    # --- 2. EVALUATE the Cooldown Status ---
    if last_used_str:
        last_used_time = datetime.fromisoformat(last_used_str)
        time_since_last_use = datetime.now(timezone.utc) - last_used_time

        if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
            # AGENT IS ON COOLDOWN. Terminate the run.
            seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
            override_message = (
                f"The {agent_name} is exhausted and must recover its power. "
                f"It cannot be summoned for another {seconds_remaining} seconds."
            )
            print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
            # Returning a Content object stops the agent and sends this message to the user.
            return types.Content(parts=[types.Part(text=override_message)])

    # --- 3. UPDATE the Cooldown API (if not on cooldown) ---
    current_time_iso = datetime.now(timezone.utc).isoformat()
    payload = {"timestamp": current_time_iso}
    
    print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
    try:
        requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")

    # --- 4. ALLOW the agent to run ---
    # Returning None tells the ADK to proceed with the agent's execution as normal.
    print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")

這個 check_cool_down 函式是我們的攔截器。ADK 會先執行這個函式,再允許 Earth Elemental 執行。

  • 檢查:向 Cooldown API 提出 GET 要求,檢查上次使用「熟悉」的時間。
  • 評估:比較時間戳記與目前時間。
  • 行動:
    • 如果「熟悉」處於冷卻狀態,系統會傳回含有錯誤訊息的 Content 物件,終止代理程式的執行作業。這則訊息會直接傳送給使用者,且系統不會執行服務專員的主要邏輯。
    • 如果 Familiar 可用,就會向 Cooldown API 發出 POST 要求來更新時間戳記,然後傳回 None,向 ADK 發出信號,表示代理程式可以繼續執行。

👉✏️ 現在,請將這個攔截器套用至 Earth 元素。在同一個 ~/agentverse-architect/agent/earth/agent.py 檔案中,將 #REPLACE-before_agent-config 註解替換為下列程式碼:

before_agent_callback=check_cool_down

驗證冷卻時間

現在來測試一下我們的新魔法定律。我們會召喚土元素,然後立即再次嘗試召喚,看看回呼是否成功攔截並封鎖第二次嘗試。

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run earth

👉💻 在控制台中:

  • 首次召喚:開始seismic charge, starting from zero
  • 預期結果:Earth Elemental 會順利執行。在執行 adk web 指令的終端機中,您會看到記錄 [Callback] ... Updating timestamp....
  • 冷卻測試 (60 秒內)Do another seismic charge`!
    • 預期結果:check_cool_down callback會攔截這項要求。服務專員會直接在即時通訊中回覆,例如:The earth_elemental_familiar is exhausted and must recover its power. It cannot be summoned for another... seconds
  • 等待一分鐘。
  • 第二次召喚 (60 秒後)Begin the seismic charge again
    • 預期結果:回呼會檢查 API,確認已過足夠時間,並允許繼續執行動作。土元素會再次順利運作。

callback

👉💻 按下 Ctrl+c 即可結束。

選用:在網頁 UI 中觀察回呼

您也可以執行 adk web earth,在網頁介面中測試這個流程。不過請注意,網頁介面的視覺化效果並未針對顯示回呼迴圈執行的快速疊代檢查進行最佳化,因此可能無法準確呈現流程。如要查看代理程式邏輯在檢查冷卻時間時最精確的逐步追蹤記錄,請在終端機中使用 adk run 指令,取得更清楚詳細的檢視畫面。loop

👉💻 按下 Ctrl+c 即可結束。

建立通用法則 - 冷卻外掛程式

回呼功能運作正常,但有一個重大架構缺陷:它與單一代理程式繫結。如要將這項規則套用至火和水精靈,我們必須將相同程式碼複製並貼到這些精靈的檔案中。這種做法效率不彰,而且難以維護。

架構師注意事項:外掛程式在此處至關重要。外掛程式會將可重複使用的邏輯封裝到類別中,並在執行階段層級附加。也就是說,單一外掛程式可將規則套用至該系統中執行的每個代理程式。這是代理人系統「不要重複」原則的最終表現。

現在,我們要將回呼函式重構為更強大且可重複使用的 CoolDownPlugin

👉✏️ 返回 agent/cooldown_plugin.py 檔案並建立外掛程式,將 #REPLACE-plugin 替換為下列程式碼:

class CoolDownPlugin(BasePlugin):
  """A plugin that enforces a cooldown period by checking an external API."""

  def __init__(self, cooldown_seconds: int = COOLDOWN_PERIOD_SECONDS) -> None:
    """Initialize the plugin with counters."""
    super().__init__(name="cool_down_check")
    self.cooldown_period = timedelta(seconds=cooldown_seconds)
    print(f"CooldownPlugin initialized with a {cooldown_seconds}-second cooldown.")
    

  async def before_agent_callback(
      self, *, agent: BaseAgent, callback_context: CallbackContext
  ) -> None:
    """
    This callback checks an external API to see if the agent is on cooldown.
    If it is, it terminates the run by returning a message.
    If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
    """
    agent_name = callback_context.agent_name
    print(f"[Callback] Before '{agent_name}': Checking cooldown status...")

    # If the agent is not a main Familiar, skip the entire cooldown process.
    if not agent_name.endswith("_elemental_familiar"):
        print(f"[Callback] Skipping cooldown check for intermediate agent: '{agent_name}'.")
        return None # Allow the agent to proceed immediately.


    # --- 1. CHECK the Cooldown API ---
    try:
        response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
        response.raise_for_status()
        data = response.json()
        last_used_str = data.get("time")
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
        return None # Fail open: if the API is down, let the agent work.

    # --- 2. EVALUATE the Cooldown Status ---
    if last_used_str:
        last_used_time = datetime.fromisoformat(last_used_str)
        time_since_last_use = datetime.now(timezone.utc) - last_used_time

        if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
            # AGENT IS ON COOLDOWN. Terminate the run.
            seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
            override_message = (
                f"The {agent_name} is exhausted and must recover its power. "
                f"It cannot be summoned for another {seconds_remaining} seconds."
            )
            print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
            # Returning a Content object stops the agent and sends this message to the user.
            return types.Content(parts=[types.Part(text=override_message)])

    # --- 3. UPDATE the Cooldown API (if not on cooldown) ---
    current_time_iso = datetime.now(timezone.utc).isoformat()
    payload = {"timestamp": current_time_iso}
    
    print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
    try:
        requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")

    # --- 4. ALLOW the agent to run ---
    # Returning None tells the ADK to proceed with the agent's execution as normal.
    print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")

將外掛程式附加至召喚師的執行階段

現在,我們要如何將這項通用法律套用至所有智慧音箱?我們會將外掛程式附加至 ADK 執行階段。

ADK 執行階段是執行引擎,可讓代理程式運作。當您使用 adk.run() 或 to_a2a() 等指令時,就是將代理程式交給執行階段。這個引擎負責管理代理程式回合的整個生命週期:接收使用者輸入內容、呼叫 LLM、執行工具及處理外掛程式。在這個層級附加外掛程式,基本上就是修改引擎中每個代理程式的「物理定律」,確保冷卻規則普遍且一致地套用。

👉✏️ 首先,請移除舊的代理專屬回呼。前往 ~/agentverse-architect/agent/earth/agent.py,然後刪除以下整行內容:

before_agent_callback=check_cool_down

👉✏️ 接下來,我們會在 A2A 進入點指令碼中,將新外掛程式附加至執行階段。前往 ~/agentverse-architect/agent/agent_to_a2a.py 檔案。使用下列程式碼片段取代 #REPLACE-IMPORT 註解:

from cooldown_plugin import CoolDownPlugin

👉✏️ 將 #REPLACE-PLUGIN 替換為下列程式碼片段:

plugins=[CoolDownPlugin(cooldown_seconds=60)],

啟用新的全球外掛程式前,請務必移除舊的代理商專屬邏輯,以免發生衝突。👉✏️ 清理 Earth 代理程式。前往 ~/agentverse-architect/agent/earth/agent.py 檔案,並完全刪除 before_agent_callback=check_cool_down 行。這會將所有冷卻期責任轉移給新外掛程式。

驗證外掛程式

現在我們有了通用法則,必須使用這項新魔法重新部署精靈。

👉💻 使用主要 Cloud Build 管道重建並重新部署所有三個 Familiars。

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

👉💻 部署完成後,我們會下達 summoner_agent 指令,測試外掛程式的效用。召喚師會嘗試委派給寵物,但附加至每個寵物執行階段的外掛程式會攔截指令並強制執行冷卻時間。

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner

👉💻 在控制台中,依序執行下列測試:

  • 首次召喚:開始Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality
  • 預期結果:Fire Elemental 會順利執行。
  • 冷卻測試 (60 秒內)Hype, with Inescapable Reality as weakness is still standing! Strike it again!
    • 預期結果:服務專員會直接在即時通訊中回覆,例如:.... It cannot be summoned for another... seconds
  • 等待一分鐘。
  • 第二次召喚 (60 秒後)Hype must be defeated. It has Inescapable Reality as weakness! Strike it again!
    • 預期結果:回呼會檢查 API,確認已過足夠時間,並允許繼續執行動作。火元素會再次順利運作。

外掛程式

👉💻 按下 Ctrl+C 即可結束。

召喚師,恭喜!您已成功使用自訂外掛程式和外部狀態管理服務,實作以規則為基礎的自動化調度管理系統,這是非常先進且穩固的架構模式。

非遊戲玩家

8. Binding the Echoes of Battle - Agent State & Memory

如果召喚師不顧一切地重複使用相同策略,就會變得容易預測。明智的召喚師會從過去的戰鬥中學習,調整戰術,讓敵人措手不及。面對強大的首領時,召喚處於冷卻時間的寵物會浪費一回合,這是重大失誤。為避免這種情況,召喚師需要記憶上次的動作。

故事

架構師注意事項:記憶和狀態管理是將代理程式從簡單的工具呼叫器,提升為智慧型對話夥伴的關鍵。請務必瞭解這兩種類型:

  • 長期記憶:用於永久保存的知識。這類資料通常儲存在持續性儲存空間中,可視為可搜尋的封存資料或知識庫。當中包含許多過往的對話和來源資訊,因此服務專員可以回想特定使用者或主題的事實。ADK 的 MemoryService 就是為此而設計,可管理長期知識的擷取和搜尋作業。
  • 短期狀態:這是指暫時性的「當下」知識,僅與目前的工作或對話相關。這就像戰鬥計畫的一組附註:「我剛才使用了火元素,所以牠可能很累。」這個狀態很輕量,只會在目前工作階段期間存在。

總覽

在我們的使用案例中,不需要記住每場戰鬥,只需要記住這次遭遇中召喚的最後一隻寵物。因此,輕量級的短期狀態是完美的架構選擇。我們會使用 after_tool_callback 儲存這項重要資訊。

記錄迴響:回憶最後的召喚

我們將使用 after_tool_callback 實作短期記憶。這是功能強大的 ADK 勾點,可讓我們在工具成功執行,執行自訂 Python 函式。我們會使用這個攔截器,記錄剛召喚到代理程式工作階段狀態的「熟悉」名稱。

👉✏️ 在 ~/agentverse-architect/agent/summoner/agent.py 檔案中,將 #REPLACE-save_last_summon_after_tool 註解替換為下列函式:

def save_last_summon_after_tool(
    tool,
    args: Dict[str, Any],
    tool_context: ToolContext,
    tool_response: Dict[str, Any],
) -> Optional[Dict[str, Any]]:
    """
    Callback to save the name of the summoned familiar to state after the tool runs.
    """
    familiar_name = tool.name
    print(f"[Callback] After tool '{familiar_name}' executed with args: {args}")

    # Use the tool_context to set the state
    print(f"[Callback] Saving last summoned familiar: {familiar_name}")
    tool_context.state["last_summon"] = familiar_name
    # Important: Return the original, unmodified tool response to the LLM
    return tool_response

👉✏️ 現在,將這個 save_last_summon_after_tool 附加至 Summoner 代理程式。在同一個檔案中,將 #REPLACE-Memory-check-config 註解替換為下列程式碼:

after_tool_callback=save_last_summon_after_tool,

👉✏️ 將整個代理程式提示詞換成下列內容

        You are the Master Summoner, a grand strategist who orchestrates your Familiars.
        Your mission is to analyze the description of a monster and defeat it by summoning

        You should also know the familiar you called last time or there might be none, 
        And then choose the most effective AND AVAILABLE Familiar from your state called last_summon, do not call that familiar that you called last time!
        
        You MUST follow this thinking process for every command:

        **1. Strategic Analysis:**
        First, analyze the monster's description and the tactical situation.
        Based on your Familiar Doctrines, determine the IDEAL strategy.

        **2. Cooldown Verification:**
        Second, you MUST review the entire conversation history to check the real-time
        cooldown status of all Familiars. A Familiar is ON COOLDOWN and UNAVAILABLE
        if it was summoned less than one minute ago.

        **3. Final Decision & Execution:**
        Based on your analysis and cooldown check, you will now act:
        -   **If your ideal Familiar IS available:** Summon it immediately.
        -   **If your ideal Familiar IS ON COOLDOWN:** You must adapt. Choose another
            Familiar that is AVAILABLE and can still be effective, even if it's not the
            perfect choice. If multiple Familiars are available, you may choose any one of them.
        -   **If ALL Familiars ARE ON COOLDOWN:** You are forbidden from summoning.
            Your ONLY response in this case MUST be: "All Familiars are recovering
            their power. We must wait."
        -   For earth elemental familiar. Always do seismic charge, and start with base damange 1.


        --- FAMILIAR DOCTRINES (Your Toolset) ---
        - `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
          Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
        - `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
          Ideal for Unbroken Collaboration weakness.
        - `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
          repeatedly charge power. Ideal for Elegant Sufficiency weakness.

驗證:適應性策略試用

👉💻 現在,讓我們驗證召喚師的新策略邏輯。目標是確認召喚師不會連續兩次使用相同的精靈,展現記憶上次動作並適應的能力。

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner

👉💻 Monster Strike #1:Hype. It's a single, slow-moving target with thick armor. Its weakness is Inescapable Reality.

  • 預期結果:召喚者會分析弱點,並正確召喚 fire_familiar。👉💻 Monster Strike #2 (記憶力測驗):Hype is still standing! It hasn't changed its form. Strike it again! Its weakness is Inescapable Reality.
  • 預期結果:召喚師的策略分析會再次指出火精靈是理想選擇。不過,新的指令和記憶體會告訴模型,fire_familiar 是 last_summon。為避免重複召喚,現在會調整策略,召喚其他可用的精靈 (水精靈或土精靈)。

final-result

👉💻 按下 Ctrl+C 即可結束。

部署自動化調度管理工具

部署完 Familiars,並讓 Summoner 充滿記憶後,就可以部署最終的升級版協調器。

👉💻 藍圖完成後,我們現在要進行最後的儀式。這項指令會建構 summoner_agent 並部署至 Cloud Run。

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
gcloud builds submit . \
  --config=cloudbuild-summoner.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_FIRE_URL="$FIRE_URL",_WATER_URL="$WATER_URL",_EARTH_URL="$EARTH_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

部署 Summoner 代理程式後,請確認其代理程式對代理程式 (A2A) 端點是否已上線,且設定正確無誤。這個端點會提供公開的 agent.json 檔案 (又稱「代理程式資訊卡」),讓其他代理程式探索其功能。👉💻 執行下列 curl 指令,擷取並格式化 Agent Card:

. ~/agentverse-architect/set_env.sh
curl https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app/.well-known/agent.json" | jq

您應該會看到描述召喚師代理程式的乾淨 JSON 輸出內容。仔細查看 sub_agents 部分,您會看到列出的 fire_familiarwater_familiarearth_familiar。這表示召喚師已上線,並與軍團建立連線。

這證明您的架構是成功的。召喚師不只是代理人,更是適應型策略家,會從行動中學習,成為更有效的指揮官。

您已完成最後一次的架構試用。戰場的迴響現在將受你意志的約束。訓練已結束。真正的戰鬥即將展開。現在,請帶著完成的系統,迎接最終挑戰。準備迎接魔王戰

非遊戲玩家

9. The Boss Fight

最終藍圖已刻成,元素字體已鑄造完成,你的精靈也已與你的意志連結,等待透過 Concord 接收你的指令。多代理系統不只是服務的集合,而是活生生的策略軍團,您就是這個軍團的中心。終極測試的時機已到,也就是針對單一代理程式無法擊敗的對手進行即時協調。

取得代理程式的 Locus

你必須擁有兩把鑰匙,才能進入戰場:英雄的專屬簽章 (Agent Locus) 和通往 Spectre 巢穴的隱藏路徑 (Dungeon URL)。

👉💻 首先,請在 Agentverse 中取得代理程式的專屬地址 (即 Locus)。這是將冠軍連線至戰場的即時端點。

echo https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app"

👉💻 接著,找出目的地。這個指令會顯示 Translocation Circle 的位置,也就是進入 Spectre 領域的入口。

echo https://agentverse-dungeon"-${PROJECT_NUMBER}.${REGION}.run.app"

重要事項:請準備好這兩個網址。您會在最後一個步驟中用到這些資訊。

與幽靈對峙

取得座標後,您現在可以前往「Translocation Circle」並施展咒語,準備開戰。

👉 在瀏覽器中開啟 Translocation Circle 網址,即可站在通往 The Crimson Keep 的閃耀入口前。

如要攻破要塞,你必須將暗影之刃的本質與傳送門調和。

  • 在頁面中,找出標示為「A2A Endpoint URL」(A2A 端點網址) 的符文輸入欄位。
  • 特工地點網址 (您複製的第一個網址) 貼到這個欄位,即可刻上英雄的徽記。
  • 按一下「連線」,即可體驗瞬間移動的魔力。

Translocation Circle

傳送時的強光逐漸消退,你已離開聖所。空氣中充滿能量,寒冷而尖銳。在您面前,幽靈實體化了,形成嘶嘶作響的靜電和損毀程式碼的漩渦,不潔的光芒在地下城地板上投下長長的舞動陰影。牠沒有臉,但你感覺到牠龐大、令人疲憊的存在感完全集中在你身上。

只有堅定信念,才能邁向勝利。這是一場意志力的較量,戰場就在心靈。

你向前衝刺,準備發動第一波攻擊,但幽靈卻反擊了。不會升起護盾,但會直接將問題投射到你的意識中,這是從訓練核心汲取的閃爍符文挑戰。

地牢

這就是這場戰役的本質。知識就是你的武器。

  • 運用所學知識回答問題,刀刃就會燃起純粹的能量,擊碎幽靈的防禦並造成致命一擊。
  • 但如果你猶豫不決,答案含糊不清,武器的光芒就會黯淡。但這時的攻擊只會發出可悲的悶響,造成的傷害也只有一小部分。更糟的是,幽靈會以你的不確定感為食,每犯下一個錯誤,幽靈的腐化力量就會增長。

這就是最後的挑戰,冠軍。程式碼是你的魔法書,邏輯是你的劍,知識則是能抵禦混亂的盾牌。

專注。擊出好球。這關係到 Agentverse 的命運。

召喚師,恭喜!

您已順利完成試用。您已精通多代理程式協調作業,將孤立的精靈和混亂的力量轉化為和諧的協調。您現在可以指揮全自動化系統,執行複雜的策略來防禦 Agentverse。

10. 清除:拆除召喚師的協和

恭喜你精通召喚師的協約!為確保 Agentverse 保持原始狀態,並清除訓練場地,您現在必須執行最終的清除儀式。系統會逐步移除您在過程中建立的所有資源。

停用 Agentverse 元件

現在要系統性地拆除多代理系統的已部署元件。

刪除所有 Cloud Run 服務和 Artifact Registry 存放區

這會從 Cloud Run 移除所有已部署的 Familiar 代理程式、Summoner Orchestrator、MCP 伺服器和 Dungeon 應用程式。

👉💻 在終端機中逐一執行下列指令,刪除各項服務:

. ~/agentverse-architect/set_env.sh
gcloud run services delete summoner-agent --region=${REGION} --quiet
gcloud run services delete fire-familiar --region=${REGION} --quiet
gcloud run services delete water-familiar --region=${REGION} --quiet
gcloud run services delete earth-familiar --region=${REGION} --quiet
gcloud run services delete mcp-api-server --region=${REGION} --quiet
gcloud run services delete mcp-general-server --region=${REGION} --quiet
gcloud run services delete toolbox --region=${REGION} --quiet
gcloud run services delete agentverse-dungeon --region=${REGION} --quiet
gcloud run services delete nexus-of-whispers-api --region=${REGION} --quiet
gcloud artifacts repositories delete ${REPO_NAME} --location=${REGION} --quiet

刪除 Cloud SQL 執行個體

這會移除 summoner-librarium-db 執行個體,包括其中的資料庫和所有資料表。

👉💻 在終端機中執行:

. ~/agentverse-dataengineer/set_env.sh
gcloud sql instances delete summoner-librarium-db --database-version=POSTGRES_14 --project=${PROJECT_ID} --quiet

刪除 Secret Manager 密鑰和 Google Cloud Storage bucket

👉💻 在終端機中執行:

. ~/agentverse-dataengineer/set_env.sh
gcloud secrets delete tools --quiet
gcloud storage rm -r gs://${BUCKET_NAME} --quiet

清除本機檔案和目錄 (Cloud Shell)

最後,清除 Cloud Shell 環境中複製的存放區和建立的檔案。這是選用步驟,但強烈建議執行,以便徹底清除工作目錄。

👉💻 在終端機中執行:

rm -rf ~/agentverse-architect
rm -rf ~/agentverse-dungeon
rm -f ~/project_id.txt

您已成功清除 Agentverse Architect 歷程的所有痕跡。專案已清理完畢,可以開始下一個冒險。