[智能体-240]:LangChain实现MCP工具调用的代码示例(MCP client端)
LangChain + MCP Client 工具调用最简示例
架构说明:
- MCP Server:独立进程 / 远端服务,向外暴露标准化 MCP 接口、提供工具元信息与远程执行;
- MCP Client(本示例):在 LangChain 侧封装成标准
LangChain Tool,塞入bind_tools,沿用原有 LCEL 链路:Prompt | llm.bind_tools(mcp_tools) | tool_exec;- 上层 Chain 完全复用原有
bind_tools + RunnableLambda执行器,业务链路无改动。
前置:MCP 遵循 Model Context Protocol 标准 JSON-RPC,示例封装通用 MCP 客户端;假设已有一台运行在
http://127.0.0.1:8080/mcp的 MCP 服务。
1、依赖安装
bash
运行
pip install langchain langchain-openai requests pydantic2、通用 MCP Client 封装(把远端 MCP 服务转为 LangChain Tool)
python
运行
import requests from typing import Dict, Any from langchain_core.tools import Tool from langchain_core.tools.base import BaseTool class MCPClient: def __init__(self, endpoint: str): self.endpoint = endpoint self.session = requests.Session() def list_tools(self) -> list[Dict[str, Any]]: """MCP协议:拉取远端全部工具元数据(name/desc/parameters schema)""" req = { "jsonrpc": "2.0", "id": 1, "method": "tools/list" } # 从远程MCP server获取tools清单 resp = self.session.post(self.endpoint, json=req).json() return resp["result"]["tools"] def call_tool(self, tool_name: str, args: Dict[str, Any]) -> str: """MCP协议:远程调用工具""" req = { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": tool_name, "arguments": args } } # 对远程mcp server发起请求,远程执行tool调用 resp = self.session.post(self.endpoint, json=req).json() return str(resp["result"]["content"]) def to_langchain_tools(self) -> list[BaseTool]: """将MCP远端工具自动转换成LangChain @Tool格式""" mcp_tools_raw = self.list_tools() lc_tools = [] for item in mcp_tools_raw: name = item["name"] desc = item["description"] params_schema = item["inputSchema"] def create_tool(n=name): def _run(**kwargs): return self.call_tool(n, kwargs) return _run lc_tool = Tool( name=name, description=desc, func=create_tool() ) lc_tools.append(lc_tool) return lc_tools3、LCEL 完整链路:bind_tools + 通用 tool_exec 执行器
python
运行
from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, AIMessage, ToolMessage from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnableLambda # ① 初始化MCP客户端,对接远端MCP Server mcp_client = MCPClient(endpoint="http://127.0.0.1:8080/mcp") # 自动拉取远端所有工具,转为LangChain标准工具 mcp_tool_list = mcp_client.to_langchain_tools() tool_map = {t.name: t for t in mcp_tool_list} # ② LLM绑定MCP远程工具(和本地工具bind_tools写法完全一致) base_llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) llm_with_mcp = base_llm.bind_tools(mcp_tool_list) # ③ 通用工具执行节点:复用原有RunnableLambda执行逻辑(本地/远程工具统一执行) def tool_exec_func(ai_msg: AIMessage): if not ai_msg.tool_calls: return ai_msg.content msg_list = [] for call in ai_msg.tool_calls: tool = tool_map[call["name"]] res = tool.run(call["args"]) msg_list.append(ToolMessage(content=str(res), tool_call_id=call["id"])) final_msg = llm_with_mcp.invoke([HumanMessage(""), ai_msg] + msg_list) return final_msg.content tool_exec_node = RunnableLambda(tool_exec_func) # ④ 组装标准LCEL链路 prompt = ChatPromptTemplate.from_messages([("user", "{query}")]) chain = prompt | llm_with_mcp | tool_exec_node4、调用测试
python
运行
# 示例:MCP服务内置计算器、查字符串长度等远端工具 resp = chain.invoke({"query": "计算 123 + 456"}) print(resp)关键要点(贴合之前分工逻辑)
bind_tools无改动:MCP 远端工具经过封装后和本地 Python 工具使用方式完全一致,LLM 只看工具 name/desc/schema,分不清是本地函数还是网络远程调用;- tool_exec 执行节点无改动:
tool.run()内部已经被 MCP Client 封装为网络请求,上层执行逻辑统一,不用区分本地 / 远程; - 解耦价值:MCP Server 独立部署、独立升级;LangChain Agent 不用改代码、不用重新打包,仅修改 MCP 对接地址即可切换远端工具服务。
拓展:本地 + MCP 远程工具混用
python
运行
# 本地自定义工具 + MCP远程工具合并放入同一tools列表 from langchain_core.tools import tool @tool def local_hello(name: str) -> str: """本地函数:打招呼""" return f"hello {name}" all_tools = [local_hello] + mcp_tool_list llm_all = base_llm.bind_tools(all_tools)LLM 自动按需选择调用本地函数 或 MCP 远端服务。
补充:MCP Server 简易示意(伪逻辑)
python
运行
# MCP Server内部:收到tools/call,调用内部业务函数,返回结果 # 工具实现可以是任意语言(Python/Java/Go),与LangChain项目彻底分离