MCP实战:使用 LangGraph 和 MCP 协议无缝集成外部工具
在构建强大的 AI 智能体时,一个核心挑战是如何让大语言模型(LLM)突破其固有的知识边界,与外部世界进行交互。无论是执行复杂的数学运算、查询实时天气,还是调用企业内部 API,工具(Tools)都是扩展模型能力的关键。然而,工具的多样性和部署方式的差异,常常让集成过程变得复杂且不统一。
为了解决这一痛点,模型上下文协议(Model Context Protocol, MCP) 应运而生。MCP 是一个开放协议,旨在标准化应用程序向语言模型提供工具和上下文信息的方式。通过 MCP,开发者可以将任何功能封装成一个标准化的“工具服务器”,供不同的 LlamaIndex、LangChain 等框架调用,从而实现工具生态的解耦与复用。
在 LangGraph 生态中,我们可以通过 langchain-mcp-adapters
库,让我们的智能体轻松发现并使用托管在 MCP 服务器上的各种工具。本文将详细介绍如何在 LangGraph 中集成 MCP 工具,并创建你自己的 MCP 服务器。
第一步:使用 MCP 工具
LangGraph 提供了两种主要方式来使用 MCP 工具:一种是使用预构建的 create_react_agent
,另一种是手动构建一个自定义的 StateGraph。两者的核心都是通过 MultiServerMCPClient
客户端连接到一个或多个 MCP 服务器。
首先,你需要安装必要的库:
pip install langchain-mcp-adapters
方式一:使用预构建的 React Agent
这是最简单快捷的方式。你只需配置好 MCP 服务器的连接信息,获取工具列表,然后将其绑定到一个预构建的智能体上即可。
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent# 配置 MCP 客户端,连接到不同的工具服务器
client = MultiServerMCPClient({"math": { # 数学工具服务器"command": "python","args": ["/path/to/your/math_server.py"], # 替换为你的数学服务器脚本的绝对路径"transport": "stdio", # 通过标准输入/输出通信},"weather": { # 天气工具服务器"url": "http://localhost:8000/mcp", # 服务器运行在本地 8000 端口"transport": "streamable_http", # 通过 HTTP 流式传输}}
)# 异步获取所有可用的工具
tools = await client.get_tools()# 创建一个使用 Anthropic Claude 模型和 MCP 工具的智能体
agent = create_react_agent(model="anthropic:claude-3-5-sonnet-latest",tools=tools
)# 调用智能体进行数学计算
math_response = await agent.ainvoke({"messages": [{"role": "user", "content": "what's (3 + 5) x 12?"}]}
)
print(math_response["messages"][-1].content) # 输出: 96# 调用智能体查询天气
weather_response = await agent.ainvoke({"messages": [{"role": "user", "content": "what is the weather in nyc?"}]}
)
print(weather_response["messages"][-1].content) # 输出天气信息
方式二:构建自定义 StateGraph
如果你需要更精细的控制,比如自定义决策逻辑或状态管理,可以手动构建一个 StateGraph。这种方式虽然代码量稍多,但灵活性极高。
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain.chat_models import init_chat_model
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode# 初始化大语言模型
model = init_chat_model("anthropic:claude-3-5-sonnet-latest")# 配置并连接 MCP 客户端
client = MultiServerMCPClient({"math": {"command": "python","args": ["./examples/math_server.py"],"transport": "stdio",},"weather": {"url": "http://localhost:8000/mcp/","transport": "streamable_http",}}
)
tools = await client.get_tools()# 将工具绑定到模型,使其知道可以调用哪些工具
model_with_tools = model.bind_tools(tools)# 创建一个用于执行工具调用的节点
tool_node = ToolNode(tools)# 定义决策函数:检查模型的回复是否包含工具调用
def should_continue(state: MessagesState):last_message = state["messages"][-1]if last_message.tool_calls: # 如果有工具调用,则进入工具节点return "tools"return END # 否则结束# 定义调用模型的节点函数
async def call_model(state: MessagesState):response = await model_with_tools.ainvoke(state["messages"])return {"messages": [response]}# 构建计算图
builder = StateGraph(MessagesState)
builder.add_node("call_model", call_model)
builder.add_node("tools", tool_node)
builder.add_edge(START, "call_model")
# 从模型节点根据条件决定是调用工具还是结束
builder.add_conditional_edges("call_model", should_continue)
# 工具执行完毕后,返回给模型节点进行下一步处理(如总结结果)
builder.add_edge("tools", "call_model")# 编译图
graph = builder.compile()# 测试自定义图
response = await graph.ainvoke({"messages": [{"role": "user", "content": "what's (3 + 5) x 12?"}]}
)
print(response["messages"][-1].content)
第二步:创建你自己的 MCP 服务器
MCP 的强大之处在于其开放性和易用性。你可以使用 mcp
库快速创建自己的工具服务器,并将其暴露给任何兼容 MCP 的客户端(如 LangGraph)。
首先,安装 mcp
库:
pip install mcp
示例 1:创建一个数学工具服务器
下面的代码定义了一个名为 “Math” 的 MCP 服务器,提供 add
和 multiply
两个工具。
# math_server.py
from mcp.server.fastmcp import FastMCP# 创建一个名为 "Math" 的 MCP 服务器实例
mcp = FastMCP("Math")# 使用装饰器将普通函数注册为 MCP 工具
@mcp.tool()
def add(a: int, b: int) -> int:"""Add two numbers"""return a + b@mcp.tool()
def multiply(a: int, b: int) -> int:"""Multiply two numbers"""return a * b# 启动服务器,通过标准输入/输出与客户端通信
if __name__ == "__main__":mcp.run(transport="stdio")
示例 2:创建一个天气工具服务器
这个服务器通过 HTTP 提供服务,模拟返回纽约的天气。
# weather_server.py
from mcp.server.fastmcp import FastMCPmcp = FastMCP("Weather")@mcp.tool()
async def get_weather(location: str) -> str:"""Get weather for location."""# 这里可以集成真实的天气 APIreturn f"It's always sunny in {location}"if __name__ == "__main__":# 启动 HTTP 服务器,默认端口通常是 8000mcp.run(transport="streamable-http")
启动服务器:
# 启动数学服务器(通常由客户端进程调用)
# 启动天气服务器
python weather_server.py
总结
通过 MCP 协议和 LangGraph 的 langchain-mcp-adapters
,我们实现了一种优雅且标准化的工具集成方案。开发者可以:
- 快速集成:无需为每个新工具编写复杂的适配器,只需将其部署为 MCP 服务器。
- 灵活扩展:智能体可以动态发现并使用来自不同服务器、不同团队开发的工具。
- 解耦架构:工具的实现与智能体的逻辑完全分离,便于独立开发、测试和维护。
MCP 正在成为连接 LLM 与外部世界的通用桥梁。无论你是想构建一个简单的个人助手,还是一个复杂的企业级 AI 平台,MCP 都能为你提供强大的底层支持。现在就开始尝试,为你的 LangGraph 智能体插上 MCP 的翅膀吧!