ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

LangChain+MCP(模型上下文协议)实现案例:用 TaoToken 统一 Key 打通 Agent 工具链

LangChain+MCP(模型上下文协议)实现案例:用 TaoToken 统一 Key 打通 Agent 工具链 1. 从一次本地多工具联调说起LangChain Agent 接 MCP 到底卡在哪如果你正在用 LangChain 搭 Agent又想让它调用本地文件、数据库、内部接口这类外部能力大概率会碰到同一个问题工具怎么接、Key 怎么管、多个工具怎么统一调度。MCP模型上下文协议就是为解决这件事而生的它把「模型能调用什么工具」抽象成一套标准协议LangChain 通过langchain-mcp-adapters就能把 MCP Server 暴露的工具直接变成 Agent 的 tools。但真正动手时链路会变得很碎math_server 用 stdio 传输、weather_server 用 SSE 传输、模型侧还要配 base_url 和 API Key如果每个模型、每个工具都单独配一套凭证本地联调很快就会乱成一锅粥。这篇就聚焦这个场景用 TaoToken 统一 Key 把模型调用这一层收敛掉再给出config.toml与settings.json骨架、Key 的填入位置以及一次 Agent 调用工具的完整验证动作和预期返回让你能照着复现一条可运行的 MCP 接入流程。适合谁看已经会写基础 LangChain Agent、想接 MCP 工具但被配置链路劝退的同学以及本地同时跑多个 MCP Server、想统一管理模型凭证的开发者。下面所有步骤都在本地环境完成不涉及任何网络层特殊配置。2. TaoToken 前置统一 Key 在 MCP 链路里的位置先说清楚 TaoToken 在这条链路里扮演什么角色。MCP 负责「工具侧」的协议标准化TaoToken 负责「模型侧」的凭证统一。你原本可能要在.env里分别写DEEPSEEK_API_KEY、ZHIPUAI_API_KEY、OPENAI_API_KEY每换一个模型就改一次配置用 TaoToken 之后模型调用统一走一个 base_url 和一个 KeyAgent 侧只需要认这一套凭证。具体来说LangChain 里ChatOpenAI兼容 OpenAI 协议所以只要把openai_api_base指向 TaoToken 的 API 地址openai_api_key填 TaoToken 生成的 Key模型名按需切换即可。这样 MCP 工具链不变模型层却可以随时换。你需要先拿到 Key。进入控制台创建 API Key地址是https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_console创建后复制那串sk-开头的 Key后面填进.env或settings.json。API 基础地址统一用https://taotoken.net/api注意这个地址不加任何 UTM 参数直接作为openai_api_base使用。如果你对模型对话能力想先单独验证可以走模型对话入口https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_chat长期做编码或 Agent 联调、调用量比较大的可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_plan接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_docAPI Keys 管理页在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_keys3. 可复制配置config.toml 与 settings.json 骨架这一节给出两份配置文件骨架。config.toml用来描述 MCP Server 的启动方式settings.json用来放模型凭证和运行参数。两者配合Agent 启动时读配置、连 Server、拿 tools。先看config.toml它把两个 MCP Server 的传输方式和启动命令写清楚# config.toml [llm] provider openai-compatible base_url https://taotoken.net/api model glm-4-flashx api_key_env TAOTOKEN_API_KEY [mcp_servers.math] transport stdio command python args [./math_server.py] [mcp_servers.weather] transport sse url http://localhost:8000/sse [agent] max_iterations 8 verbose true这里api_key_env指向环境变量名而不是把 Key 明文写进 toml避免误提交。模型名glm-4-flashx只是示例你可以按 TaoToken 支持的模型列表替换。再看settings.json它承担运行期参数和 Key 的注入{ llm: { base_url: https://taotoken.net/api, api_key: ${TAOTOKEN_API_KEY}, model: glm-4-flashx, temperature: 0.2 }, mcp: { math: { command: python, args: [./math_server.py], transport: stdio }, weather: { url: http://localhost:8000/sse, transport: sse } }, runtime: { timeout_seconds: 60, retry: 2 } }Key 的填入位置就在settings.json的llm.api_key用${TAOTOKEN_API_KEY}占位实际值放.env# .env TAOTOKEN_API_KEYsk-你的TaoToken密钥这样模型侧只认一个 KeyMCP 侧只认配置文件里的 Server 列表职责清晰。依赖安装pip install langchain-mcp-adapters langgraph langchain-openai python-dotenvPython 版本要求 3.10 及以上。4. 验证请求一次 Agent 调用工具的完整动作与预期返回配置就绪后写两个 MCP Server。math_server.py用 stdio 传输# math_server.py from mcp.server.fastmcp import FastMCP mcp FastMCP(Math) mcp.tool() def add(a: int, b: int) - int: 对两个整数相加 return a b mcp.tool() def multiple(a: int, b: int) - int: 对两个整数相乘 return a * b if __name__ __main__: mcp.run(transportstdio)weather_server.py用 SSE 传输默认监听 8000 端口# weather_server.py from mcp.server.fastmcp import FastMCP mcp FastMCP(Weather) mcp.tool() async def get_weather(location: str) - str: 获取位置的天气。 return f{location}当前天气晴朗温度 25°C if __name__ __main__: mcp.run(transportsse)开两个终端分别启动python math_server.py python weather_server.pystdio 的 Server 启动后没有输出是正常的SSE 的会通过 uvicorn 起一个 HTTP 服务。接着写客户端把模型指向 TaoToken# client.py import asyncio import os from dotenv import load_dotenv from langchain_mcp_adapters.client import MultiServerMCPClient from langgraph.prebuilt import create_react_agent from langchain_openai import ChatOpenAI load_dotenv() model ChatOpenAI( openai_api_basehttps://taotoken.net/api, openai_api_keyos.getenv(TAOTOKEN_API_KEY), model_nameglm-4-flashx, ) async def run_client(): async with MultiServerMCPClient( { math: { command: python, args: [./math_server.py], transport: stdio, }, weather: { url: http://localhost:8000/sse, transport: sse, }, } ) as client: agent create_react_agent(model, client.get_tools()) math_response await agent.ainvoke( {messages: 请问(3 5) x 12多少?} ) print(Math Response:, math_response[messages][-1].content) weather_response await agent.ainvoke( {messages: 请问北京今天天气怎么样?} ) print(Weather Response:, weather_response[messages][-1].content) if __name__ __main__: asyncio.run(run_client())运行python client.py预期返回类似Math Response: (3 5) x 12 96 Weather Response: 北京当前天气晴朗温度 25°C看到这两行说明 Agent 已经通过 MCP 成功调用了两个 Server 的工具模型侧走的是 TaoToken 统一 Key。这一步是整个链路的关键验证点工具被真实触发、参数被正确传递、结果被模型整合成自然语言。5. 本篇常见错排查NotImplementedError 与配置踩坑第一个高频报错是NotImplementedError出现在实例化MultiServerMCPClient的过程中尤其在 Windows Python 3.12 环境下。根因是 asyncio 的 subprocess 在 Windows 默认事件循环下不支持而 stdio 传输依赖子进程。处理方式是在入口处显式设置事件循环策略import asyncio import sys if sys.platform win32: asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())把这段放在asyncio.run()之前。如果是在 FastAPI 里调用注意 FastAPI 自己管理事件循环需要在应用启动时设置策略而不是在路由函数里临时改。第二个坑是路径问题。args里的./math_server.py是相对当前工作目录的如果你从别的目录启动 client会找不到文件。稳妥做法是用绝对路径import os BASE_DIR os.path.dirname(os.path.abspath(__file__)) args: [os.path.join(BASE_DIR, math_server.py)]第三个坑是 SSE Server 没起来就去连报连接拒绝。确认weather_server.py已经在 8000 端口监听再跑 client。stdio 的 Server 不需要手动确认端口但它的进程必须能被 client 拉起。第四个坑是 Key 没读到。load_dotenv()要在读取os.getenv之前调用且.env文件要在当前工作目录。如果返回 401先检查TAOTOKEN_API_KEY是否为空再确认 base_url 是https://taotoken.net/api而不是别的路径。报错现象可能原因处理方式NotImplementedErrorWindows 事件循环不支持子进程设置 ProactorEventLoopPolicyFileNotFoundErrorServer 路径为相对路径改用绝对路径Connection refusedSSE Server 未启动先启动 weather_server401 UnauthorizedKey 未加载或错误检查 .env 与 base_url6. 把 Key 收敛之后MCP 联调才真正可维护走到这里你应该已经跑通了一条完整的链路两个 MCP Server 分别用 stdio 和 SSE 传输LangChain Agent 通过MultiServerMCPClient拿到 tools模型侧用 TaoToken 统一 Key 调用。整个过程里模型凭证只有一处工具配置只有一份换模型不用动 MCP 配置加工具不用动模型配置。如果你后面要把这套东西接到 FastAPI 里做接口建议把 model、MCPClient、Agent 的创建封装成单例或依赖注入不要在每次请求里重新实例化MultiServerMCPClient否则既慢又容易触发事件循环相关问题。长期做编码和 Agent 联调的话Coding Plan 会比按量调用更省心https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_plan_end需要新建或轮换 Key 时走 API Keys 页https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_keys_end接入细节和参数说明以官方文档为准https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_doc_end先把client.py跑出那两行预期返回再往 FastAPI 封装走顺序别反能省掉大半排障时间。
返回列表