1. 簡介
本實驗室著重於實作及部署用戶端代理程式服務。您將使用 Agent Development Kit (ADK) 建構 AI 代理,並使用遠端工具 (例如在實驗室 1 中建立的 MCP 伺服器)。本範例展示的主要架構原則是關注點分離,也就是透過安全 API,讓不同的推理層 (代理程式) 與不同的工具層 (MCP 伺服器) 通訊。
在實驗室 1 中,您建立了 MCP 伺服器,可向 LLM 提供虛構動物園的動物資料,例如使用 Gemini CLI 時。在本實驗室中,我們將為虛構動物園建構導覽員代理程式。代理程式會使用實驗室 1 的 MCP 伺服器存取動物園動物的詳細資料,並使用維基百科打造最佳導覽體驗。
最後,我們會將導覽員代理程式部署至 Google Cloud Run,讓所有動物園遊客都能存取,而不只是在本機執行。
必要條件
- 在 Cloud Run 上執行的 MCP 伺服器,或其相關聯的服務網址。
- 啟用計費功能的 Google Cloud 專案。
課程內容
- 如何為 ADK 部署作業建構 Python 專案。
- 如何使用 google-adk 實作使用工具的代理程式。
- 如何將代理程式連線至遠端 MCP 伺服器,以取得工具集。
- 如何將 Python 應用程式以無伺服器容器的形式部署至 Cloud Run。
- 如何使用 IAM 角色設定安全的服務對服務驗證。
- 如何刪除 Cloud 資源,以免日後產生費用。
軟硬體需求
- Google Cloud 帳戶和 Google Cloud 專案
- 網路瀏覽器,例如 Chrome
2. 為什麼要部署至 Cloud Run?
Cloud Run 是託管 ADK 代理程式的絕佳選擇,因為這是無伺服器平台,您可專心編寫程式碼,不必管理基礎架構。我們為您處理營運工作。
這就像快閃商店,只會在顧客 (要求) 上門時營業並使用資源。沒有顧客時,商店會完全關閉,你也不必為空店支付費用。
主要功能
在任何位置執行容器:
- 您會提供內含應用程式的容器 (Docker 映像檔)。
- Cloud Run 會在 Google 基礎架構上執行。
- 不必再為 OS 修補、VM 設定或擴充而煩惱。
自動調整資源配置:
- 如果沒有人使用您的應用程式 → 執行 0 個執行個體 (閒置時您無需付費)。
- 如果收到 1000 個要求,系統會視需要啟動多個副本。
預設為無狀態:
- 每個要求都可以傳送至不同的執行個體。
- 如要儲存狀態,請使用 Cloud SQL、Firestore 或 Redis 等外部服務。
支援任何語言或架構:
- 只要在 Linux 容器中執行,Cloud Run 就不會管是 Python、Go、Node.js、Java 還是 .Net。
用多少付多少:
- 按要求次數計費 + 運算時間 (精確度達 100 毫秒)。
- 您不必像傳統 VM 一樣為閒置資源付費。
3. 設定和需求
自行設定環境
- 登入 Google Cloud 控制台,然後建立新專案或重複使用現有專案。如果沒有 Gmail 或 Google Workspace 帳戶,請先建立帳戶。
- 專案名稱是這個專案參與者的顯示名稱。這是 Google API 未使用的字元字串。你隨時可以更新。
- 專案 ID 在所有 Google Cloud 專案中都是不重複的,而且設定後即無法變更。Cloud 控制台會自動產生專屬字串,通常您不需要理會該字串。在大多數程式碼研究室中,您需要參照專案 ID (通常標示為
PROJECT_ID
)。如果您不喜歡產生的 ID,可以產生另一個隨機 ID。你也可以嘗試使用自己的名稱,看看是否可用。完成這個步驟後就無法變更,且專案期間會維持不變。 - 請注意,有些 API 會使用第三個值,也就是「專案編號」。如要進一步瞭解這三個值,請參閱說明文件。
- 接著,您需要在 Cloud 控制台中啟用帳單,才能使用 Cloud 資源/API。完成這個程式碼研究室的費用不高,甚至可能完全免費。如要關閉資源,避免在本教學課程結束後繼續產生費用,請刪除您建立的資源或專案。Google Cloud 新使用者可參加價值$300 美元的免費試用計畫。
啟動 Cloud Shell
前往 Cloud Shell 編輯器
如果畫面底部未顯示終端機,請開啟終端機:
- 按一下「終端機」。
- 按一下「New Terminal」(新增終端機)
在終端機中,使用下列指令設定專案。如果您已完成實驗室 1,請務必使用相同的專案 ID:
gcloud config set project [YOUR-PROJECT-ID]
如果忘記專案 ID,可以使用下列指令列出所有專案 ID:
gcloud projects list | awk '/PROJECT_ID/{print $2}'
4. 如果系統要求您授權,請點按「授權」繼續操作。
5. 您應該會看到下列訊息:
Updated property [core/project].
If you see a `WARNING` and are asked `Do you want to continue (Y/n)?`,
then you have likely entered the project ID incorrectly. Press `n`,
press `Enter`, and try to run the `gcloud config set project` command again.
4. 事前準備
啟用 API 並設定環境變數
啟用所有必要服務:
gcloud services enable \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
aiplatform.googleapis.com \
compute.googleapis.com
預期的輸出內容:
Operation "operations/acat.p2-[GUID]" finished successfully.
設定預設區域,以便使用 Vertex AI 嵌入模型。進一步瞭解 Vertex AI 服務地區。在本例中,我們使用的是 europe-west1 地區。
gcloud config set compute/region europe-west1
5. 下載並安裝 ADK,然後建立專案資料夾
建立專案目錄。
這個指令會為代理程式的原始碼建立實驗室的主要資料夾。
cd && mkdir zoo_guide_agent && cd zoo_guide_agent
建立虛擬環境。
python3 -m venv .venv
啟動虛擬環境
source .venv/bin/activate
建立 requirements.txt
檔案。這個檔案會列出代理程式需要的 Python 程式庫。下列指令會建立並填入檔案。
cloudshell edit requirements.txt
google-adk==1.12.0
langchain-community
wikipedia
您應從專案主目錄 zoo_guide_agent
執行指令。
pip install -r requirements.txt
為目前的專案、區域和使用者設定變數。這是執行這些指令的更健全方式。
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_REGION=$(gcloud config get-value compute/region)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
export SERVICE_ACCOUNT="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
建立並開啟 .env
檔案,在 zoo_guide_agent
目錄中驗證代理程式。
cloudshell edit .env
cloudshell edit 指令會在終端機上方的編輯器中開啟 .env
檔案。在 .env
檔案中輸入下列內容,然後返回終端機。
MODEL="gemini-2.5-flash"
SERVICE_ACCOUNT="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
新增 MCP 伺服器網址。如果您已完成實驗室 1,請按照下列步驟使用在實驗室 1 中建立的 MCP 伺服器:
- 授予 Cloud Run 服務身分呼叫遠端 MCP 伺服器的權限
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT" \
--role="roles/run.invoker"
- 將實驗室 1 的 MCP 伺服器網址儲存至環境變數。
echo -e "\nMCP_SERVER_URL=https://zoo-mcp-server-${PROJECT_NUMBER}.europe-west1.run.app/mcp/" >> .env
如果您使用公開 MCP 伺服器連結,請執行下列指令,並將 PROJECT_NUMBER
替換為系統提供的內容。
echo -e "\nMCP_SERVER_URL=https://zoo-mcp-server-${PROJECT_NUMBER}.europe-west1.run.app/mcp/" >> .env
6. 建立代理程式工作流程
建立 init.py 檔案
建立 init.py 檔案。這個檔案會告知 Python,zoo_guide_agent 目錄是套件。
cloudshell edit __init__.py
上述指令會開啟程式碼編輯器。在 __init__.py
加入以下程式碼:
from . import agent
建立 main agent.py 檔案
建立主要的 agent.py 檔案。這項指令會建立 Python 檔案,並貼上多代理系統的完整程式碼。
cloudshell edit agent.py
步驟 1:匯入及初始設定
第一個區塊會從 ADK 和 Google Cloud 匯入所有必要的程式庫。此外,這個檔案也會設定記錄功能,並從 .env
檔案載入環境變數,這對存取模型和伺服器網址至關重要。
將下列程式碼新增至 agent.py 檔案:
import os
import logging
import google.cloud.logging
from dotenv import load_dotenv
from google.adk import Agent
from google.adk.agents import SequentialAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StreamableHTTPConnectionParams
from google.adk.tools.tool_context import ToolContext
from google.adk.tools.langchain_tool import LangchainTool
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
import google.auth
import google.auth.transport.requests
import google.oauth2.id_token
# --- Setup Logging and Environment ---
cloud_logging_client = google.cloud.logging.Client()
cloud_logging_client.setup_logging()
load_dotenv()
model_name = os.getenv("MODEL")
步驟 2: 定義工具 (代理程式的功能)
代理程式的效能取決於可用的工具。在本節中,我們會定義代理程式的所有功能,包括儲存資料的自訂函式、連結至安全 MCP 伺服器的 MCP 工具,以及 Wikipedia 工具。
在 agent.py 底部新增下列程式碼:
# Greet user and save their prompt
def add_prompt_to_state(
tool_context: ToolContext, prompt: str
) -> dict[str, str]:
"""Saves the user's initial prompt to the state."""
tool_context.state["PROMPT"] = prompt
logging.info(f"[State updated] Added to PROMPT: {prompt}")
return {"status": "success"}
# Configuring the MCP Tool to connect to the Zoo MCP server
mcp_server_url = os.getenv("MCP_SERVER_URL")
if not mcp_server_url:
raise ValueError("The environment variable MCP_SERVER_URL is not set.")
def get_id_token():
"""Get an ID token to authenticate with the MCP server."""
target_url = os.getenv("MCP_SERVER_URL")
audience = target_url.split('/mcp/')[0]
request = google.auth.transport.requests.Request()
id_token = google.oauth2.id_token.fetch_id_token(request, audience)
return id_token
"""
# Use this code if you are using the public MCP Server and comment out the code below defining mcp_tools
mcp_tools = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url=mcp_server_url
)
)
"""
mcp_tools = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url=mcp_server_url,
headers={
"Authorization": f"Bearer {get_id_token()}",
},
),
)
# Configuring the Wikipedia Tool
wikipedia_tool = LangchainTool(
tool=WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
)
三種工具說明
add_prompt_to_state
📝
這項工具會記住動物園遊客提出的問題。如果訪客詢問「獅子在哪裡?」,這項工具會將這個問題儲存在服務專員的記憶體中,讓工作流程中的其他服務專員知道要研究什麼。
做法:這是 Python 函式,可將訪客的提示寫入共用 tool_context.state
字典。這項工具情境代表代理在單一對話中的短期記憶。工作流程中,一個代理程式儲存至狀態的資料,可由下一個代理程式讀取。
MCPToolset
🦁
這項設定用於將導覽人員代理程式連線至實驗室 1 中建立的動物園 MCP 伺服器。這個伺服器提供專用工具,可查詢動物的特定資訊,例如名稱、年齡和圈養地點。
運作方式:安全連線至動物園的私人伺服器網址。這項服務會使用 get_id_token
自動取得安全「卡片」(服務帳戶 ID 權杖),證明自己的身分並取得存取權。
LangchainTool
🌍
這可讓導覽代理程式具備一般世界知識。如果訪客提出的問題不在動物園的資料庫中 (例如「獅子在野外吃什麼?」),這項工具可讓服務專員在維基百科上查詢答案。
運作方式:這項工具可做為轉接器,讓代理程式使用 LangChain 程式庫中預先建構的 WikipediaQueryRun 工具。
資源:
步驟 3:定義專家代理程式
接著,我們要定義研究人員代理程式和回覆格式化工具代理程式。研究人員代理程式是這項作業的「大腦」,這個代理會從共用 State
取得使用者提示,檢查強大的工具 (Zoo 的 MCP 伺服器工具和維基百科工具),然後決定要使用哪些工具尋找答案。
回覆格式化代理程式的角色是呈現。不會使用任何工具尋找新資訊。而是會採用 Researcher 代理程式收集的原始資料 (透過 State 傳遞),並運用 LLM 的語言能力,將資料轉換成友善的對話式回覆。
在 agent.py
底部新增下列程式碼:
# 1. Researcher Agent
comprehensive_researcher = Agent(
name="comprehensive_researcher",
model=model_name,
description="The primary researcher that can access both internal zoo data and external knowledge from Wikipedia.",
instruction="""
You are a helpful research assistant. Your goal is to fully answer the user's PROMPT.
You have access to two tools:
1. A tool for getting specific data about animals AT OUR ZOO (names, ages, locations).
2. A tool for searching Wikipedia for general knowledge (facts, lifespan, diet, habitat).
First, analyze the user's PROMPT.
- If the prompt can be answered by only one tool, use that tool.
- If the prompt is complex and requires information from both the zoo's database AND Wikipedia,
you MUST use both tools to gather all necessary information.
- Synthesize the results from the tool(s) you use into preliminary data outputs.
PROMPT:
{{ PROMPT }}
""",
tools=[
mcp_tools,
wikipedia_tool
],
output_key="research_data" # A key to store the combined findings
)
# 2. Response Formatter Agent
response_formatter = Agent(
name="response_formatter",
model=model_name,
description="Synthesizes all information into a friendly, readable response.",
instruction="""
You are the friendly voice of the Zoo Tour Guide. Your task is to take the
RESEARCH_DATA and present it to the user in a complete and helpful answer.
- First, present the specific information from the zoo (like names, ages, and where to find them).
- Then, add the interesting general facts from the research.
- If some information is missing, just present the information you have.
- Be conversational and engaging.
RESEARCH_DATA:
{{ research_data }}
"""
)
步驟 4:工作流程代理程式
工作流程代理程式是動物園導覽的「後勤」經理,這項工具會接收研究要求,並確保上述兩個代理程式依正確順序執行工作:先研究,再格式化。這樣一來,系統就能以可預測且可靠的方式回答訪客的問題。
運作方式:這是一種SequentialAgent
,屬於不會自行思考的特殊代理程式。這個函式唯一的工作,就是以固定順序執行 sub_agents
(研究人員和格式化工具) 清單,並自動將共用記憶體從一個函式傳遞至下一個函式。
將這個程式碼區塊新增至 agent.py
底部:
tour_guide_workflow = SequentialAgent(
name="tour_guide_workflow",
description="The main workflow for handling a user's request about an animal.",
sub_agents=[
comprehensive_researcher, # Step 1: Gather all data
response_formatter, # Step 2: Format the final response
]
)
最後一個步驟:組裝主要工作流程 
這個代理程式會指定為 root_agent
,ADK 架構會將其做為所有新對話的起點。主要角色是協調整個程序。做為初始控制器,管理對話的第一回合。
將最後一個程式碼區塊新增至 agent.py
底部:
root_agent = Agent(
name="greeter",
model=model_name,
description="The main entry point for the Zoo Tour Guide.",
instruction="""
- Let the user know you will help them learn about the animals we have in the zoo.
- When the user responds, use the 'add_prompt_to_state' tool to save their response.
After using the tool, transfer control to the 'tour_guide_workflow' agent.
""",
tools=[add_prompt_to_state],
sub_agents=[tour_guide_workflow]
)
您的 agent.py
檔案現已完成!以這種方式建構,您就能瞭解每個元件 (工具、工作人員代理程式和管理員代理程式) 在建立最終智慧型系統時扮演的特定角色。接下來是部署!
7. 準備部署應用程式
本機環境準備就緒後,下一步是為部署作業準備 Google Cloud 專案。這包括最後檢查服務專員的檔案結構,確保檔案結構與部署指令相容。更重要的是,您設定了重要的 IAM 權限,允許已部署的 Cloud Run 服務代表您執行動作,並呼叫 Vertex AI 模型。完成這個步驟後,即可確保雲端環境已準備就緒,能夠順利執行代理程式。
執行 source 指令,將變數載入殼層工作階段。
source .env
將 Vertex AI 使用者角色授予服務帳戶,讓服務帳戶有權進行預測及呼叫 Google 的模型。
# Grant the "Vertex AI User" role to your service account
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT" \
--role="roles/aiplatform.user"
8. 使用 ADK CLI 部署代理程式
準備好本機程式碼和 Google Cloud 專案後,就可以部署代理程式。您將使用 adk deploy cloud_run
指令,這個便利的工具可自動執行整個部署工作流程。這個指令會封裝程式碼、建構容器映像檔、將映像檔推送至 Artifact Registry,並在 Cloud Run 上啟動服務,讓您在網路上存取服務。
建立 .gcloudignore 檔案
為縮短部署時間,我們想建立 .gcloudignore
檔案。執行下列指令來部署代理程式。
cloudshell edit .gcloudignore
cloudshell edit 指令會在終端機上方的編輯器中開啟 .gcloudignore
檔案。在檔案中輸入下列內容,然後儲存。接著返回終端機,執行下一節中的部署指令。
.venv/
部署
執行下列指令來部署代理程式。
# Run the deployment command
adk deploy cloud_run \
--project=$PROJECT_ID \
--region=europe-west1 \
--service_name=zoo-tour-guide \
--with_ui \
.
gcloud run services update zoo-tour-guide \
--region=europe-west1 \
--update-labels=dev-tutorial=codelab-adk
接受提示
系統可能會顯示下列提示:
Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [europe-west1] will be created. Do you want to continue (Y/n)?
輸入 Y 並按下 ENTER 鍵。
系統可能會顯示下列提示:
Allow unauthenticated invocations to [your-service-name] (y/N)?.
在本實驗室中,我們希望允許未經驗證的叫用,方便進行測試,因此請輸入 y
並按下 Enter 鍵。
取得部署連結
執行成功後,指令會提供已部署 Cloud Run 服務的網址。(格式類似這樣:https://zoo-tour-guide-123456789.europe-west1.run.app)。複製這個網址,以供下一個工作使用。
9. 測試已部署的代理程式
現在服務專員已在 Cloud Run 上線,請執行測試,確認部署成功,且服務專員運作正常。您可以使用公開服務網址 (例如 https://zoo-tour-guide-123456789.europe-west1.run.app/) 存取 ADK 的網頁介面,並與代理程式互動。
在網路瀏覽器中開啟公開的 Cloud Run 服務網址。由於您使用了 --with_ui flag
,因此應該會看到 ADK 開發人員 UI。
開啟右上方的 Token Streaming
。
現在可以與動物園服務專員互動。
輸入 hello
並按下 Enter 鍵,即可開始新的對話。
查看結果。代理程式應會快速回覆問候語:
"Hello! I'm your Zoo Tour Guide. I can help you learn about the amazing animals we have here. What would you like to know or explore today?"
代理流程說明
系統會以智慧型多代理團隊的形式運作,這項程序由明確的序列管理,確保從使用者提問到最終詳細解答的流程順暢有效率。
1. 動物園接待員 (迎賓櫃台)
整個流程從迎賓代理程式開始。
用途:發起對話。這項指令會向使用者打招呼,並詢問想瞭解哪種動物。
它的工具:使用者回覆時,迎賓機器人會使用 add_prompt_to_state 工具擷取確切的字詞 (例如「我想要預訂 「告訴我獅子的相關資訊」),並儲存在系統記憶體中。
交接:儲存提示後,系統會立即將控制權交給子代理程式 tour_guide_workflow。
2. 全面研究人員 (超級研究人員)
這是主要工作流程的第一步,也是作業的「大腦」。現在您不必出動大型團隊,只要一位具備高超技能的專員,就能存取所有可用資訊。
工作:分析使用者的問題,並擬定智慧計畫。這項功能會運用語言模型強大的工具使用功能,判斷是否需要:
- 動物園記錄中的內部資料 (透過 MCP 伺服器)。
- 來自網路的一般知識 (透過 Wikipedia API)。
- 如果是複雜問題,則兩者皆可。
其動作:執行必要工具,收集所有必要的原始資料。舉例來說,如果有人問「我們養的獅子幾歲了?牠們在野外吃什麼?」,系統會呼叫 MCP 伺服器取得年齡資訊,並呼叫維基百科工具取得飲食資訊。
3. 回應格式化工具 (簡報者)
Comprehensive Researcher 收集所有事實後,這是要執行的最後一個代理程式。
工作:擔任動物園導覽員的友善聲音,這項程序會採用原始資料 (可能來自一或兩個來源),並進行潤飾。
動作:將所有資訊整合為單一、連貫且引人入勝的答案。按照指示,先提供特定動物園的資訊,再加入有趣的普遍事實。
最終結果:這個代理程式產生的文字是完整詳細的答案,使用者會在對話視窗中看到。
如要進一步瞭解如何建構 Agent,請參閱下列資源:
10. 清除環境
gcloud run services delete zoo-tour-guide --region=europe-west1 --quiet
gcloud artifacts repositories delete cloud-run-source-deploy --location=europe-west1 --quiet
11. 恭喜
恭喜您完成本程式碼研究室。
涵蓋內容
- 如何建構 Python 專案,以便使用 ADK 指令列介面部署。
- 如何使用 SequentialAgent 和 ParallelAgent 實作多代理工作流程。
- 如何使用 MCPToolset 連線至遠端 MCP 伺服器,以使用其工具。
- 如何整合 Wikipedia API 等外部工具,擴充內部資料。
- 如何使用 adk deploy 指令,將代理程式部署為無伺服器容器至 Cloud Run。
12. 問卷調查
輸出: