在 昨天 Day 18,我們看到 MCP (Model Context Protocol) 如何把工具抽象成獨立服務,讓同一個工具能被 Claude Desktop、VSCode 插件,甚至不同 Agent 框架共用,大幅提升可攜性與治理彈性。
昨天我們先嘗試了 Claude Desktop 的整合,體驗了 MCP 如何讓外部 API 工具以獨立服務的方式接入應用。
今天,我們要把這個概念延伸到 LangChain (最新 v1.0 版) —— 讓 Agent 也能透過 MCP 來呼叫工具,並把結果整理成自然語言回覆。
這一步,就像在不同框架之間搭起一座橋,讓同一個工具可以跨平台使用。
雖然 LangChain 本身已經有完整的工具系統(例如 @tool
、ToolNode
等),
MCP 的價值在於,它讓工具可以 脫離框架束縛,成為獨立的「跨平台服務」。
這樣的設計有幾個好處:
更直觀的比喻是:
MCP 就像一個標準化的「USB 插槽」,把不同工具變成可以隨插即用的裝置;
LangChain Agent 則像「電腦」,透過插槽與工具互動,依需求來運用它們。
電腦不需要理解滑鼠或隨身碟的內部設計,只要透過 USB 插槽,就能順利使用。
我們延續昨天的例子 —— 查詢維也納天氣。
不同的是,這次改由 LangChain Agent 透過 MCP 工具來完成。
(以下程式寫法皆使用 LangChain 最新 v1.0 版,官方預計十月份(這個月)會全面切換到 v1.0 版本)
圖:使用者提出問題後,LangChain Agent 判斷需要工具,呼叫 MCP Server 的 get_weather
。MCP Server 負責轉接至 AccuWeather API,取得天氣資料,再回傳給 Agent,由 Agent 整理成自然語言回覆給使用者。
整個流程可以分成三個層次:
使用者層
LangChain Agent 層
get_weather
)。MCP Server 層
get_weather
負責與 AccuWeather API 溝通。透過這樣的分工,LangChain 專注在推理與對話,而 MCP 則把外部 API 包裝成 跨框架可重用的服務,讓工具在不同應用之間保持一致性。
要讓 LangChain Agent 能透過 MCP 呼叫工具,前提是要有一個 MCP Server 負責提供工具。
這部分的建立方式與細節,已經在 昨天 Day 18 的 Demo:把 AccuWeather 包裝成 MCP 工具 中完整說明。
簡單來說,MCP Server 的角色是:
get_weather
)。在進入程式之前,先安裝必要套件,並設定環境變數:
# 安裝套件
pip install -q --pre -U langchain
pip install -q -U langchain-google-genai
pip install -q langchain-mcp-adapters
# 設定環境變數
export GOOGLE_API_KEY={你的 Google API Key}
export ACCUWEATHER_API_KEY={你的 AccuWeather API Key}
以下程式示範如何將 MCP 工具注入 LangChain Agent:
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
import asyncio
import os
async def run_agent_with_accuweather_mcp():
# 從環境變數讀取 AccuWeather API Key
accuweather_api_key = os.getenv("ACCUWEATHER_API_KEY")
if not accuweather_api_key:
raise ValueError("請設定 ACCUWEATHER_API_KEY 環境變數")
# 建立 MultiServerMCPClient,並設定 AccuWeather MCP Server
client = MultiServerMCPClient(
{
"accuweather": {
"transport": "stdio",
"command": "uv",
"args": [
"--directory",
"{MCP 程式路徑}",
"run",
"weather_mcp_server.py"
],
"env": {"ACCUWEATHER_API_KEY": accuweather_api_key}
}
}
)
# 取得 MCP 工具
tools = await client.get_tools()
# 從環境變數讀取 Google API Key
google_api_key = os.getenv("GOOGLE_API_KEY")
if not google_api_key:
raise ValueError("請設定 GOOGLE_API_KEY 環境變數")
# 建立 Gemini-2.5-FLASH LLM
llm = init_chat_model(
"gemini-2.5-flash",
model_provider="google_genai",
api_key=google_api_key
)
# 建立 Agent,並加入 MCP 工具
agent = create_agent(
model=llm,
tools=tools,
prompt="你是一位天氣助理,可以透過工具查詢城市的即時天氣。"
)
# 與 Agent 對話,詢問維也納的天氣
response = await agent.ainvoke({
"messages": [{"role": "user", "content": "維也納的天氣如何?"}]
})
print("\n=== 對話歷程 ===")
for m in response["messages"]:
role = m.__class__.__name__
print(f"[{role}] {getattr(m, 'content', '') or getattr(m, 'tool_calls', '')}")
print("\n=== 模型最終回答 ===")
print(response["messages"][-1].content)
if __name__ == "__main__":
asyncio.run(run_agent_with_accuweather_mcp())
這段程式主要完成以下幾件事:
讀取 API Key
ACCUWEATHER_API_KEY
與 GOOGLE_API_KEY
,確保程式能連線到 AccuWeather API 與 Gemini 模型。建立 MCP Client
MultiServerMCPClient
連線到 AccuWeather MCP Server,並將 get_weather
工具註冊進來。uv run main.py
)、路徑與環境變數。取得工具清單
client.get_tools()
,動態取得 MCP Server 提供的工具(此例為 get_weather
)。建立 LLM
建立 Agent 並注入 MCP 工具
create_agent
把 LLM 與 MCP 工具組合在一起。執行對話
ainvoke
模擬一次對話,輸入「維也納的天氣如何?」。get_weather
,最後輸出自然語言答案。圖:使用者詢問「維也納的天氣如何?」後,LangChain Agent 判斷需要呼叫 MCP 工具 get_weather
,並由 MCP Server 向 AccuWeather API 取得即時天氣資料。接著 Agent 將 JSON 資料整理成自然語言回答,完整呈現氣溫、體感溫度、濕度、能見度、風速與紫外線指數等資訊,回覆給使用者。
這裡可以看到:
Agent 呼叫 MCP 工具 —— 帶入 city="維也納"
的參數。
MCP Server 負責 API 互動 —— 向 AccuWeather API 取回即時天氣資料。
Agent 整理回覆 —— 將結構化數據轉換成自然語言答案。
分工的關鍵價值 ——
今天的重點是基礎整合:
這是一個重要的轉折點:
工具不再依賴某一個框架,而是成為真正的 「共享資源」。
明天,我們將進一步挑戰:
不只是一個 MCP 工具,而是讓 Agent 能 同時協調多個 MCP 工具,並引入 ReAct 推理策略 —— 讓工具之間不再只是單獨呼叫,而能展開「智慧的對話」。
圖:布拉格克萊門特學院(Klementinum)的「天文塔 (Astronomical Tower)」內部,早期以大型日晷與弧形測角儀測量太陽位置來校準時間。這些精密的觀測工具,讓天文學家能準確掌握宇宙規律。正如 MCP 的角色 —— 提供標準化的「工具介面」,讓不同系統能在同一基準下協同運作,維持知識與應用的一致性。(攝影:作者自攝)