📚 第31课核心知识点梳理:MCP 工具与智能小秘书案例
一、什么是 MCP?(Model Context Protocol)
MCP(模型上下文协议)是一个开放的标准化协议,旨在解决 AI 大语言模型与外部工具、数据源之间的"连接碎片化"问题。在传统的 AI Agent 开发中,开发者需要为每个外部服务编写专用的适配器,导致系统维护成本高、扩展性差。MCP 提供了一个统一的规范:
| MCP 核心设计 | 说明 |
|---|---|
| 统一工具描述格式 | 通过标准的 Tool Schema 定义工具的输入参数、输出格式和执行方式 |
| 跨语言客户端/服务端实现 | 支持 stdio 管道、HTTP SSE 等多种通信方式 |
| 服务发现机制 | 通过注册中心实现 MCP Server 的动态加载 |
| 版本兼容性保障 | 协议标准化,避免 API 变更导致的集成问题 |
采用 MCP 后,新工具接入时间从平均 72 小时缩短至 15 分钟以内。
二、为什么需要 MCP?
- 工具链碎片化:每个外部系统需要定制 API 连接代码,维护成本高昂
- 多模型协同:支持不同厂商 LLM 的无缝切换,避免技术锁定
- 开发效率跃升:标准化协议使集成成本降低 68%,开发周期缩短 42%
三、LangGraph 与 MCP 的两种集成模式
LangGraph 与 MCP 的融合有两种模式,各自适用于不同的场景。
| 集成模式 | 说明 | 适用场景 |
|---|---|---|
| 客户端集成模式 | 将 MCP Server 暴露的工具集作为 LangGraph 工作流中的原子节点,Agent 可通过统一接口调用外部服务 | 调用外部 NLP 服务、访问向量数据库、集成第三方 API |
| 服务端封装模式 | 将现有 LangGraph 工作流暴露为 MCP 服务,供其他系统调用 | 复用已有流程、构建可组合的工作流服务 |
下面通过完整的案例演示这两种模式。
🪐 星系案例:智能小秘书系统
构建一个支持多工具调用的智能小秘书系统,集成数学计算和天气查询两大能力,通过 MCP 协议统一管理。
案例整体架构图
目录结构
mcp_intelligent_secretary/ ├── math_server.py # 数学计算 MCP Server (stdio) ├── weather_server.py # 天气查询 MCP Server (HTTP/SSE) ├── agent_client.py # LangGraph Agent 客户端 └── .env # 环境配置步骤一:安装依赖
pipinstalllangchain-mcp-adapters langgraph langchain-openai mcp httpx python-dotenv步骤二:数学计算 MCP Server(stdio 通信)
# math_server.pyimportasynciofrommcp.serverimportServerfrommcp.server.stdioimportstdio_serverfrommcp.typesimportTool,TextContentimportjson app=Server("math-server")@app.list_tools()asyncdeflist_tools():return[Tool(name="add",description="计算两个数的和",inputSchema={"type":"object","properties":{"a":{"type":"number","description":"第一个数"},"b":{"type":"number","description":"第二个数"}},"required":["a","b"]}),Tool(name="multiply",description="计算两个数的乘积",inputSchema={"type":"object","properties":{"a":{"type":"number","description":"第一个数"},"b":{"type":"number","description":"第二个数"}},"required":["a","b"]}),]@app.call_tool()asyncdefcall_tool(name:str,arguments:dict):ifname=="add":result=arguments["a"]+arguments["b"]return[TextContent(type="text",text=str(result))]elifname=="multiply":result=arguments["a"]*arguments["b"]return[TextContent(type="text",text=str(result))]raiseValueError(f"Unknown tool:{name}")asyncdefmain():asyncwithstdio_server()as(read_stream,write_stream):awaitapp.run(read_stream,write_stream,app.create_initialization_options())if__name__=="__main__":asyncio.run(main())步骤三:天气查询 MCP Server(HTTP SSE 通信)
# weather_server.pyimportasyncioimportjsonfrommcp.serverimportServerfrommcp.server.sseimportSseServerTransportfrommcp.typesimportTool,TextContentfromstarlette.applicationsimportStarlettefromstarlette.routingimportRouteimportuvicorn app=Server("weather-server")sse=SseServerTransport("/messages")@app.list_tools()asyncdeflist_tools():return[Tool(name="get_weather",description="查询指定城市的天气信息",inputSchema={"type":"object","properties":{"city":{"type":"string","description":"城市名称,如北京、上海、广州"}},"required":["city"]})]@app.call_tool()asyncdefcall_tool(name:str,arguments:dict):ifname=="get_weather":city=arguments["city"]# 模拟天气查询weather_data={"北京":"晴朗,25°C,空气质量良好","上海":"多云,22°C,湿度适中","广州":"阵雨,28°C,注意带伞"}result=weather_data.get(city,f"晴转多云,20°C")return[TextContent(type="text",text=f"{city}天气:{result}")]raiseValueError(f"Unknown tool:{name}")# Starlette 应用(支持 SSE)asyncdefhandle_sse(request):asyncwithsse.connect_sse(request.scope,request.receive,request._send)asstreams:awaitapp.run(streams[0],streams[1],app.create_initialization_options())routes=[Route("/sse",endpoint=handle_sse),Route("/messages",endpoint=sse.handle_post_message,methods=["POST"]),]starlette_app=Starlette(routes=routes)if__name__=="__main__":uvicorn.run(starlette_app,host="127.0.0.1",port=8000)步骤四:LangGraph Agent 客户端
# agent_client.pyimportasyncioimportosfromdotenvimportload_dotenvfromlangchain_openaiimportChatOpenAIfromlangchain_mcp_adapters.clientimportMultiServerMCPClientfromlanggraph.prebuiltimportcreate_react_agentfromlanggraph.checkpoint.memoryimportMemorySaver load_dotenv()ifos.name=='nt':importsysimportasyncioifsys.platform=='win32':asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())# 初始化 LLMllm=ChatOpenAI(model="qwen-plus",temperature=0.7,api_key=os.getenv("DASHSCOPE_API_KEY"),base_url=os.getenv("DASHSCOPE_BASE_URL"),)asyncdefmain():# 配置多个 MCP Servermcp_servers={"math":{"command":"python","args":["math_server.py"],"transport":"stdio",},"weather":{"url":"http://127.0.0.1:8000/sse","transport":"sse",},}# 创建 MCP 客户端并获取工具asyncwithMultiServerMCPClient(mcp_servers)asclient:tools=awaitclient.get_tools()print(f"✅ 加载了{len(tools)}个 MCP 工具:")fortoolintools:print(f" -{tool.name}:{tool.description}")# 创建 LangGraph Agentagent=create_react_agent(model=llm,tools=tools,prompt="你是一个智能小秘书,可以帮助用户进行数学计算和查询天气。")# 交互对话print("\n🤖 智能小秘书已启动(输入 quit 退出)\n")config={"configurable":{"thread_id":"user_001"}}whileTrue:user_input=input("用户: ")ifuser_input.lower()=="quit":breakresponse=awaitagent.ainvoke({"messages":[("user",user_input)]},config=config)print(f"助手:{response['messages'][-1].content}\n")if__name__=="__main__":asyncio.run(main())启动顺序
# 终端1:启动数学 MCP Serverpython math_server.py# 终端2:启动天气 MCP Serverpython weather_server.py# 终端3:启动 Agentpython agent_client.py📊 对话测试效果
✅ 加载了 3 个 MCP 工具: - add: 计算两个数的和 - multiply: 计算两个数的乘积 - get_weather: 查询指定城市的天气信息 🤖 智能小秘书已启动(输入 quit 退出) 用户: 3 + 5 等于多少? 助手: 3 + 5 = 8。 用户: 把这个结果乘以 4,然后告诉我 助手: 8 × 4 = 32。 用户: 北京今天天气怎么样? 助手: 北京天气:晴朗,25°C,空气质量良好。📌 关键代码解析
1.MultiServerMCPClient
统一管理多个 MCP Server,支持 stdio 和 SSE 两种通信方式。
2.client.get_tools()
自动发现注册的工具,将 MCP Tool 转换为 LangChain Tool 对象。
3.create_react_agent
LangGraph 预置的 ReAct Agent,自动处理工具调用循环。
🎯 高频面试题汇总
一、MCP 基础概念题
| 面试问题 | 核心回答要点 |
|---|---|
| 什么是 MCP?为什么需要它? | MCP(Model Context Protocol)是开放协议,解决 LLM 与外部工具集成的碎片化问题。需解释传统开发痛点(定制 API 适配器)和 MCP 价值(工具接入时间从 72 小时→15 分钟) |
| MCP 1.0 和 2.0 的主要区别? | MCP 2.0 增强版本兼容性、改进动态服务发现机制、引入闭环反馈与可视化编排 |
| MCP 与 Function Calling 的区别? | Function Calling 是模型专有特性,由模型在运行时决定调用哪个函数;MCP 是协议层标准化,提供统一工具描述,解耦工具实现与模型 |
| MCP Server 的两种通信方式? | stdio(标准输入输出,适合本地子进程);SSE(Server-Sent Events,适合远程 HTTP 调用) |
二、LangGraph + MCP 集成题
| 面试问题 | 核心回答要点 |
|---|---|
| LangGraph 与 MCP 如何集成? | 两种模式:客户端集成模式(工具节点化);服务端封装模式(工作流暴露为服务) |
| 如何实现多 MCP Server 并行调用? | 用 MultiServerMCPClient 统一管理,内部通过 asyncio.gather 并发执行 |
| MCP 工具调用失败如何处理? | 在 Agent 中实现重试策略和降级方案;支持同步/异步混合调用,自动适配 |
三、工程实战题
| 面试问题 | 核心回答要点 |
|---|---|
| 开发 MCP Server 的关键步骤? | 创建 Server 实例、定义 list_tools 返回工具 Schema、实现 call_tool 处理请求、配置传输层(stdio/SSE) |
| MCP 工具如何定义输入输出? | 通过 inputSchema(JSON Schema)定义参数类型和必填项;Tool 对象含 name、description、inputSchema |
| MCP Server 如何实现服务发现? | 通过注册中心机制实现动态加载,客户端通过 MultiServerMCPClient 配置 endpoints |
| Agent 如何自动选择合适的 MCP 工具? | LangGraph ReAct Agent 根据工具 description 调用 LLM 判断;MCP 提供统一 Tool Schema 支持动态路由 |
💡 总结:MCP + LangGraph 的三大核心价值
- 能力解耦:将 AI 能力封装为独立节点,“一次开发,多处调用”
- 标准化集成:通过统一接口规范,实现不同厂商 LLM 与工具的灵活组合
- 闭环反馈:LangGraph 的状态管理与 MCP 反馈机制形成智能闭环系统
MCP 是一个开放标准,你可以扩展更多自定义的 MCP Server 来集成任何外部 API 或服务,并根据实际业务需求定制工具 Schema。通过本次实践,你可以直观理解 MCP 如何让 Agent 从“只会聊天”进阶到“会动手执行任务”的智能助手。