1. 为什么 Dify 工作流里的图表总是“最后一公里”卡住
Dify 把 LLM 编排、知识库检索、工具调用串成一条流水线之后,很多人会发现一个尴尬的断点:数据查出来了,结论也生成了,但最后要交付的图表还得手动复制到 Excel 或 Python 脚本里重画一遍。这个断点不是 Dify 的问题,而是“文本输出”和“图形输出”之间天然存在一道格式鸿沟——大模型擅长吐 JSON 和 Markdown,但没法直接吐一张 PNG。
AntV 团队开源的 mcp-server-chart 正好补上了这一环。它把 15 种以上常用图表(折线、柱状、饼图、散点、雷达、词云、双轴、思维导图、流程图、鱼骨图、网络图等)封装成 MCP 协议下的标准工具,Dify 通过 MCP 客户端调用后,拿回的是一个图片链接,可以直接嵌进 Markdown 报告、邮件正文或前端页面。换句话说,你让 Dify 分析完销售数据,它顺手就把柱状图渲染好了,不需要你再打开任何绘图软件。
这套组合适合三类人:一是用 Dify 搭内部报表机器人的开发者,希望输出直接带图;二是做数据分析 Agent 的团队,需要把“查询→分析→可视化”压进一条工作流;三是个人开发者,想用最低成本验证“自然语言生成图表”的可行性。我实测下来,从零配置到跑通第一张图,大约 20 分钟,其中大部分时间花在确认 Node 环境和 MCP 配置格式上。
需要提前说明的是,Dify 本身不内置 MCP 客户端,你需要通过支持 MCP 的插件或外部工具层来桥接。本文的实践路径是:Dify 工作流中通过 HTTP 请求节点调用一个本地或远程的 MCP 服务网关,网关再转发到 mcp-server-chart。如果你用的是 Cline、Claude Code 这类自带 MCP 客户端的工具,配置会更直接,但 Dify 场景下多一层转发是常态。下面从 TaoToken 的统一 Key 接入开始,把整条链路拆开。
2. TaoToken 统一 Key 与 MCP 通道的前置准备
在配置 AntV 图表 MCP 之前,先解决模型调用通道的问题。Dify 工作流里通常至少有一个 LLM 节点负责解析用户意图、提取图表参数(比如图表类型、数据字段、标题),这个节点需要稳定的 API 通道。TaoToken 的作用是把多家模型的调用收敛成一个 Base URL 和一个 Key,省去在 Dify 里为每个模型单独配供应商的麻烦。
你需要先拿到两样东西:API Key 和 Base URL。Key 在控制台创建,Base URL 统一填https://taotoken.net/api。注意这个地址不带任何查询参数,直接作为 OpenAI 兼容接口的根路径使用。如果你用的是 Dify 的 OpenAI 供应商插件,Base URL 填这个值,模型名按 TaoToken 文档里支持的名称填,比如claude-sonnet-4-20250514或gpt-4o这类。
创建 Key 的入口在控制台,具体路径是https://taotoken.net/console,登录后在 API Keys 页面新建。建议给这个 Key 起一个能区分用途的名字,比如dify-antv-chart,方便后续排查是哪个工作流在消耗额度。Key 只显示一次,复制后先存到密码管理器里。
模型选择上,图表参数提取这个环节对模型能力要求不算高,但要求输出稳定的 JSON。实测下来,Claude 系列在“把自然语言转成结构化图表配置”这件事上格式遵从度较好,GPT 系列在数据字段映射上偶尔会多包一层。你可以先在模型对话页面手动试几条 prompt,确认模型能稳定输出{chartType, data, title, width, height}这样的结构,再写进 Dify 的提示词里。
TaoToken 的 Coding Plan 适合长期跑 Agent 工作流的场景,因为图表生成往往伴随多轮工具调用,按量计费在调试期容易超预期。如果你只是验证阶段,先用按量 Key 即可。接入文档在https://taotoken.net/doc,里面有各语言 SDK 的示例,Dify 场景下主要看 OpenAI 兼容那部分。
这里有一个容易踩的坑:Dify 的 OpenAI 插件默认会拼接/v1/chat/completions,所以 Base URL 填https://taotoken.net/api后,实际请求路径是https://taotoken.net/api/v1/chat/completions。如果你填成https://taotoken.net/api/v1,就会变成双/v1,直接 404。这个细节在配置时确认一次,后面省很多事。
3. 可复制的 MCP 配置与 Dify 工具节点参数
这一节是整篇的核心,配置片段可以直接复制。先装 mcp-server-chart,再写 MCP 配置,最后在 Dify 里建工具节点。
3.1 安装 mcp-server-chart
确保本机 Node.js 版本在 18 以上,然后全局或项目内安装:
npm install -g @antv/mcp-server-chart如果你不想全局装,用npx直接跑也可以,配置里 command 写npx,args 写["-y", "@antv/mcp-server-chart"]。全局装的好处是启动快,npx 的好处是不污染环境。我两种都试过,npx 首次启动会多几秒下载时间,之后有缓存就快了。
3.2 MCP 配置文件
如果你用的是 Cline 或 Claude Code 这类自带 MCP 客户端的工具,配置文件通常放在项目根目录或用户配置目录。以 Cline 为例,cline_mcp_settings.json内容如下:
{ "mcpServers": { "mcp-server-chart": { "command": "npx", "args": ["-y", "@antv/mcp-server-chart"], "env": { "FONT_FAMILY": "Source Han Sans SC" } } } }FONT_FAMILY这个环境变量是解决中文图例空白的关键,后面排障章节会展开。如果你用全局安装,command 改成mcp-server-chart,args 留空数组即可。
3.3 Dify 侧的工具节点配置
Dify 本身不直接读上面的 JSON,你需要一个 MCP 网关把 stdio 协议转成 HTTP。常见做法是用mcp-proxy或自己写一个轻量 Express 服务。假设网关跑在http://127.0.0.1:3100,Dify 工作流里加一个 HTTP 请求节点,配置如下:
| 参数 | 值 |
|---|---|
| Method | POST |
| URL | http://127.0.0.1:3100/mcp |
| Headers | Content-Type: application/json |
| Body | 见下方 JSON |
Body 里传的是 MCP 的tools/call请求,以生成柱状图为例:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "generate_column_chart", "arguments": { "data": [ { "month": "1月", "sales": 320 }, { "month": "2月", "sales": 410 }, { "month": "3月", "sales": 380 } ], "xField": "month", "yField": "sales", "title": "一季度销售趋势", "width": 800, "height": 600 } } }Dify 的 LLM 节点负责把用户输入转成上面arguments里的字段,HTTP 节点负责发出去。如果你希望 LLM 直接输出完整 JSON,可以在提示词里加一句“只输出 JSON,不要解释”,然后把 LLM 输出变量映射到 HTTP Body。
3.4 模型节点与 TaoToken 的对接
Dify 的 LLM 节点选 OpenAI 供应商,Base URL 填https://taotoken.net/api,Key 填你在控制台创建的 Key,Model 填claude-sonnet-4-20250514。提示词模板可以这样写:
你是一个图表参数提取器。用户会给你一段自然语言描述和一组数据。 请输出 JSON,字段包括 chartType(column/line/pie/scatter 等)、data(数组)、xField、yField、title。 只输出 JSON,不要任何额外文字。 用户输入:{{query}} 数据:{{data}}这样 LLM 节点输出稳定 JSON,HTTP 节点直接消费,整条链路不需要人工干预。
4. 从数据输入到图表返回的验证请求
配置写完,必须跑一次端到端验证,否则你不知道是 MCP 没起来、网关没转发,还是 Dify 变量映射错了。验证分三步:先单独测 MCP 服务,再测网关,最后测 Dify 工作流。
4.1 单独测 MCP 服务
在终端直接跑:
npx -y @antv/mcp-server-chart如果服务正常,它会进入 stdio 监听状态,不输出任何内容。你可以用echo发一个 JSON-RPC 请求进去:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | npx -y @antv/mcp-server-chart正常返回是一个包含generate_column_chart、generate_line_chart等工具名的列表。如果这一步就报错,先检查 Node 版本,再检查网络是否能拉到 npm 包。
4.2 测网关转发
假设网关跑在 3100 端口,用 curl 发同样的tools/call:
curl -X POST http://127.0.0.1:3100/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "generate_column_chart", "arguments": { "data": [{"month":"1月","sales":320},{"month":"2月","sales":410}], "xField": "month", "yField": "sales", "title": "测试柱状图" } } }'成功的话,返回 JSON 里会有一个content数组,里面是图片链接,形如https://.../chart.png。把这个链接贴到浏览器,能看到渲染好的柱状图。如果返回local proxy failed或连接拒绝,说明网关没起来或端口不对。
4.3 测 Dify 工作流
在 Dify 里新建一个工作流,节点顺序:开始 → LLM(TaoToken 通道)→ HTTP 请求(网关)→ 结束。开始节点加两个输入变量query和data,LLM 节点按 3.4 的提示词配置,HTTP 节点按 3.3 的 Body 配置,其中arguments里的字段用 LLM 输出变量替换。
运行工作流,输入:
query: 帮我生成一季度销售柱状图 data: [{"month":"1月","sales":320},{"month":"2月","sales":410},{"month":"3月","sales":380}]如果一切正常,结束节点会输出图片链接。点开链接能看到图,说明整条链路通了。我实测时第一次跑返回的是reading choices报错,原因是 LLM 输出被包了一层 Markdown 代码块,HTTP 节点解析失败。解决办法是在 LLM 提示词里强调“不要用代码块包裹”,或者在 HTTP 节点前加一个代码节点做字符串清洗。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
这一节按真实报错来,每个都给出定位方法和修复动作。
5.1 401 Unauthorized
这个报错出现在 LLM 节点,说明 TaoToken 的 Key 没填对或没带上。检查三处:Dify 供应商配置里的 API Key 是否粘贴完整(没有多余空格);Base URL 是否是https://taotoken.net/api;如果用的是自定义模型供应商,确认请求头里带了Authorization: Bearer <key>。还有一种情况是 Key 被禁用或额度耗尽,去控制台看 Key 状态。
5.2 local proxy failed
这个报错通常出现在 Dify 的 HTTP 节点,意思是 Dify 容器无法访问你填的127.0.0.1:3100。因为 Dify 跑在 Docker 里时,127.0.0.1指向容器本身,不是宿主机。解决办法是把网关地址改成宿主机的局域网 IP,比如http://192.168.1.100:3100/mcp,或者在 Dify 的 docker-compose 里加extra_hosts把host.docker.internal映射到宿主机网关。如果你用的是 Dify 云版,那网关必须暴露公网地址,本地 127.0.0.1 不可达。
5.3 reading choices 报错
这个报错说明 LLM 返回的内容不是合法 JSON,HTTP 节点在解析时失败。常见原因是模型把 JSON 包在 Markdown 代码块里,或者加了“好的,以下是 JSON”这类前缀。修复方式有两种:一是在提示词里加“只输出 JSON,不要代码块,不要解释”;二是在 LLM 节点和 HTTP 节点之间加一个代码节点,用正则把```json和```去掉。我倾向第二种,因为模型偶尔不听话,代码节点兜底更稳。
5.4 OAuth 相关报错
如果你在 MCP 网关层加了鉴权,可能会遇到 OAuth token 过期或 scope 不足的报错。mcp-server-chart 本身不需要 OAuth,但如果你用的网关框架默认开了 OAuth,需要在网关配置里关掉,或者给 Dify 的 HTTP 节点加上正确的 Bearer token。检查网关日志里401和invalid_token关键字,确认 token 签发和校验用的是同一套密钥。
5.5 图表中文空白
生成的图里中文标题或图例显示为方块或空白,这是字体问题。mcp-server-chart 渲染时依赖系统字体,如果容器或本机没有中文字体,就会 fallback 到默认字体导致空白。解决办法是在 MCP 配置的env里指定FONT_FAMILY,值填系统里已安装的中文字体名,比如Source Han Sans SC或Noto Sans CJK SC。如果系统没装,先装字体再重启 MCP 服务。这个坑我在第一次跑中文标题时踩过,图出来了但标题是空的,排查了半小时才定位到字体。
6. 把图表能力接进你的日常工作流
配置跑通之后,真正有价值的是把它嵌进重复性任务里。比如你每天要出一份销售日报,可以在 Dify 工作流里加一个定时触发,数据从数据库或 API 拉取,LLM 节点负责总结趋势并提取图表参数,HTTP 节点调 MCP 生成图,最后结束节点把文字结论和图片链接拼成 Markdown 推送到企业微信或邮件。整条链路不需要人打开任何绘图工具。
如果你用 Claude Code 做开发,可以把 mcp-server-chart 直接配到 Claude Code 的 MCP 配置里,这样在终端里让 Claude 分析 CSV 文件时,它能直接调图表工具生成图,省去 Dify 那层转发。配置格式和 3.2 节一样,只是客户端从 Dify 换成 Claude Code。Coding Plan 在这种长期编码加可视化的场景下比较划算,因为工具调用频次高,按量计费容易失控。
还有一个实用技巧:把常用的图表参数模板存成 Dify 的变量或提示词片段,比如“销售数据默认用柱状图,时间序列默认用折线图,占比默认用饼图”。这样 LLM 节点不需要每次从零推理图表类型,输出更稳定,也省 token。我试过在提示词里加一句“如果用户没指定图表类型,按数据特征自动选择”,实测下来模型选错的概率明显降低。
最后提醒一点:mcp-server-chart 返回的是图片链接,如果你需要把图嵌进 PDF 或离线文档,记得先把图片下载到本地再引用,否则链接失效后图就没了。这个细节在自动化报告场景里容易被忽略,但交付给非技术同事时很关键。