1. 从一次“查天气”说起ChatDeepSeek 调用高德地图 MCP 到底在做什么很多人第一次听到“用自然语言查天气”脑子里浮现的是打开手机 App、输入城市、点查询。但如果你想让自己的程序具备这个能力尤其是让大模型自己决定“该调用哪个工具、传什么参数”那就绕不开 MCPModel Context Protocol这套机制。ChatDeepSeek 是 LangChain 生态里对接 DeepSeek 模型的封装它支持 tool_calls 返回而高德地图官方提供了 MCP Server把“查天气”“查 POI”“算路线”这些能力包装成标准工具。两者一结合你就能实现用户说一句“帮我看看杭州明天适不适合出门”模型自动识别需要调用高德天气工具传入城市和日期拿到结果后再用自然语言回复。这个链路里最容易被忽略、也最容易卡住的一环是 MCP endpoint 的配置。默认情况下MCP Server 通过 stdio 在本地拉起一个 Node 进程但如果你希望把请求统一走一个可管理的入口或者团队里多人共用一套工具服务就需要把 endpoint 指向一个稳定的地址。TaoToken 在这里扮演的角色是提供兼容 OpenAI 协议的统一接入层让你在 ChatDeepSeek 的api_base和 MCP 客户端的连接配置上都能有一个可复用的地址而不是每个项目各自散落一堆 key 和 URL。我试过把整套流程跑通从申请高德 Key、装 Node 环境到写一个能多轮对话的 Python 脚本中间踩过几个坑Node 版本太低导致 npx 执行失败、DeepSeek 官方 API 和某些云厂商版本对 tool_calls 支持不一致、MCP session 生命周期管理不当导致工具调用报错。下面我会把可复制的配置片段、验证步骤和排错方法都摊开讲你跟着做就能跑通一次真实的天气查询。适合谁看已经会用 Python 写点脚本、想给自己的 Agent 加上“真实世界工具调用”能力的开发者或者你正在评估 MCP 协议怎么落地想找一个最小可运行示例。不需要你之前接触过 MCP但需要你能看懂 async/await 和基本的命令行操作。2. 前置准备TaoToken 接入层与高德 MCP 环境搭建在写代码之前先把两件事搞定一个是模型侧的接入地址一个是工具侧的高德服务。TaoToken 的 API 地址是https://taotoken.net/api它兼容 OpenAI 的接口规范所以 ChatDeepSeek 里配置api_base时可以直接指向它。这样做的好处是你后续如果换模型或者加其他工具不用改一堆散落的 endpoint。API Key 可以在控制台生成地址是https://taotoken.net/api-keys生成后复制出来备用。高德地图 MCP Server 的申请入口在高德开放平台你需要创建一个应用并拿到AMAP_MAPS_API_KEY。这个 Key 是给 MCP Server 用的不是给模型用的两者不要混。高德官方提供的 MCP Server 包名是amap/amap-maps-mcp-server通过 npx 拉起。这里有个硬性要求Node 版本必须大于等于 18.20.4否则 npx 执行会报错。你可以用node -v检查如果低于这个版本去 Node 官网下载 LTS 版本覆盖安装。Python 侧需要装三个包mcp、langchain、langchain_deepseek。用 pip 一次性装pip install mcp langchain langchain_deepseek装完之后建议先单独验证一下 MCP Server 能不能正常启动。你可以直接在终端跑npx -y amap/amap-maps-mcp-server如果它没有立刻退出而是等待输入说明进程能起来。按 CtrlC 结束即可。这一步能帮你排除 Node 环境问题避免后面在 Python 里调试半天才发现是 npx 根本跑不起来。关于模型选择目前实测下来DeepSeek 官方 API 能正常返回tool_calls字段ChatDeepSeek 可以正确解析。但如果你用的是某些云厂商托管的 DeepSeek 版本可能会遇到不返回 tool_calls 的情况导致模型只会“说”要调用工具但实际没有结构化输出。所以建议优先用官方接口或者通过 TaoToken 这类兼容层接入保证 tool_calls 行为一致。TaoToken 的接入文档在https://taotoken.net/doc里面有关于 Base URL 和鉴权头的说明。如果你之前用的是 OpenAI SDK迁移过来基本只需要改base_url和api_key两个字段。对于 ChatDeepSeek配置方式类似llm ChatDeepSeek( api_basehttps://taotoken.net/api, api_key你的TaoToken Key, modeldeepseek-chat )注意api_base不要带末尾斜杠也不要加/v1之外的路径具体以文档为准。模型 ID 用deepseek-chat即可这是对话模型支持工具调用。环境变量方面建议把 Key 放到.env文件或者系统环境变量里不要硬编码在脚本中。尤其是高德的AMAP_MAPS_API_KEY一旦泄露可能被别人刷额度。你可以用os.environ.get()读取或者用 python-dotenv 加载。最后确认一下网络MCP Server 通过 stdio 本地通信不涉及外部端口所以不需要额外开防火墙。但 npx 第一次执行会从 npm 仓库下载包需要能正常访问 npm。如果你在公司内网可能需要配置 npm 镜像源。3. 可复制配置MCP endpoint 与 ChatDeepSeek 的完整对接片段这一节给出可以直接复制运行的配置代码。核心思路是MCP Server 的参数用StdioServerParameters描述模型用ChatDeepSeek初始化然后把工具列表绑定到模型上。为了让 endpoint 可管理我把模型侧的api_base指向 TaoToken工具侧仍然走本地 stdio但参数集中在一个字典里方便后续替换。先看 MCP 服务配置from mcp import StdioServerParameters server_params StdioServerParameters( commandnpx, args[-y, amap/amap-maps-mcp-server], env{ AMAP_MAPS_API_KEY: 你的高德Key } )这段配置里command是 npxargs里-y表示自动确认安装后面是包名。env传入高德 KeyMCP Server 启动时会读取这个环境变量。如果你想把 endpoint 改成远程地址MCP 协议也支持 SSE 或 HTTP 传输但高德官方目前主要提供 stdio 方式所以这里保持本地拉起。模型配置from langchain_deepseek import ChatDeepSeek llm ChatDeepSeek( api_basehttps://taotoken.net/api, api_key你的TaoToken Key, modeldeepseek-chat, temperature0 )temperature0是为了让工具调用更稳定减少模型“自由发挥”导致参数格式错误。如果你需要更活泼的回复可以调到 0.3 左右但工具调用场景建议低温度。接下来是绑定工具的函数。这里有个关键点MCP 的 session 不能跨多次调用复用因为 stdio 连接在async with退出后就关闭了。所以我的做法是第一次启动 MCP 获取工具列表并绑定到模型之后每次实际调用工具时重新开一个 session。这样虽然多了一次进程启动开销但避免了 session 状态混乱导致的报错。import asyncio from mcp import ClientSession from mcp.client.stdio import stdio_client async def bind_llm_with_tools(): async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools_list await session.list_tools() print(可用工具:, [t.name for t in tools_list.tools]) available_tools [ { type: function, function: { name: tool.name, description: tool.description, parameters: tool.inputSchema } } for tool in tools_list.tools ] return llm.bind_tools(available_tools)list_tools()返回的工具里高德天气工具通常叫maps_weather描述里会写明支持城市和日期参数。inputSchema是 JSON Schema 格式直接传给bind_tools即可。工具调用函数async def call_tools(tool_calls): async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() for tool in tool_calls: name tool[name] args tool[args] print(f调用工具 {name}参数: {args}) result await session.call_tool(name, argumentsargs) print(f工具返回: {result}) return result注意这里tool[args]是模型生成的参数字典直接传给call_tool。返回的result里包含 content 列表通常是文本形式的天气信息。主循环async def chat_loop(): llm_with_tools await bind_llm_with_tools() messages [ (system, 你是一个中文助手需要查天气时调用工具拿到结果后用自然语言回复。) ] while True: user_input input(你) if user_input.lower() in {exit, quit, bye}: print(再见) break messages.append((human, user_input)) response llm_with_tools.invoke(messages) print(模型回复:, response.content) messages.append((ai, response.content)) if response.tool_calls: result await call_tools(response.tool_calls) messages.append((tool, str(result))) if __name__ __main__: asyncio.run(chat_loop())这里我把工具返回结果追加到 messages 里这样模型下一轮能基于真实天气数据回复。如果你不追加模型会“忘记”工具结果继续瞎编。整个配置片段里TaoToken 的 Base URL 只出现在api_base一处高德 Key 只出现在env一处职责清晰。如果你要把这套代码放到服务器上跑记得把 Key 换成环境变量读取不要提交到 Git。4. 验证请求一次真实天气查询的完整过程与结果配置写好后跑起来看看。在终端执行python your_script.py你会先看到工具列表打印出来类似可用工具: [maps_weather, maps_poi_search, maps_direction_walking, ...]这说明 MCP Server 启动成功工具已经绑定到模型。然后进入对话循环输入你杭州明天天气怎么样模型会先返回一段 content可能是空的或者“我来查一下”同时response.tool_calls里会有结构化数据。我的实测输出里tool_calls 长这样[ { name: maps_weather, args: {city: 杭州, date: 2025-06-11}, id: call_xxx } ]注意date是模型根据“明天”推算出来的这依赖模型对当前日期的理解。如果你发现日期不对可以在 system prompt 里注入当前日期比如“今天是 2025-06-10”。然后call_tools会启动新的 MCP session调用maps_weather返回结果类似工具返回: content[TextContent(typetext, text杭州明天多云气温 22-28℃东南风 3 级适合出行。)]最后模型拿到这个结果生成自然语言回复模型回复: 杭州明天多云气温 22 到 28 摄氏度东南风 3 级挺适合出门的记得带件薄外套。到这里一次完整的“自然语言 → 工具调用 → 天气结果 → 自然语言回复”链路就跑通了。你可以继续追问“那后天呢”模型会再次调用工具传入新的日期。多轮对话下messages 里会累积历史模型能理解上下文。如果你想把 endpoint 换成 TaoToken 的模型对话入口做对比测试可以访问https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentchatdeepseek_amap_mcputm_campaignrewrite在网页里直接输入类似问题观察模型是否触发工具调用。不过网页版通常不暴露 tool_calls 细节更适合验证模型理解能力。验证过程中有几个观察点第一工具调用的参数是否正确尤其是城市名和日期格式第二MCP Server 返回的文本是否包含有效天气信息第三模型是否把工具结果正确融入回复而不是重复调用。如果模型反复调用同一个工具可能是 system prompt 没写清楚或者 temperature 太高。另外如果你用的是 TaoToken 的 Coding Plan 做长期开发可以把这套代码放到项目里通过https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentchatdeepseek_amap_mcputm_campaignrewrite了解配额和接入方式。对于需要频繁调用工具的 Agent 场景统一入口能省去不少管理成本。5. 常见报错排查401、local proxy failed、reading choices 与 OAuth跑这套流程最容易遇到的报错集中在几个地方。我按真实错误信息整理一下排查思路。401 Unauthorized通常出现在模型侧或高德侧。如果 ChatDeepSeek 初始化后调用报 401检查api_key是否填对TaoToken 的 Key 是否在有效期内。如果 MCP Server 启动时报 401检查AMAP_MAPS_API_KEY是否正确高德 Key 是否绑定了 MCP 服务权限。注意高德 Key 有 Web 服务、JS API 等不同类型MCP 需要的是 Web 服务类型的 Key。local proxy failed这个报错一般出现在 npx 下载包的时候说明网络无法访问 npm 仓库。解决办法是配置 npm 镜像源比如npm config set registry https://registry.npmmirror.com然后重新执行。如果你在公司内网可能需要联系运维开通 npm 访问权限。注意不要用任何非正规的网络工具合规环境下配置镜像源即可。reading choices 报错类似KeyError: choices或reading choices说明模型返回的 JSON 结构不符合预期。常见原因是api_base配置错误比如多加了/v1或者少了路径导致请求打到了错误的端点。检查 TaoToken 的 Base URL 是否为https://taotoken.net/api不要自己拼/chat/completionsSDK 会自动补全。另外如果模型不支持 tool_calls返回结构里没有choices[0].message.tool_calls也会在解析时报错。换用支持工具调用的模型即可。OAuth 相关报错如果你在 MCP 配置里用了需要 OAuth 的远程服务可能会遇到 token 过期或 scope 不足。高德 MCP 目前用 API Key 鉴权不涉及 OAuth所以这个报错一般出现在你混用了其他 MCP Server 时。检查server_params里是否误加了 OAuth 配置或者环境变量里有没有冲突的 token。工具调用返回空结果模型生成了 tool_calls但call_tool返回空。检查参数格式比如city是否传了中文date是否符合YYYY-MM-DD。高德天气工具对城市名支持中文但如果你传了拼音可能查不到。可以在call_tools里打印args确认。Node 版本过低报错信息类似npx: command not found或Unsupported engine。用node -v确认版本低于 18.20.4 就升级。升级后重启终端确保 PATH 生效。session 复用导致报错如果你把stdio_client的 session 存成全局变量第二次调用时可能报Session is closed。按我上面的写法每次调用工具重新开 session虽然多一次启动但稳定。如果你追求性能可以用连接池但实现复杂度高不建议新手折腾。模型不返回 tool_calls前面提过某些云厂商的 DeepSeek 版本不支持。确认你用的api_base是官方或 TaoToken 兼容层模型 ID 是deepseek-chat。如果还是不行在bind_tools后打印llm_with_tools的绑定结果确认工具确实传进去了。排查时建议打开 debug 日志LangChain 支持langchain.debug True能看到完整的请求和响应。MCP 侧可以在call_tools里打印result的原始内容确认工具是否真的被调用。6. 把 MCP endpoint 统一到 TaoToken 后的长期用法跑通一次天气查询只是起点。真正有价值的是把这套模式复制到其他工具上比如查 POI、算路线、甚至调用你自己的内部服务。这时候 endpoint 的统一管理就很重要了。TaoToken 的 API 地址https://taotoken.net/api可以作为模型侧的统一入口而 MCP 工具侧你可以继续用 stdio也可以逐步迁移到远程 MCP Server。如果你打算长期做 Agent 开发建议把 Key 管理、模型切换、工具注册都抽象成配置。比如用一个config.yaml存模型 ID 和 Base URL用环境变量存敏感 Key。这样换模型时只改一处不用翻遍代码。TaoToken 的接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentchatdeepseek_amap_mcputm_campaignrewrite里有关于多模型路由的说明可以参考。对于需要频繁调用工具的场景Coding Plan 可能比按量计费更划算具体可以看https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentchatdeepseek_amap_mcputm_campaignrewrite。但如果你只是偶尔跑几个查询按量付费就够了。最后提醒一点MCP Server 通过 stdio 启动时每次调用都会拉起一个 Node 进程如果并发高进程数会暴涨。生产环境建议用 SSE 或 HTTP 传输的 MCP Server或者自己做一个常驻的 MCP 网关。高德官方目前主要提供 stdio所以如果你要上生产可能需要自己包一层。代码跑通后你可以试着把 system prompt 改得更具体比如“你只能调用 maps_weather 工具参数必须包含 city 和 date”这样能减少模型乱调工具的概率。也可以加一个 fallback当工具调用失败时让模型直接回复“暂时查不到天气”。这些细节决定了 Agent 的可用性。整套流程里最关键的三个配置项是TaoToken 的 Base URL、高德 Key、Node 版本。把这三个确认好剩下的就是复制代码、跑起来、看结果。遇到报错就对照第 5 节排查基本能覆盖 90% 的问题。
阅读完成 · 觉得有帮助?