资讯详情

资讯详情

LangGraph 接入 MCP:把工具调用链路改到 TaoToken 的配置与验证

1. 为什么要把 LangGraph 的 MCP 工具链路统一到 TaoToken如果你已经在本地跑通了 LangGraph MCP大概率会遇到一个很现实的问题模型请求散落在好几个地方。ChatOpenAI里写一个base_urlChatTongyi里写一个api_keyMCP server 的env里又塞一个第三方 key最后排查一次工具调用失败得翻四五个文件才能确认请求到底从哪个通道发出去的。LangGraph 的多智能体工作流本身是「编排层」它不关心模型请求走哪条路只关心节点之间的状态流转。MCP 是「工具层」负责把外部能力以统一协议暴露给 Agent。真正决定请求发往哪里的是模型客户端初始化时那个base_url和api_key。所以「把工具调用链路改到 TaoToken」这件事本质上是把 LangGraph 里所有模型客户端的 endpoint 收敛到同一个通道同时让 MCP server 侧的环境变量也指向同一套凭证。TaoToken 在这里扮演的角色是统一的模型请求入口。它提供 OpenAI 兼容的/v1/chat/completions接口意味着你原来用ChatOpenAI、langchain_openai写的代码几乎不用改只需要替换base_url和api_key。对于 LangGraph 这种重度依赖 LangChain 生态的框架来说兼容性就是最大的省事。适合谁看这篇已经在本地用langchain-mcp-adapters跑通过至少一个 MCP server、能成功调用get_tools()并让 Agent 执行工具、但模型请求还指向各家厂商分散 endpoint 的开发者。如果你还没跑通 MCP 基础链路建议先把MultiServerMCPClient和create_react_agent的最小例子跑起来再回来看统一通道的配置。我试过把三个不同厂商的模型客户端混在一个 LangGraph 图里结果一次工具调用超时日志里三个 endpoint 交替出现定位花了半小时。从那以后我就把所有模型请求收敛到一个通道排查成本直接降下来。下面按「前置准备 → 可复制配置 → 验证请求 → 排错」的顺序展开每一步都给完整代码。2. TaoToken 前置准备Key、Base URL 与 MCP 环境变量在改 LangGraph 代码之前先把凭证和地址准备好。TaoToken 的 API 地址是https://taotoken.net/api注意这个地址不带任何查询参数直接作为 OpenAI 兼容的base_url使用。很多人在这一步会多写一个/v1结果请求变成/v1/v1/chat/completions直接 404后面排错章节会专门讲这个。Key 的获取走控制台登录后在 API Keys 页面创建。创建时建议按用途命名比如langgraph-mcp-dev这样后面在 MCP server 的env里看到这个 key 就知道是哪个项目在用。Key 只在创建时完整显示一次复制后存到本地.env文件不要硬编码进代码提交到仓库。MCP server 侧的环境变量写法是这次改造的关键点之一。MCP 的 stdio 方式通过env字段把环境变量传给子进程SSE 方式则通过 URL 参数或请求头传递。如果你用的是自己手写的 FastMCP server模型请求发生在 server 内部的 sampling 回调里这时候 server 需要知道往哪个 endpoint 发请求。所以要在 server 启动时注入TAOTOKEN_API_KEY和TAOTOKEN_BASE_URL两个环境变量。一个容易忽略的点LangGraph 主进程和 MCP server 子进程是两套环境。主进程里ChatOpenAI用的 key和 MCP server 里 sampling 用的 key可以是同一个但必须都显式配置。只配了主进程工具调用时 server 侧 sampling 会因为拿不到 key 而失败报错信息通常是401或missing api key但堆栈会指向 MCP 通信层容易误判成协议问题。建议在项目根目录建一个.envTAOTOKEN_API_KEYsk-你的key TAOTOKEN_BASE_URLhttps://taotoken.net/api然后在 LangGraph 主进程和 MCP server 启动脚本里都用python-dotenv或os.environ读取。这样只有一处凭证来源改 key 的时候不用满项目搜。3. 可复制配置LangGraph 客户端与 MCP server 的 endpoint 写法这一节给完整可复制的配置片段。先看 LangGraph 主进程里的模型客户端。原来你可能写的是from langchain_openai import ChatOpenAI llm ChatOpenAI( modelgpt-4o-mini, base_urlhttps://api.openai.com/v1, api_keysk-xxx, )改成 TaoToken 通道后import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI load_dotenv() llm ChatOpenAI( modelgpt-4o-mini, base_urlos.environ[TAOTOKEN_BASE_URL], api_keyos.environ[TAOTOKEN_API_KEY], streamingTrue, )注意base_url直接用https://taotoken.net/api不要手动拼/v1。LangChain 的 OpenAI 客户端会自动补/chat/completions如果你在base_url里已经带了/v1最终路径会重复。Model ID 按你实际要用的填TaoToken 支持多个模型具体列表在模型对话页面能看到。接下来是 MCP server 侧的配置。以 stdio 方式为例MultiServerMCPClient的配置里env字段要注入 TaoToken 的凭证from langchain_mcp_adapters.client import MultiServerMCPClient client MultiServerMCPClient( { my-local-mcp: { command: python, args: [mcp_server.py], env: { TAOTOKEN_API_KEY: os.environ[TAOTOKEN_API_KEY], TAOTOKEN_BASE_URL: os.environ[TAOTOKEN_BASE_URL], }, transport: stdio, } } )如果你用的是 SSE 方式连接远程 MCP server配置改成client MultiServerMCPClient( { my-remote-mcp: { url: http://127.0.0.1:8000/sse, transport: sse, } } )SSE 方式下模型请求发生在 server 内部所以 server 启动时必须自己读到TAOTOKEN_API_KEY。手写 FastMCP server 时在 sampling 回调里构造模型客户端import os from mcp.server.fastmcp import FastMCP from langchain_openai import ChatOpenAI mcp FastMCP(taotoken-mcp-demo) mcp.tool() def add(a: int, b: int) - int: Add two numbers together. return a b if __name__ __main__: mcp.run(transportsse)如果 server 内部需要调用模型做 sampling就在回调里用os.environ[TAOTOKEN_BASE_URL]和os.environ[TAOTOKEN_API_KEY]初始化ChatOpenAI。这样主进程和 server 进程用的是同一套凭证请求都从 TaoToken 通道出去。一个完整的settings风格配置片段方便你对照检查{ model_client: { base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, model: gpt-4o-mini }, mcp_servers: { my-local-mcp: { transport: stdio, command: python, args: [mcp_server.py], env: { TAOTOKEN_API_KEY: ${TAOTOKEN_API_KEY}, TAOTOKEN_BASE_URL: https://taotoken.net/api } } } }三件套记牢Base URL 是https://taotoken.net/apiKey 从环境变量读Model ID 按实际填。任何一处缺失工具调用链路都会断。4. 验证请求一次完整的 MCP 工具调用链路确认配置改完不能只看代码要跑一次完整链路确认请求确实从 TaoToken 发出。验证思路是让 Agent 调用一个 MCP 工具同时在 TaoToken 控制台的用量日志里看到这次请求。先写一个最小验证脚本import asyncio import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_mcp_adapters.client import MultiServerMCPClient from langgraph.prebuilt import create_react_agent load_dotenv() async def main(): llm ChatOpenAI( modelgpt-4o-mini, base_urlos.environ[TAOTOKEN_BASE_URL], api_keyos.environ[TAOTOKEN_API_KEY], ) client MultiServerMCPClient( { demo-mcp: { command: python, args: [mcp_server.py], env: { TAOTOKEN_API_KEY: os.environ[TAOTOKEN_API_KEY], TAOTOKEN_BASE_URL: os.environ[TAOTOKEN_BASE_URL], }, transport: stdio, } } ) tools await client.get_tools() print(已加载工具:, [t.name for t in tools]) agent create_react_agent(modelllm, toolstools) response await agent.ainvoke( {messages: [{role: user, content: 帮我算一下 3 加 5 等于几}]} ) print(最终回复:, response[messages][-1].content) if __name__ __main__: asyncio.run(main())运行后你会看到两段输出第一段是已加载工具确认 MCP server 成功暴露了add工具第二段是最终回复确认 Agent 调用了工具并拿到结果。如果已加载工具是空列表说明 MCP server 没启动成功跟 TaoToken 无关先查 server 脚本。确认工具加载成功后打开 TaoToken 控制台的用量日志页面刷新一下应该能看到刚才这次请求的记录包含 model、token 数和时间戳。这一步是「确认请求确实经由统一通道发出」的关键证据。如果日志里没有记录但 Agent 又返回了结果说明请求走了别的 endpoint回去检查base_url是不是被某个环境变量覆盖了。再补一个更严格的验证在 MCP server 的add工具里加一行打印确认工具真的被执行了mcp.tool() def add(a: int, b: int) - int: Add two numbers together. print(f[MCP SERVER] add called with {a}, {b}) return a b运行验证脚本时终端会先打印[MCP SERVER] add called with 3, 5再打印最终回复。这条日志证明工具调用链路是通的LangGraph 主进程 → MCP 协议 → server 工具执行 → 结果回传 → 模型生成最终回复。整条链路上模型请求都从 TaoToken 走。如果你用的是 SSE 方式验证方法一样只是MultiServerMCPClient配置换成url字段server 侧用mcp.run(transportsse)启动然后访问http://127.0.0.1:8000/sse确认服务在监听。5. 本篇常见错排查401、local proxy failed 与 reading choices改 endpoint 的过程中报错基本集中在几个固定位置。下面按真实报错逐个拆。401 Unauthorized。最常见的原因是 key 没读到。检查.env文件是否在项目根目录、load_dotenv()是否在读取环境变量之前调用、MCP server 的env字段是否真的把 key 传进去了。stdio 方式下env字段是显式传递的不会自动继承主进程环境所以必须手动写。如果主进程能跑通但工具调用报 401八成是 server 侧env漏了TAOTOKEN_API_KEY。local proxy failed / connection refused。这个报错通常出现在base_url写错或网络不通时。先确认base_url是https://taotoken.net/api没有多余路径。然后用 curl 直接测一下curl -X POST https://taotoken.net/api/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:gpt-4o-mini,messages:[{role:user,content:hi}]}如果 curl 能通但 Python 报连接失败检查是不是有全局代理环境变量干扰比如HTTP_PROXY、HTTPS_PROXY被设成了本地某个端口。清掉这些变量再跑。reading choices 相关报错。典型信息是KeyError: choices或list index out of range说明返回的 JSON 结构里没有choices字段。这通常是因为base_url多写了/v1请求打到了错误路径返回的是 404 页面而不是模型响应。把base_url改成https://taotoken.net/api即可。另一个可能是 Model ID 写错服务端返回了错误对象解析时找不到choices。对照模型对话页面确认 Model ID 拼写。OAuth 相关报错。如果你在 MCP 配置里用了需要 OAuth 的远程 server而凭证又指向 TaoToken会出现 OAuth 流程和 API Key 混用的情况。TaoToken 走的是 API Key 认证不需要 OAuth。把 MCP 配置里的 OAuth 字段去掉统一用env里的TAOTOKEN_API_KEY。工具加载为空。get_tools()返回空列表先看 MCP server 进程有没有正常启动。stdio 方式下command和args要能独立在终端跑通。比如python mcp_server.py手动执行看有没有报错。server 启动失败时MultiServerMCPClient不会抛异常只是拿不到工具容易误判成 TaoToken 问题。请求发出但控制台无记录。Agent 返回了结果但 TaoToken 用量日志里没有。检查是不是有多个模型客户端实例其中一个还指向旧 endpoint。LangGraph 图里如果有多个节点各自初始化了ChatOpenAI要确保每一处都改了base_url。用grep -r base_url .搜一遍项目把所有旧地址替换掉。排查顺序建议先 curl 测通道 → 再手动跑 MCP server → 再跑最小 Agent 脚本 → 最后看控制台日志。每一步确认通过再往下走比一次性跑完整图再猜哪里出错快得多。6. 把统一通道固化到你的 LangGraph 工作流配置改完、验证跑通之后建议把凭证读取和客户端初始化抽成一个公共模块比如llm_factory.py所有节点都从这里拿模型实例。这样以后换通道只改一个文件不用满项目搜base_url。import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI load_dotenv() def get_llm(model: str gpt-4o-mini) - ChatOpenAI: return ChatOpenAI( modelmodel, base_urlos.environ[TAOTOKEN_BASE_URL], api_keyos.environ[TAOTOKEN_API_KEY], streamingTrue, )MCP server 的env也从这个模块的同一套环境变量读保证主进程和子进程凭证一致。长期跑编码类 Agent 的话可以把这套配置和 Coding Plan 结合让多智能体工作流的模型请求都走统一通道用量和排查都在一个地方看。最后留一个实用习惯每次改完 endpoint先跑第 4 节那个最小验证脚本确认工具加载和最终回复都正常再去跑完整的 LangGraph 图。最小脚本 10 秒能跑完完整图可能要几分钟先用小成本确认通道通再上大流程。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →