1. 为什么要在 Dify 里接一个 12306 查询工具
如果你正在用 Dify 搭出行助手,大概率会遇到一个尴尬:模型能聊火车票,但真问「明天福州到兰州有哪些车次」,它只能凭记忆编,车次号、发到时间、余票全是幻觉。原因很简单,大模型本身没有实时数据源,它需要外部工具。
这里有两个概念要先分清楚。Function Calling 是模型厂商给的「表达能力」,模型自己解析意图、生成调用指令,格式各家不同,OpenAI、Qwen 的响应结构都有差异。MCP(Model Context Protocol)是「连接规则」,用 JSON-RPC 2.0 把工具交互标准化,任何支持 MCP 的客户端都能接同一套服务,不绑死某一家模型。一句话:Function Calling 让模型知道「何时调用工具」,MCP 解决「如何安全高效地调用工具」。
Dify 通过 MCP 插件把这两者串起来:插件负责和 MCP 服务通信,模型只负责决定调哪个工具、传什么参数。这篇就按「装插件 → 拿 12306 MCP 配置 → 建 Agent → 真实查一次车次」的顺序走一遍,链路跑通后你就能把同样的骨架换成机票、酒店、天气等任意 MCP 服务。
适合谁看:已经会用 Dify 建 Agent 或工作流、想给应用加实时数据能力的开发者;对 MCP 只听过名字、想找个具体场景上手的人。全程不需要你写后端服务,配置为主。
2. 前置准备:Dify 的 MCP 插件与 TaoToken 模型接入
动手前先把两件事备齐:Dify 侧能装插件,模型侧能稳定调用支持 Function Calling 的模型。
Dify 这边,进入 Marketplace 搜索 MCP,安装MCP SEE插件(有的版本显示为 MCP SSE / MCP Client,认准能配置 SSE 地址的那个)。装完在插件列表里能看到它,后面 Agent 添加工具时会用到。
模型这边,Agent 要跑 Function Calling,模型必须原生支持工具调用。我实测下来 Qwen 系列里 72b 和 32b 表现稳定,30b 那档在 MCP 多轮调用上容易掉链子,后面第 5 节会具体说。如果你本地没有合适的模型服务,可以用 TaoToken 统一接入,它兼容 OpenAI 风格的接口,Dify 里填 Base URL 和 Key 就能用。
TaoToken 的 API 地址是https://taotoken.net/api,模型对话、Coding Plan、控制台、API Keys 这些入口都在官网能找到:
官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= API 地址:https://taotoken.net/api
在 Dify 的「设置 → 模型供应商」里选 OpenAI 兼容类型,Base URL 填上面的 API 地址,Key 从控制台生成。生成 Key 的页面在这里:
API Keys:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
如果你打算长期跑编码类 Agent、频繁调用工具,可以看下 Coding Plan,额度模型更适合这种多轮工具调用场景:
Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
模型接好后,在 Dify 里先建一个空白 Agent 试一句普通对话,确认模型通了,再往下接 MCP。这一步别省,否则后面报错你分不清是模型问题还是 MCP 配置问题。
3. 可复制的 12306 MCP 服务配置骨架
MCP 服务从哪来?两个常用来源:魔搭社区 MCP 广场(https://modelscope.cn/mcp)和智谱的搜索 MCP 页面。在广场里搜 12306,能找到现成的火车票查询 MCP 服务,点进去一般会给你一段配置,形如:
{ "mcpServers": { "12306-mcp": { "url": "https://example-mcp-host/sse", "type": "sse" } } }注意,广场给的原始配置字段名不一定和 Dify 插件对得上。Dify 的 MCP 插件通常要的是「服务名 + SSE 地址」这种更扁平的结构,所以要做一次改造。把上面的配置改成插件能识别的样子:
{ "mcpServers": { "12306": { "transport": "sse", "url": "https://example-mcp-host/sse" } } }关键字段说明,用表格对照一下更清楚:
| 字段 | 作用 | 常见坑 |
|---|---|---|
mcpServers | 顶层容器,可放多个服务 | 名字写错插件直接读不到 |
服务名(如12306) | 工具前缀,Agent 里显示为12306.xxx | 含空格或中文可能解析失败 |
transport/type | 传输方式,SSE 场景填sse | 填成stdio会连不上远程 |
url | MCP 服务的 SSE 端点 | 少写/sse路径会 404 |
把改造后的 JSON 复制进 Dify 的 MCP 插件配置框,保存。保存成功后插件一般会显示已连接的服务数量,如果显示 0 或者报连接超时,先检查 url 是否可访问、transport 是否写对。
注意:MCP 服务地址请以你实际获取到的为准,上面
example-mcp-host只是占位。不要把它当成固定地址直接抄。
配置保存后,回到 Agent 编辑页,在「工具」里添加 MCP 相关工具。Dify 的 MCP 插件一般会暴露三个工具:获取 MCP 工具列表、调用 MCP 工具,加上系统自带的当前时间。这三个是后面 Agent 能查车次的最小集合。
4. 建 Agent 并跑通一次真实车次查询
新建一个 Agent 应用,模型先选 Qwen2.5-72b(温度设 0,减少随机性)。提示词这样写:
你叫"火车侠",是 12306-MCP 专属 AI 助理,专注铁路出行服务。 调用 MCP 工具时,先获取工具列表,再选择 12306 相关工具来回答。 你需要先了解本 MCP 每个工具的参数含义,再发起调用。 用户查询车票、规划行程时,给出车次、发到时间、历时和余票的最优推荐。工具勾选:当前时间、获取 MCP 工具列表、调用 MCP 工具。
然后发一句真实查询:「明天从福州到兰州的火车」。
正常链路是这样的:模型先调「获取 MCP 工具列表」,拿到 12306 服务下有哪些方法(比如按站站查询、按车次查询);再调「调用 MCP 工具」,传入出发站、到达站、日期参数;MCP 服务返回车次列表,模型整理成自然语言。
一次成功的返回大概长这样(车次信息以实际查询为准):
明天福州到兰州方向,为你找到以下车次: G1902 福州 08:12 发车,兰州西 20:35 到达,历时约 12 小时 23 分,二等座有票 Z126 福州 11:05 发车,兰州 次日 14:20 到达,历时约 27 小时,硬卧有票 ...看到车次号、发到时间、余票这些字段被正确填出来,说明 MCP 链路通了。如果模型只回「我无法查询实时车次」,多半是工具没勾上,或者模型没触发 Function Calling。
再换两个模型对比一下,这一步很关键。用 Qwen2.5-32b 问「后天从镇江到定西的火车余票」,通常也能正常调用。但换成 Qwen3-30b 问同样的问题,我实测下来它经常不触发 MCP 调用,直接凭记忆编答案,或者只调了「获取工具列表」就停住,不再往下调「调用 MCP 工具」。温度设 0 也一样,属于模型对多轮工具调用的支持不足,不是配置问题。
所以选型建议:优先 Qwen2.5-72b,其次 Qwen2.5-32b,30b 这档在 MCP 场景先别用。如果你用 TaoToken 接入,可以在模型对话页先单独测一下模型的工具调用能力,确认它支持再放进 Agent:
模型对话:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
5. 本篇常见报错与排查清单
接 MCP 最容易卡在几个固定位置,按下面顺序排查,基本能覆盖九成问题。
插件保存后服务数为 0。先确认 url 能访问,浏览器直接打开 SSE 地址看有没有响应;再确认transport字段是sse不是stdio;最后检查 JSON 有没有多余逗号,Dify 的配置框对格式很敏感。
Agent 不调用 MCP 工具。三个原因:工具没勾选、模型不支持 Function Calling、提示词没引导。先确认「获取 MCP 工具列表」和「调用 MCP 工具」都勾了;再换 Qwen2.5-72b 试;提示词里明确写「先获取工具列表再调用」,别指望模型自己猜。
调用了工具但返回空。多半是参数名对不上。MCP 工具对出发站、到达站、日期的字段名有固定要求,让模型先调「获取工具列表」看清参数定义,再传值。日期格式也要注意,有的服务要YYYY-MM-DD,有的要时间戳。
模型编造车次。这是最危险的,说明它没真调工具。把温度降到 0,提示词里加一句「所有车次信息必须来自 MCP 工具返回,不得凭记忆回答」。如果还编,就是模型工具调用能力不行,换模型。
多轮对话后工具失效。MCP 支持持续上下文,但 Dify 的会话记忆和 MCP 上下文是两套东西。长对话里如果工具突然不响应,开个新会话重试,或者检查插件连接是否超时断开。
提示:排查时把 Dify 的日志级别调高,能看到模型实际发出的工具调用请求和 MCP 返回的原始 JSON,比猜快得多。
6. 把骨架复用到其他 MCP 服务
12306 只是验证链路的一个例子。这套「装 MCP 插件 → 改造配置 → 建 Agent → 勾三个工具」的骨架,换成天气、航班、地图任何 MCP 服务都能用,区别只在服务名和参数。
如果你要长期跑这类 Agent、频繁做工具调用,建议把模型接入统一到 TaoToken,省得每个应用单独配 Key。接入文档在这里,里面有 Dify、LangChain 等常见客户端的配置示例:
接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
最后留一个我踩过的坑:MCP 服务名别用中文或带空格,Agent 里工具会显示成服务名.方法名,名字不规范时模型容易解析错。用12306、weather这种纯英文短名最稳。链路跑通后,先拿一个简单查询压测几次,确认稳定了再往工作流里接。