大家好,鐵人賽第十六天,今天我們來玩點不一樣的!
在前兩天,我們的角色是「工具的創造者」,我們親手編寫了天氣查詢和計算機的邏輯。但 MCP 生態系的真正魅力在於互操作性 (interoperability) —— 我們不僅要會創造工具,更要懂得如何使用別人已經創造好的工具。
今天,我們將進行一次華麗的角色轉換,從 MCP Server (服務提供者) 轉變為 MCP Host (服務消費者)。我們將學習如何讓我們的 Python Agent 連接上公開的、由第三方開發的 MCP 伺服器,並將它們的能力化為己用。
我們將整合兩個由 MCP 官方社群提供的、非常實用的 MCP 伺服器:
list_directory
(列出目錄), read_file
(讀取檔案) 等操作。
在開始寫程式碼之前,請確保您的環境已準備就緒:
which npx
(Node.js 的一部分) 和 which adk
指令都可正常使用。fetch
工具的 Docker 映像檔拉到本地。
docker pull mcp/fetch
# 例如在桌面建立一個資料夾
mkdir ~/Desktop/MyAgentWorkFolder
cd ~/Desktop/MyAgentWorkFolder
touch test1.txt test2.md
agent.py
現在,讓我們用全新的程式碼來覆蓋 agent.py
。這段程式碼的核心是使用 MCPToolset
來定義並連接到外部的 MCP 伺服器。
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
from mcp import StdioServerParameters
# --- 1. 定義檔案系統工具的工作目錄 ---
# 請務必將此路徑修改為您自己電腦上的實際路徑
TARGET_FOLDER_PATH = "/Users/imac/Desktop/MyAgentWorkFolder"
# --- 2. 定義檔案系統工具集 ---
filesystem_toolset = MCPToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
# ADK 會在背景幫我們執行這個 npx 指令來啟動伺服器
command='npx',
args=[
"-y",
"@modelcontextprotocol/server-filesystem",
TARGET_FOLDER_PATH, # 將工作目錄作為參數傳入
],
),
),
# tool_filter=['list_directory'] # 可選:若只希望 Agent 使用部分工具,可取消此行註解
)
# --- 3. 定義 Docker Fetch 工具集 ---
fetch_toolset = MCPToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
# ADK 會在背景幫我們執行 docker run 指令來啟動伺服器
command='docker',
args=['run', '-i', '--rm', 'mcp/fetch']
)
)
)
# --- 4. 建立整合了兩種外部工具集的 Agent ---
root_agent = LlmAgent(
model='gemini-1.5-flash',
name='file_and_web_assistant_agent',
instruction=(
"你是一位強大的助理,不僅可以幫使用者管理本地檔案(例如列出目錄、讀取檔案),"
"還可以使用 Docker 容器裡的工具來擷取網路資料。"
"請根據使用者的問題,判斷應該使用檔案工具還是網路擷取工具。"
),
tools=[
filesystem_toolset, # 註冊第一個工具集
fetch_toolset # 註冊第二個工具集
],
)
MCPToolset
: 這是 ADK 中的關鍵類別。它代表的不是單一工具,而是一整套由外部 MCP 伺服器提供的工具。StdioConnectionParams
: 我們告訴 ADK,要透過標準輸入/輸出 (Stdio) 的方式與這些外部伺服器溝通。StdioServerParameters
: 我們在這裡定義了如何啟動這些外部伺服器。ADK 會在幕後為我們管理這些子進程 (sub-processes)。tools=[filesystem_toolset, fetch_toolset]
: 這是最神奇的地方!我們不再傳入 Python 函式,而是傳入 MCPToolset
的實例。我們的 Agent 現在的能力,是由這兩個外部伺服器動態決定的!adk web
adk web
啟動時,它會自動在背景執行 npx
和 docker run
指令,啟動我們定義的兩個 MCP 伺服器。http://127.0.0.1:8000
,選擇 multi_tool_agent
。現在,來測試我們 Agent 的新能力吧!
使用者指令: 列出現有資料夾內有什麼檔案
成果: Agent 成功理解了指令,選擇了 filesystem_toolset
,並呼叫了其中的 list_directory
工具,正確地列出了我們在 MyAgentWorkFolder
中建立的檔案!
使用者指令: 請給我看這則新聞的內容 https://news.ttv.com.tw/news/1140907000100W
成果: Agent 再次正確地判斷出這個任務需要上網,選擇了 fetch_toolset
,並呼叫了 fetch
工具,雖然成功地抓取資訊,但感覺成效不是太好,似乎他的 tools 抓取有被什麼東西阻擋的樣子
今天我們完成了一次華麗的角色轉換,從工具的創造者變成了優雅的消費者。我們學到了:
MCPToolset
: 這是 ADK 中連接外部 MCP Server 的關鍵。我們的 AI Agent 現在就像擁有了無限手套,可以隨時嵌入來自社群的各種「能力寶石」。
明天,我們將回到「創造者」的角色,並且把我們的工具部屬在雲端上!!!