☰
在LangGraph中使用mcp服务:TaoToken统一Key接入与config.toml配置骨架
2026/9/26 14:08:35 网站建设 项目流程

1. LangGraph 接 MCP 服务,为什么 Key 管理会先崩

LangGraph 做多 Agent 工作流时,MCP 服务是绕不开的一环。它能把外部工具、数据源、本地脚本统一成模型可调用的 tool 列表,让ToolNode直接消费。但真正落地时,最先出问题的往往不是图怎么连,而是 Key 怎么管。

一个典型场景:你的 LangGraph 工作流里同时挂了三个 MCP 服务——一个查天气的远程服务、一个本地菜谱服务、一个内部知识库服务。每个服务背后可能对应不同的模型供应商,DeepSeek、通义、Claude 各一套 Key。如果每个服务单独配 Key,代码里就会散落一堆openai_api_key、api_key、token字段,换环境时逐个改,漏一个就 401。

TaoToken 在这里的角色是统一入口。它把多家模型的调用收敛到一个 API 地址和一把 Key 上,LangGraph 侧只需要认一个base_url和一个api_key。MCP 服务本身不关心你用的是哪家模型,它只负责暴露工具;模型调用统一走 TaoToken,Key 管理就从「N 个服务 N 套 Key」变成「一个 config.toml 管全部」。

这篇面向的是已经在写 LangGraph、准备把 MCP 服务接进工作流的开发者。目标很具体:给出一份可复制的config.toml配置骨架,用 TaoToken 统一 Key 接入,再跑一次 MCP 服务连通性验证,让整条调用链一次配置跑通。

适合谁:手上有 LangGraph 项目、正在被多服务 Key 困扰、希望配置和代码分离的人。如果你还没开始写 LangGraph,建议先把StateGraph和ToolNode的基本用法跑一遍再回来。

2. TaoToken 前置:拿 Key、认地址、定模型

在写 config.toml 之前,先把三件事定下来:API Key、API 地址、默认模型名。这三样是后面所有配置的锚点。

TaoToken 的 API 地址是https://taotoken.net/api,注意这个地址不带任何查询参数,直接作为 OpenAI 兼容的base_url使用。Key 在控制台的 API Keys 页面创建,创建后只显示一次,复制到安全的地方。

模型名这块要留意:TaoToken 走的是 OpenAI 兼容协议,所以 LangGraph 里用ChatOpenAI就能接,model字段填你实际要用的模型标识。不同模型在工具调用能力上有差异,LangGraph 的bind_tools依赖模型返回结构化的tool_calls,选模型时优先选工具调用支持稳定的。

提示:Key 不要硬编码进 Python 文件。这篇的骨架会把 Key 放进 config.toml,代码只读配置。这样换 Key 不用改代码,也不会误提交到仓库。

如果你还没创建 Key,可以先去控制台建一个,顺手把模型对话页面打开,确认 Key 能正常调通再往下走。这一步花两分钟,能省掉后面排查 401 的时间。

3. config.toml 配置骨架:一份文件管住 Key 和 MCP 服务

下面这份config.toml是整篇的核心。它分三块:模型接入、MCP 服务注册、运行时参数。你可以直接复制,把占位符换成自己的值。

# config.toml # LangGraph + MCP 服务统一配置骨架 [llm] # TaoToken 统一入口,OpenAI 兼容协议 base_url = "https://taotoken.net/api" api_key = "sk-your-taotoken-key" model = "your-model-name" temperature = 0 [mcp.servers.weather] # 远程 MCP 服务示例 url = "https://mcpstore.wiki/mcp" transport = "streamable-https" timeout = 30 [mcp.servers.howtocook] # 本地 MCP 服务示例,通过 npx 启动 command = "npx" args = ["-y", "howtocook-mcp"] timeout = 60 [runtime] # 服务等待超时,本地服务启动慢可以调大 wait_timeout = 60 # 是否在启动时打印服务状态 verbose = true

这份骨架的设计思路是「配置归配置,代码归代码」。[llm]段只认 TaoToken 的地址和 Key,MCP 服务段只描述服务怎么连,两者解耦。你新增一个 MCP 服务,只加一个[mcp.servers.xxx]段,不用动 Python。

读取配置用标准库tomllib(Python 3.11+)或tomli:

import tomllib with open("config.toml", "rb") as f: config = tomllib.load(f) llm_cfg = config["llm"] mcp_cfg = config["mcp"]["servers"]

拿到配置后,模型侧这样初始化:

from langchain_openai import ChatOpenAI llm = ChatOpenAI( temperature=llm_cfg["temperature"], model=llm_cfg["model"], openai_api_key=llm_cfg["api_key"], openai_api_base=llm_cfg["base_url"], )

注意openai_api_base填的是https://taotoken.net/api,不要在后面拼/v1或别的路径,OpenAI 兼容客户端会自己处理。这一步配错,最常见的表现是 404 而不是 401,排查时先看地址。

MCP 服务侧,用 MCPStore 把 config.toml 里的服务注册进去:

from mcpstore import MCPStore store = MCPStore.setup_store() for name, svc in mcp_cfg.items(): if "url" in svc: store.for_store().add_service({ "name": name, "url": svc["url"], "transport": svc.get("transport", "streamable-https"), }) else: store.for_store().add_service({ "name": name, "command": svc["command"], "args": svc["args"], }) store.for_store().wait_service(name, timeout=svc.get("timeout", 30))

这段代码把「远程 URL 服务」和「本地命令服务」两种形态统一处理。远程服务走url,本地服务走command + args,和主流 MCP 客户端的 json 配置格式一致,迁移成本低。

4. 验证请求:一次跑通 LangGraph 调用链

配置写完,先别急着搭复杂的图。用最小可运行例子验证 MCP 服务是否真的连通、工具是否真的能被模型调用。

先验证工具列表能拿到:

tools = store.for_store().for_langgraph().list_tools() print(f"loaded tools: {len(tools)}") for t in tools: print("-", t.name)

如果这里len(tools)是 0,说明服务注册了但工具没拉下来,先查服务状态,别往下走。

工具列表正常后,搭一个最小的 LangGraph 图:

from typing import Annotated, TypedDict from langchain_core.messages import HumanMessage from langgraph.graph import StateGraph, END from langgraph.prebuilt import ToolNode from langgraph.graph.message import add_messages model_with_tools = llm.bind_tools(tools) tool_node = ToolNode(tools) class AgentState(TypedDict): messages: Annotated[list, add_messages] def call_model(state: AgentState): response = model_with_tools.invoke(state["messages"]) return {"messages": [response]} def should_continue(state: AgentState): last = state["messages"][-1] if hasattr(last, "tool_calls") and last.tool_calls: return "tools" return END workflow = StateGraph(AgentState) workflow.add_node("agent", call_model) workflow.add_node("tools", tool_node) workflow.set_entry_point("agent") workflow.add_conditional_edges("agent", should_continue, {"tools": "tools", END: END}) workflow.add_edge("tools", "agent") app = workflow.compile()

跑一次:

query = "帮我查一下北京今天的天气" result = app.invoke({"messages": [HumanMessage(content=query)]}) for msg in result["messages"]: if hasattr(msg, "tool_calls") and msg.tool_calls: print("tool_calls:", [tc["name"] for tc in msg.tool_calls]) if hasattr(msg, "content") and msg.content: print("content:", msg.content)

成功的标志有两个:一是输出里出现tool_calls,说明模型正确识别了 MCP 工具;二是最终content里包含工具返回的数据,说明整条链路——模型调用走 TaoToken、工具调用走 MCP 服务——都通了。

实测下来,最容易卡住的是模型没返回tool_calls。这通常不是 MCP 的问题,而是模型本身工具调用能力弱,或者bind_tools传进去的 schema 有问题。先打印tools[0]看结构,再换一个工具调用稳定的模型试。

5. 本篇常见错排查

报错一:401 Unauthorized。先查 config.toml 里的api_key有没有多余空格,再确认 Key 是否已过期。TaoToken 的 Key 在控制台可以重新生成,生成后记得同步更新配置文件。如果代码里还残留旧的硬编码 Key,会覆盖配置,检查一下。

报错二:404 Not Found。九成是base_url写错了。正确值是https://taotoken.net/api,不要加/v1,不要加尾部斜杠。有些教程会让你拼/v1/chat/completions,那是直接发 HTTP 请求的写法,用ChatOpenAI时不需要。

报错三:MCP 服务 wait_service 超时。本地服务通过npx启动时,首次运行要下载包,60 秒可能不够。把[mcp.servers.xxx]里的timeout调到 120,或者先在终端手动跑一次npx -y howtocook-mcp把包缓存下来。远程服务超时通常是网络问题,确认 URL 可访问。

报错四:tools 列表为空。服务注册成功但工具拉不下来,常见原因是transport字段和服务实际协议不匹配。远程服务如果用的是 SSE,transport要写sse;如果是 streamable-https,就写streamable-https。不确定时先不写transport,让客户端自动推断。

报错五:模型返回了 tool_calls 但 ToolNode 执行报错。这通常是工具参数 schema 和模型生成的参数对不上。打印msg.tool_calls看模型传了什么,再对比tools里对应工具的args_schema。MCP 服务返回的 schema 如果嵌套层级深,模型容易填错,可以在工具描述里补一句参数说明。

报错六:换环境后全部 401。说明 Key 没跟着配置走。检查.gitignore有没有把config.toml排除,以及 CI/CD 里是否通过环境变量注入了 Key。推荐做法是 config.toml 里写占位符,运行时用环境变量覆盖:

import os llm_cfg["api_key"] = os.environ.get("TAOTOKEN_API_KEY", llm_cfg["api_key"])

6. 配置跑通之后,往哪走

到这一步,你应该已经有一份能跑的 config.toml、一个能列出 MCP 工具的 store、一张能调用工具的 LangGraph 图。整条链路的关键点就三个:TaoToken 统一 Key 收敛了模型调用,config.toml 把配置和代码分离,MCPStore 把服务生命周期管住。

接下来如果要做长期编码或 Agent 项目,建议把 Key 和模型配置进一步收敛到 Coding Plan,按项目维度管理调用额度,避免多个项目共用一把 Key 时互相干扰。如果只是想验证某个模型在工具调用上的表现,可以直接在模型对话页面切换模型试,不用改代码。

接入文档里有完整的参数说明和更多 MCP 服务注册示例,遇到 config.toml 字段不确定的地方可以对照查。API Keys 页面则是 Key 出问题时第一个要去的地方——重新生成、复制、更新配置,三步解决大部分 401。

最后留一个实用习惯:每次新增 MCP 服务后,先单独跑list_tools()确认工具能拉下来,再往图里加。这个动作花十秒,能避免把服务注册问题和图编排问题混在一起排查。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询