ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Langchain 使用 mcp 服务:把 MCP 工具接入 Langchain Agent 的配置与验证

Langchain 使用 mcp 服务:把 MCP 工具接入 Langchain Agent 的配置与验证 1. 为什么 Langchain Agent 接 MCP 总在工具描述这步卡住Langchain 使用 mcp 服务这件事真正让人头疼的从来不是 Agent 本身而是「工具从哪来、长什么样、怎么被 Agent 看见」。Langchain 的 Agent 依赖一份结构化的工具列表每个工具要有 name、description、args_schema模型才能判断该不该调用、传什么参数。而 MCPModel Context Protocol服务暴露出来的工具是另一套描述体系字段命名、参数结构、调用入口都不一样。你直接把 MCP Server 的 JSON 塞给 Agent它大概率会报参数校验失败或者干脆不调用工具只在最后编一段看起来像答案的文字。我见过最常见的三种翻车现场第一种是 MCP Server 明明启动了但 Langchain 侧拿到的 tools 列表是空的Agent 退化成纯聊天第二种是工具能列出来但 description 是空的或者全是英文乱码模型不知道这工具干嘛用于是永远不选它第三种是工具被调用了但参数 schema 对不上执行时报ValidationErrorAgent 拿到异常后又开始胡编。这三种问题的根因其实是一个MCP 的工具描述没有经过一层「翻译」就直接喂给了 Langchain。这篇要解决的就是这个翻译层。我会用一个可复制的路径把 MCP Server 启动、工具描述读取、Langchain Agent 绑定、端到端调用验证串起来。适合已经写过 Langchain Agent、但还没把 MCP 工具接进去的同学也适合手里有一堆 MCP Server、想让它们被 Agent 统一调度的场景。核心检索词就是 Langchain 使用 mcp 服务全文围绕「配置 验证 排障」展开不堆概念。先说清楚一个前提MCP 服务分远程和本地两类。远程的一般给一个 URL走 streamable-https 或 sse本地的一般是一个 command 加 args比如npx -y howtocook-mcp或者python ./assistant_server.py。这两类在 Langchain 侧的接入方式不同但最终都要变成 Langchain 能识别的 tool 对象。下面我会先讲前置准备再给可复制配置然后是验证和排障。2. TaoToken 前置把模型入口和 MCP 工具链先对齐在写 Agent 代码之前先把模型入口定下来。Langchain 的ChatOpenAI需要一个openai_api_base和openai_api_key很多人卡在这里是因为 base 写错、key 没配、或者模型名和实际可用模型对不上。我建议统一走一个兼容 OpenAI 协议的入口这样 Langchain 侧不用改代码只改三个变量。TaoToken 的 API 入口是https://taotoken.net/api兼容 OpenAI 的/v1/chat/completions和/v1/models。你可以在控制台创建 key然后在 Langchain 里这样配from langchain_openai import ChatOpenAI llm ChatOpenAI( temperature0, modeldeepseek-chat, openai_api_keysk-你的key, openai_api_basehttps://taotoken.net/api/v1, )注意openai_api_base要带/v1因为 Langchain 的 OpenAI 封装会在后面拼/chat/completions。如果你只写到https://taotoken.net/api请求会打到https://taotoken.net/api/chat/completions路径不对就会 404。这个坑我踩过报错信息是Error code: 404 - {detail: Not Found}看起来像 key 问题其实是 base 少了/v1。模型名这块deepseek-chat是常用的工具调用模型支持 function calling适合 Agent 场景。如果你要用别的模型先去模型对话页面确认一下模型 ID别凭记忆写。key 的创建在 API Keys 页面创建后复制一次后面就看不到了。MCP 工具链这边你需要一个能管理 MCP Server 生命周期的库。直接用官方mcp包也行但要自己处理进程启动、超时、工具描述转换代码量不小。我这次用mcpstore它把「注册服务、等待就绪、导出 Langchain 工具」这几步封装好了几行代码就能拿到list_tools()。安装pip install mcpstore langchain langchain-openai langchain-core装完之后先确认版本python -c import mcpstore, langchain; print(mcpstore.__version__, langchain.__version__)如果mcpstore导入报ModuleNotFoundError多半是 pip 装到了别的 Python 环境。用which python和which pip对一下确保是同一个解释器。这一步看着简单但后面所有报错排查都要基于「环境一致」这个前提。3. 可复制配置MCP Server 注册与 Langchain 工具导出这一节是全文的核心给一份能直接跑的配置。先讲远程 MCP 服务再讲本地进程最后讲怎么导出成 Langchain 工具。远程服务注册用 URL 方式from mcpstore import MCPStore store MCPStore.setup_store() store.for_store().add_service({ name: mcpstore-wiki, url: https://mcpstore.wiki/mcp, transport: streamable-https, }) store.for_store().wait_service(mcpstore-wiki, timeout30)transport可以省略库会自动推断但显式写出来更稳。wait_service的 timeout 单位是秒远程服务一般 10 到 30 秒够了。如果超时先别改代码用 curl 测一下 URL 通不通curl -i -X POST https://mcpstore.wiki/mcp \ -H Content-Type: application/json \ -H Accept: application/json, text/event-stream \ -d {jsonrpc:2.0,id:1,method:initialize,params:{protocolVersion:2024-11-05,capabilities:{},clientInfo:{name:probe,version:1.0}}}返回 200 且带result字段说明服务端没问题问题在客户端配置。本地进程注册用 command 加 argsstore.for_store().add_service({ name: howtocook, command: npx, args: [-y, howtocook-mcp], }) store.for_store().wait_service(howtocook, timeout60)本地服务启动慢timeout 给 60 秒。如果npx找不到先node -v确认 Node 装了再npx -v确认 npx 可用。Windows 上如果报command not found把command改成npx.cmd。标准 MCP 配置格式也支持直接贴 JSONstore.for_store().add_service({ mcpServers: { mcpstore-wiki: { url: https://mcpstore.wiki/mcp }, howtocook: { command: npx, args: [-y, howtocook-mcp] } } })这种格式的好处是你从别的 MCP 客户端比如 Claude Desktop、Cline导出的配置可以原样贴进来不用改字段。mcpServers下面每个 key 就是服务名wait_service时用这个名字。导出 Langchain 工具tools store.for_store().for_langchain().list_tools() print(f工具数量: {len(tools)}) for t in tools: print(t.name, |, t.description[:60])list_tools()返回的是 Langchain 的StructuredTool列表可以直接传给create_tool_calling_agent。如果你同时有自己用tool定义的工具直接列表相加from langchain_core.tools import tool tool def get_time() - str: 返回当前时间格式 YYYY-MM-DD HH:MM:SS from datetime import datetime return datetime.now().strftime(%Y-%m-%d %H:%M:%S) all_tools tools [get_time]这里有个细节MCP 导出的工具和tool定义的工具在 Agent 眼里是同一类对象可以混用。但要注意名字冲突如果 MCP 里有个工具叫get_time你又定义了一个Agent 可能选错。导出后先打印一遍名字确认没有重复。4. 验证请求一次端到端调用与成功结果配置写完跑一次完整调用。代码结构如下from langchain.agents import create_tool_calling_agent, AgentExecutor from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from mcpstore import MCPStore store MCPStore.setup_store() store.for_store().add_service({ name: mcpstore-wiki, url: https://mcpstore.wiki/mcp, transport: streamable-https, }) store.for_store().wait_service(mcpstore-wiki, timeout30) tools store.for_store().for_langchain().list_tools() print(可用工具:, [t.name for t in tools]) llm ChatOpenAI( temperature0, modeldeepseek-chat, openai_api_keysk-你的key, openai_api_basehttps://taotoken.net/api/v1, ) prompt ChatPromptTemplate.from_messages([ (system, 你是一个助手需要调用工具时请调用不要编造结果。), (human, {input}), (placeholder, {agent_scratchpad}), ]) agent create_tool_calling_agent(llm, tools, prompt) executor AgentExecutor(agentagent, toolstools, verboseTrue) resp executor.invoke({input: 帮我查一下 mcpstore 是什么}) print(最终输出:, resp[output])跑起来后verboseTrue会打印 Agent 的思考过程。成功的标志是日志里出现Invoking: 工具名 with {...}然后Tool output有内容最后Final Answer是基于工具结果生成的。如果日志里只有Final Answer没有Invoking说明模型没选工具问题在工具描述或 prompt。验证模型入口是否通单独跑一段from langchain_openai import ChatOpenAI llm ChatOpenAI(modeldeepseek-chat, openai_api_keysk-你的key, openai_api_basehttps://taotoken.net/api/v1) print(llm.invoke(说一句话).content)这段能出文字说明 key 和 base 没问题。如果报 401去 API Keys 页面确认 key 没删、没写错如果报 404检查 base 是不是少了/v1。验证 MCP 工具是否真的可调用可以绕过 Agent 直接调tool tools[0] result tool.invoke({query: test}) print(result)参数名要看工具的args_schema打印出来print(tools[0].args_schema.schema())这一步能帮你确认工具到底要什么参数避免 Agent 传错。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth排障这块按报错原文对照别凭感觉改。401 Unauthorized。两种可能key 错或者 base 错。先确认openai_api_key是sk-开头且没多余空格再确认openai_api_base是https://taotoken.net/api/v1。如果 key 是从别处复制的注意有没有换行符。用print(repr(api_key))看一眼。local proxy failed / connection refused。这是 MCP 本地服务没起来。先手动跑一遍 commandnpx -y howtocook-mcp如果手动跑也报错是服务本身的问题跟 Langchain 无关。如果手动能跑但代码里不行检查working_dir和env。有些 MCP Server 依赖当前目录下的配置文件working_dir不设就会找不到。Error reading choices / reading choices。这是模型返回体里没有choices字段通常是 base 路径不对请求打到了非 OpenAI 兼容的端点。确认 base 带/v1且模型名在模型对话页面能查到。如果返回的是 HTML说明打到了网页而不是 API。OAuth / unauthorized_client。远程 MCP 服务需要鉴权时会出现。检查服务注册时有没有带 token 或 header。有些服务要求Authorization: Bearer xxx在add_service里加store.for_store().add_service({ name: remote_svc, url: https://example.com/mcp, headers: {Authorization: Bearer your_token}, })工具列表为空。wait_service过了但list_tools()返回空先确认服务名和wait_service里的名字一致。再确认服务真的暴露了 tools用store.for_store().list_services()看状态。如果状态是running但工具为空可能是服务端 tools 列表需要额外初始化看服务文档。Agent 不调用工具。工具在列表里但模型不选两个方向一是 description 太模糊二是 prompt 没引导。把 system prompt 改成「必须调用工具获取事实不要凭记忆回答」再试。如果还不行把工具 description 打印出来看是不是空的。6. 语义一致 CTA把这条链路固化成可复用配置跑通一次之后建议把配置固化成文件别每次改代码。MCP 服务列表可以放一个 JSON{ mcpServers: { mcpstore-wiki: { url: https://mcpstore.wiki/mcp, transport: streamable-https }, howtocook: { command: npx, args: [-y, howtocook-mcp] } } }代码里读这个文件注册import json with open(mcp_servers.json) as f: cfg json.load(f) store.for_store().add_service(cfg) for name in cfg[mcpServers]: store.for_store().wait_service(name, timeout60)模型入口这块key 和 base 放环境变量别硬编码export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api/v1import os llm ChatOpenAI( modeldeepseek-chat, openai_api_keyos.environ[TAOTOKEN_API_KEY], openai_api_baseos.environ[TAOTOKEN_BASE_URL], )这样换模型、换 key 都不用动代码。如果你要长期跑 Agent 任务比如批量处理、定时调度可以看 Coding Plan它更适合持续性的编码和 Agent 场景。模型验证和对话调试用模型对话页面key 管理在 API Keys接入细节看接入文档。MCP 服务本身的文档在 doc 页面遇到工具描述问题先去那查。最后留一个实用技巧每次改完 MCP 配置先单独跑list_tools()打印工具名和 description确认无误再跑 Agent。这一步花 10 秒能省掉后面半小时的「为什么模型不调工具」排查。工具描述是 Agent 的眼睛眼睛看不清后面全白搭。
返回列表