搭配 ADK 代理程式使用 Cloud Run 上的 MCP 伺服器

1. 簡介

本實驗室著重於實作及部署用戶端代理程式服務。您將使用 Agent Development Kit (ADK) 建構 AI 代理,並使用遠端工具 (例如在實驗室 1 中建立的 MCP 伺服器)。本範例展示的主要架構原則是關注點分離,也就是透過安全 API,讓不同的推理層 (代理程式) 與不同的工具層 (MCP 伺服器) 通訊。

在實驗室 1 中,您建立了 MCP 伺服器,可向 LLM 提供虛構動物園的動物資料,例如使用 Gemini CLI 時。在本實驗室中,我們將為虛構動物園建構導覽員代理程式。代理程式會使用實驗室 1 的 MCP 伺服器存取動物園動物的詳細資料,並使用維基百科打造最佳導覽體驗。

f8d4423edbfe993d.png

最後,我們會將導覽員代理程式部署至 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. 設定和需求

自行設定環境

  1. 登入 Google Cloud 控制台,然後建立新專案或重複使用現有專案。如果沒有 Gmail 或 Google Workspace 帳戶,請先建立帳戶

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • 專案名稱是這個專案參與者的顯示名稱。這是 Google API 未使用的字元字串。你隨時可以更新。
  • 專案 ID 在所有 Google Cloud 專案中都是不重複的,而且設定後即無法變更。Cloud 控制台會自動產生專屬字串,通常您不需要理會該字串。在大多數程式碼研究室中,您需要參照專案 ID (通常標示為 PROJECT_ID)。如果您不喜歡產生的 ID,可以產生另一個隨機 ID。你也可以嘗試使用自己的名稱,看看是否可用。完成這個步驟後就無法變更,且專案期間會維持不變。
  • 請注意,有些 API 會使用第三個值,也就是「專案編號」。如要進一步瞭解這三個值,請參閱說明文件
  1. 接著,您需要在 Cloud 控制台中啟用帳單,才能使用 Cloud 資源/API。完成這個程式碼研究室的費用不高,甚至可能完全免費。如要關閉資源,避免在本教學課程結束後繼續產生費用,請刪除您建立的資源或專案。Google Cloud 新使用者可參加價值$300 美元的免費試用計畫。

啟動 Cloud Shell

如果畫面底部未顯示終端機,請開啟終端機:

  • 按一下「終端機」
  • 按一下「New Terminal」(新增終端機)

d32c46fffa0a30a5.png

在終端機中,使用下列指令設定專案。如果您已完成實驗室 1,請務必使用相同的專案 ID:

gcloud config set project [YOUR-PROJECT-ID]

如果忘記專案 ID,可以使用下列指令列出所有專案 ID:

gcloud projects list | awk '/PROJECT_ID/{print $2}'

4. 如果系統要求您授權,請點按「授權」繼續操作。

6356559df3eccdda.png

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 伺服器:

  1. 授予 Cloud Run 服務身分呼叫遠端 MCP 伺服器的權限
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SERVICE_ACCOUNT" \
  --role="roles/run.invoker"
  1. 將實驗室 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: 定義工具 (代理程式的功能)

3eb9c6772576b906.jpeg

代理程式的效能取決於可用的工具。在本節中,我們會定義代理程式的所有功能,包括儲存資料的自訂函式、連結至安全 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())
)

三種工具說明

  1. add_prompt_to_state 📝

這項工具會記住動物園遊客提出的問題。如果訪客詢問「獅子在哪裡?」,這項工具會將這個問題儲存在服務專員的記憶體中,讓工作流程中的其他服務專員知道要研究什麼。

做法:這是 Python 函式,可將訪客的提示寫入共用 tool_context.state 字典。這項工具情境代表代理在單一對話中的短期記憶。工作流程中,一個代理程式儲存至狀態的資料,可由下一個代理程式讀取。

  1. MCPToolset 🦁

這項設定用於將導覽人員代理程式連線至實驗室 1 中建立的動物園 MCP 伺服器。這個伺服器提供專用工具,可查詢動物的特定資訊,例如名稱、年齡和圈養地點。

運作方式:安全連線至動物園的私人伺服器網址。這項服務會使用 get_id_token 自動取得安全「卡片」(服務帳戶 ID 權杖),證明自己的身分並取得存取權。

  1. LangchainTool 🌍

這可讓導覽代理程式具備一般世界知識。如果訪客提出的問題不在動物園的資料庫中 (例如「獅子在野外吃什麼?」),這項工具可讓服務專員在維基百科上查詢答案。

運作方式:這項工具可做為轉接器,讓代理程式使用 LangChain 程式庫中預先建構的 WikipediaQueryRun 工具。

資源:

步驟 3:定義專家代理程式

b8a9504b21920969.jpeg

接著,我們要定義研究人員代理程式和回覆格式化工具代理程式。研究人員代理程式是這項作業的「大腦」,這個代理會從共用 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
    ]
)

最後一個步驟:組裝主要工作流程 1000b9d20f4e134b.jpeg

這個代理程式會指定為 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?"

3244d2f6c3b03088.png e135694253b1be41.png

代理流程說明

系統會以智慧型多代理團隊的形式運作,這項程序由明確的序列管理,確保從使用者提問到最終詳細解答的流程順暢有效率。

1. 動物園接待員 (迎賓櫃台)

整個流程從迎賓代理程式開始。

用途:發起對話。這項指令會向使用者打招呼,並詢問想瞭解哪種動物。

它的工具:使用者回覆時,迎賓機器人會使用 add_prompt_to_state 工具擷取確切的字詞 (例如「我想要預訂 「告訴我獅子的相關資訊」),並儲存在系統記憶體中。

交接:儲存提示後,系統會立即將控制權交給子代理程式 tour_guide_workflow。

2. 全面研究人員 (超級研究人員)

這是主要工作流程的第一步,也是作業的「大腦」。現在您不必出動大型團隊,只要一位具備高超技能的專員,就能存取所有可用資訊。

工作:分析使用者的問題,並擬定智慧計畫。這項功能會運用語言模型強大的工具使用功能,判斷是否需要:

  • 動物園記錄中的內部資料 (透過 MCP 伺服器)。
  • 來自網路的一般知識 (透過 Wikipedia API)。
  • 如果是複雜問題,則兩者皆可。

其動作:執行必要工具,收集所有必要的原始資料。舉例來說,如果有人問「我們養的獅子幾歲了?牠們在野外吃什麼?」,系統會呼叫 MCP 伺服器取得年齡資訊,並呼叫維基百科工具取得飲食資訊。

3. 回應格式化工具 (簡報者)

Comprehensive Researcher 收集所有事實後,這是要執行的最後一個代理程式。

工作:擔任動物園導覽員的友善聲音,這項程序會採用原始資料 (可能來自一或兩個來源),並進行潤飾。

動作:將所有資訊整合為單一、連貫且引人入勝的答案。按照指示,先提供特定動物園的資訊,再加入有趣的普遍事實。

最終結果:這個代理程式產生的文字是完整詳細的答案,使用者會在對話視窗中看到。

如要進一步瞭解如何建構 Agent,請參閱下列資源:

  1. ADK 說明文件
  2. 為 ADK 代理程式建構自訂工具

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. 問卷調查

輸出:

您會如何使用本教學課程?

僅閱讀內容 閱讀內容並完成練習