Dify工作流实现一键生成饼状图:从数据到ECharts可视化完整指南 Dify 里做“一键生成饼状图”不是平台内置了一个画图按钮而是靠工作流编排把用户输入变成可展示的图表页面。最近聊 Dify 智能体平台的人很多但真正拿它做日常报表、运营看板和内部数据展示时大多数人卡在同一个地方数据能进平台图表却出不来。这篇文章会从环境准备、数据格式、工作流节点、代码脚本到排错链路把“Dify 生成饼状图”这条完整路径拆开讲一遍。适合正在用 Dify 做内部工具、报表应用或者想用大模型应用平台做数据可视化的开发者和产品同学最值得关注的是怎么绕过花哨的功能列表先把一条用户输入到最终饼状图的最小链路跑通。1. 先搞清楚Dify 的一键饼状图到底是怎么实现的1.1 它不是内置按钮而是一条可复用工作流很多人一听到“一键生成饼状图”以为 Dify 里有个现成的图表组件选个数据源就能出图。实际情况不是这样。Dify 是一个大模型应用开发平台擅长把自然语言理解、数据处理、API 调用、前端展示串成一个可复用的应用但它本身不会替你完成“图表渲染”这件事。常规做法是用户输入数据LLM 把数据整理成结构化 JSON再用代码节点生成一段 ECharts 饼状图 HTML最后在 Dify 的 WebApp 页面里展示。因为 ECharts 生态成熟、图表类型多而且支持用 HTML 片段直接渲染所以这是目前比较稳的方案。“一键”这个体验要分成两头看。使用端确实是一键打开应用粘贴数据点运行浏览器里出现饼图。搭建端则需要把三段能力串起来数据抽取、格式转换、图表配置。1.2 这个方案解决什么问题很多人用 Dify 做聊天助手但做数据展示类应用时会发现纯聊天式的输出很难让业务人员直接看懂。饼状图的价值就在于把“一堆数字”变成“一眼能看明白的占比关系”。我建议用这个方案处理以下场景运营日报把各渠道访问量、订单量转成占比图。销售看板把不同产品线销售额变成饼图辅助复盘。市场调研把问卷结果中的选项分布可视化。内部工具非技术人员在界面里贴一段数据直接生成图表不用打开 Excel 或 BI 工具。适合做饼状图的数据通常不复杂核心就是两个字段分类名称和数值。如果数据维度多、关系复杂饼图反而不好看不如用柱状图或折线图。这里要先把预期控制住所谓一键是在数据相对规整的前提下成立。2. 启动环境本地部署不是必须但先满足这 3 个条件2.1 环境差异云服务体验本地部署可控Dify 本身可以托管使用也可以本地部署。如果只是想验证功能、跑通流程直接用云服务是省事的选择。但如果要接入内网数据、控制模型调用成本或者不希望把业务数据放到外部平台本地部署会更合适。本地部署最常见的路径是 Docker Compose 一键拉起官方仓库和文档里都有安装引导。这里不写死版本号因为 Dify 迭代比较快不同版本的端口、环境变量、节点名称会略有差异。通用步骤是这样# 1. 拉取 Dify 项目代码 git clone https://github.com/langgenius/dify.git # 2. 进入 docker 目录 cd dify/docker # 3. 复制环境变量文件 cp .env.example .env # 4. 启动服务 docker compose up -d启动后用浏览器访问部署提示的地址进入安装页按引导创建管理员账号。实际端口取决于 docker-compose 里的端口映射配置常见的是 80 或 3000但不代表所有版本都相同。如果访问不了先看容器是否正常运行docker compose ps这一步的目的不是把环境调得多完美而是先有一个能跑通的 Dify 实例。容器状态是 running 不代表应用已经就绪还要看日志里是否出现服务启动完成。2.2 三个必须提前确认的运行条件环境跑起来之后别急着做饼状图先确认三件事。第一模型 API 是否可用。Dify 工作流需要调用大模型做数据理解模型能力直接影响 JSON 输出的稳定性。建议选择支持 JSON 结构化输出的模型并在 Dify 的“模型供应商”里把 API Key 配好。不同模型的输出质量和格式遵守程度差别很大如果你是新手优先选常见模型的较新版本稳定度会高一些。第二WebApp 的 HTML 渲染能力。这里的“一键生成饼状图”最终依赖前端渲染 HTML。Dify 的 WebApp 页面在多数版本里支持 Markdown 和部分 HTML 标签但不同版本对 JavaScript 脚本、iframe、外部 CDN 的加载策略可能不同。不要以为所有 HTML 都能原样渲染搭建前先用一个最简单的 HTML 片段跑一遍div stylewidth:100%;height:300px;background:#eee;HTML 渲染测试/div如果这个片段能显示说明基本 HTML 没问题如果整个页面没有变化或显示成源码需要查一下版本的展示策略或者换用其他前端方案。第三ECharts 脚本怎么加载。常见做法是在生成 HTML 里引用公共 CDNscript srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script但内网环境可能访问不了外部 CDN导致图表容器有宽高、里面却是空白。生产环境如果要稳定需要把 ECharts 静态文件放到内网可访问的位置再在 HTML 里引用对应地址。这里要记住HTML 能生成不代表浏览器能正常加载图表脚本资源和网络访问是另一个独立问题。3. 数据准备饼状图好不好一半在数据格式3.1 让模型处理“规整后的数据”而不是让它猜很多人在这个环节踩坑直接给模型一大段非结构化文本然后要求它生成饼状图配置。模型确实能猜一部分但猜出来的分类、数值经常会出错。比如原文里写“线上大概三千二左右”模型可能把“三千二”解析成 3000、3200或者干脆解析成字符串。这样出来的图表看着像那么回事数字却经不起核对。更稳妥的做法是尽量让用户输入结构化数据或者在进入 LLM 节点之前先把文本抽成表格或 JSON。这样模型的任务不是“理解语义”而是“转换格式”准确率会高很多。饼状图最少需要两个字段{ source: 营业数据, name: 销售渠道, value: [ { name: 线上, value: 3200 }, { name: 门店, value: 2100 }, { name: 代理, value: 980 } ] }这个 JSON 结构很轻模型很好处理。name是图表标题value数组里每一项代表一个扇区。分类名称建议直接用中文这样后面生成 HTML 的时候不用额外做映射。3.2 不同输入格式的处理思路如果最终用户真的很习惯“粘贴一段文本”也不要急着让模型直接出图表。可以在 LLM 节点之前加一个前置提示词让模型先输出上面的 JSON再做后续转换。或者如果用户上传的是 CSV、Excel 文件在 Dify 里读取文件后通过代码节点解析成 JSON 再交给 LLM。这里有个经验不要一个节点做所有事。数据抽取、格式转换、图表生成三个阶段分开出问题时你能很快定位是模型理解错了还是代码拼接错了。数据量也要控制。饼状图适合 2 到 10 个分类。如果用户贴了 50 行分类数据直接画饼图会有大量窄扇区标签拥挤观感很差。可以让模型先按数值排序只保留前 8 个其余的合并为“其他”。这种优化一步到位用户感知最明显。4. 搭工作流从用户输入到 ECharts 配置4.1 为什么用工作流而不是“直接聊天”Dify 里可以创建聊天助手类型应用也可以创建工作流类型应用。做饼状图时我更推荐工作流。因为聊天助手的交互自由度太高用户可能说一堆和图表无关的话模型容易被带偏。工作流不一样节点是固定的用户输入一旦进入开始节点后面每个环节都是确定的。你可以理解成聊天助手是“自由对话”工作流是“固定管道”。你要做一个可复用的图表应用管道远比自由对话可靠。新建工作流后核心节点只需要四个开始节点接收用户输入。LLM 节点把输入整理成图表 JSON。代码节点把 JSON 拼成 ECharts HTML。结束节点把 HTML 输出给前端。这种结构的优点是每个节点都能单独调试。LLM 输出有问题就调提示词代码节点报错就调脚本不会一错一大片。4.2 LLM 节点提示词要“限制输出格式”LLM 节点的提示词是整个流程里最容易影响成功率的地方。很多模型默认会在 JSON 外层加 markdown 代码块或者输出额外说明文字。这样代码节点直接解析会失败。为了避免这个问题提示词里要明确要求“只输出 JSON不要输出任何解释不要加 markdown 代码块”。一个可以参考的提示词结构你是一个数据可视化助手。请根据用户输入的数据生成饼状图配置 JSON。 要求 1. 只输出 JSON不要输出任何解释。 2. JSON 结构如下 { source: 数据来源说明, name: 图表标题, value: [ { name: 分类名称, value: 数值 } ] } 3. 分类名称使用中文。 4. 如果分类超过 8 个只保留数值最大的 8 个其余合并为“其他”。 5. 数值必须是数字不要带单位。这里把“分类超过 8 个就合并”直接写进提示词能省很多后续处理。模型在生成 JSON 时就已经完成了数据裁剪。模型参数里面温度建议调到 0 到 0.2。饼状图配置不需要创意温度越低输出越稳定。如果平台支持“JSON 模式”或“结构化输出”优先开启这比提示词里的“只输出 JSON”更可靠。LLM 节点最终要输出一个字符串变量这里叫它chart_json方便后面的代码节点引用。不同版本 Dify 的变量名配置方式略有差异但思路一致上游节点输出一个变量下游节点读取。5. 代码节点把 LLM 输出转成可渲染 HTML5.1 Python 脚本的基本结构Dify 的代码节点支持 Python 和 Node.js常见做法是写一个main函数接收上游变量作为参数返回一个字典。以 Python 为例如果 LLM 节点输出的变量名是chart_json代码节点可以这样写import json import html def main(chart_json: str) - dict: try: data json.loads(chart_json) except Exception as e: return {html: fpJSON 解析失败{e}/p} name data.get(name, 数据分布) items data.get(value, []) # 对标题做 HTML 转义避免特殊字符破坏页面 safe_name html.escape(str(name)) # 把数据序列化成 JS 数组 series_data json.dumps(items, ensure_asciiFalse) chart_html f div idchart stylewidth:100%;height:420px;/div script srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script script var chart echarts.init(document.getElementById(chart)); var option {{ title: {{ text: {safe_name} }}, tooltip: {{ trigger: item }}, legend: {{ bottom: 0 }}, series: [{{ type: pie, radius: [40%, 70%], data: {series_data} }}] }}; chart.setOption(option); /script return {html: chart_html}这个脚本里最核心的是两个点。第一把chart_json从字符串转成 Python 对象。因为 LLM 输出的内容本质上是字符串不是真正的字典。第二把数据用json.dumps转成 JavaScript 数组格式。注意这里用了ensure_asciiFalse否则中文名称会变成\u4e2d\u6587这种转义形式虽然也能显示但可读性差。5.2 为什么要加 try except 和转义代码节点最容易翻车的地方是 LLM 输出的 JSON 不合规。加try except不是为了掩盖问题而是让用户至少能看到一个错误提示而不是整个页面空白。业务人员看到“JSON 解析失败”虽然不友好但比页面空白好排查得多。HTML 转义很多人会忽略。如果用户数据里带着引号、尖括号、特殊字符直接拼到 HTML 里会导致页面结构错乱甚至出现脚本执行异常。示例里对标题做了html.escape但对value数组里的分类名没有逐项处理。如果数据来自不可信用户正式环境应该把每个分类名都做一遍转义或者在前置 LLM 节点就明确禁止使用特殊字符。对内网工具来说问题不大但做公开应用时这是一个必须注意的基本安全点。还有一点要注意代码节点里引用的 ECharts 脚本来自外部 CDN。你的用户访问 WebApp 时浏览器会去外部地址拉取脚本。如果部署环境没有外网这个图表就会始终空白。解决方式是把echarts.min.js放到自己的静态资源目录然后在 HTML 里引用内网地址。Dify 的静态资源托管方式不同版本不太一样建议先确认平台的静态文件路径规则再决定是继续用 CDN 还是换本地资源。6. 验证效果单条数据跑通后再看展示细节6.1 先看节点日志再点“发布”工作流搭好后不要急着发布到 WebApp。先在 Dify 的编排页面里输入一条测试数据点击运行然后查看每个节点的输入输出。我第一次做的时候LLM 节点输出的 JSON 看起来没问题但代码节点一直报错。后来发现是 LLM 把 JSON 放进了 markdown 代码块里json.loads根本没机会处理。这个问题的排查成本极低只要看一眼节点输出原文就知道。成功判断标准可以按这张表来检查点期望结果异常可能原因LLM 节点输出能直接json.loads的字符串提示词约束不够、模型版本较旧、没有开启 JSON 模式代码节点返回html字段包含div和script变量名不对、代码节点引用字段写错WebApp 展示页面出现饼状图鼠标悬停有提示CDN 无法访问、HTML 脚本被过滤、浏览器控制台报错中文显示分类名称和标题显示正常JSON 或 JS 转义问题、编码问题先在编排页里跑通再去 WebApp。因为编排页能看到节点中间结果排查效率高很多。直接打开 WebApp 测一旦出问题只能看到最终页面没法判断是哪一段坏了。6.2 从“能出图”到“好看”需要固定风格能出图只是一个基础版本。实际内部工具里大家还会关心颜色、图例位置、占比标签是否显示。ECharts 的series里可以加label配置让每个扇区旁边显示名称和百分比label: { formatter: {b}: {d}% }代码节点里的option可以继续扩展比如color指定一组固定颜色避免每次随机颜色差异太大。legend控制图例位置数据多时放底部。tooltip鼠标悬停时显示原始数值和占比。radius控制环形图内外半径视觉上更现代。这些配置都写在代码节点的option对象里。我的建议是不要一开始就追求炫酷先保证数据和图表能对应上再慢慢调样式。因为每次改动代码节点都需要重新跑一次工作流如果一次加了太多配置出了问题很难定位是数据问题还是样式问题。WebApp 的“一键”体验到了这一步基本成立用户打开应用粘贴数据点运行浏览器直接显示饼状图。没有图表工具经验的业务人员也能看懂。7. 常见坑和排查链路先看数据再看脚本最后怀疑模型7.1 最影响成功率的四类问题第一类LLM 输出不是合法 JSON。最典型的特征是代码节点报错或者返回“JSON 解析失败”。解法是提示词里写明“不要 markdown 代码块”并开启结构化输出。第二类字段名对不上。LLM 输出了{name: 渠道, data: [...]}但代码节点读取的是value结果自然是空数组。处理方式有两种要么让提示词严格按模板输出要么在代码节点里同时兼容data和value两个字段。我更推荐后者因为模型偶尔会“发挥”兼容字段能降低返工概率。第三类HTML 能返回但页面空白。优先级最高的是检查浏览器开发者工具里的 Console 和 Network。如果看到echarts is not defined说明脚本没加载成功换成可访问的 CDN 或本地静态资源。如果看到Cannot read properties of undefined说明数据里可能没有value字段回代码节点加默认值。第四类中文乱码或显示异常。常见原因是json.dumps没加ensure_asciiFalse或者 HTML 页面编码不是 UTF-8。Dify 工作流生成的内容一般以 UTF-8 处理但如果你在脚本里手动拼接字符串还是要注意编码问题。7.2 推荐的排查顺序遇到问题不要一上来就怀疑模型能力也不要马上改提示词。按下面的顺序来看用户输入的数据本身。文件后缀、列名、编码、空值、特殊字符先清理干净。看 LLM 节点原始输出。原样复制出来用本地 Python 或 json 工具判断是否可以解析。看代码节点是否报错。报错信息里有变量名和行号能直接定位是解析失败还是字段不对。看 WebApp 浏览器控制台。重点看脚本资源是否加载、页面是否有 JS 报错。最后再调模型参数和提示词。很多时候模型没错是前面的数据和字段没对齐。这个顺序能省很多时间。我见过不少人在第 2 步就能发现问题却跑到第 5 步去改提示词反复试了很多次也没解决最后回头一看原始数据列名和模型模板里的字段名根本不匹配。8. 往生产环境去批量数据、权限和成本控制8.1 批量生成多个饼图时不要复用同一份 HTML如果需求从“一个饼图”变成“每个部门一张饼图”很多人会想着让代码节点循环生成多个图表。这种做法不是不行但要注意一块页面里多个 ECharts 实例需要不同的divid否则后一个图表会把前一个覆盖掉。代码示例里只处理了一个chart如果你要生成多个可以在 HTML 里用循环拼接charts_html [] for idx, item in enumerate(items): chart_div fdiv idchart_{idx} stylewidth:100%;height:400px;/div charts_html.append(chart_div)然后用document.getElementById(chart_0)、document.getElementById(chart_1)分别初始化。这属于扩展逻辑代码节点里把它写好后面用户一次性提交多个数据组时就能直接用。更稳妥的做法是单个工作流先做“生成一个饼图”批量需求放到外层调用方来处理。比如用 API 方式调用 Dify 应用循环发送多个请求每个请求生成独立 HTML再由上层应用组合展示。这样每个应用实例的职责更清晰也更容易定位问题。8.2 权限、安全与成本如果应用只给内部 20 个人使用安全压力不大。但如果要发布给外部客户或者计划做公开演示就必须认真处理 HTML 注入问题。用户输入的数据如果包含script标签被代码节点原样拼进 HTML就可能被浏览器执行。代码节点里对所有用户可控字段做 HTML 转义是底线配置不能跳过。成本方面ECharts HTML 方案里的脚本内容是固定的但每次模型生成的 JSON 都要调用一次 LLM。如果用户频繁请求token 成本会累积。优化方向是让 LLM 只负责“把不规整输入整理成 JSON”代码节点固定渲染。不要让 LLM 每次都输出一整段完整 HTML那样 token 消耗大、速度慢而且容易超出输出长度限制。更进一步如果用户数据已经很规整可以直接跳过 LLM 节点用代码节点解析 CSV 或 JSON 后直接生成 HTML。这样“一键生成饼状图”就变成了纯规则处理速度更快成本几乎为零。LLM 的价值只在需要理解自然语言时才体现数据格式稳定时不要为了用 AI 而用 AI。8.3 最后的落地建议如果你打算在 Dify 里做饼状图应用我更建议按照这个顺序推进先单条数据跑通再固定样式最后接批量或接口。整个过程里最该盯住的是三个位置LLM 输出的 JSON 是否规范、代码节点的字段名是否匹配、WebApp 能否加载 ECharts 脚本。把这三条链路验证清楚所谓“一键生成饼状图”才算真正立住。真正踩过几轮之后你会发现卡住你的往往不是大模型能力而是数据格式和变量名。先处理好这两件事剩下的只是把已有能力串起来。

相关新闻

最新新闻

家长纠结孩子学不学编程?先分清计算机的三个方向再决定

家长纠结孩子学不学编程?先分清计算机的三个方向再决定

家长眼里的计算机,往往是一道被省略号悬在半空中的判断题:要么是“以后好找工作”的高薪捷径,要么是“伤眼睛、打游戏、坐不住”的成长隐患,两边都站不太稳。我自己做过几年开发,也带过不少新手和学生,跟家…

2026/8/30 6:48:05
为什么我劝你自己写一个量化回测框架

为什么我劝你自己写一个量化回测框架

1. 为什么我劝你自己写一个回测框架做了几年量化交易,从最早啥都用现成框架,到后面慢慢被逼着开始自己写回测引擎,这个过程其实挺值得聊聊。好多人一听"自定义量化回测框架"就觉得没必要,觉得市面上backtrader、zipline…

2026/8/30 6:48:05
前端八股文备考指南:大厂与银行高频考点全解析

前端八股文备考指南:大厂与银行高频考点全解析

直接开聊。你如果正在准备大厂或者银行的前端面试,每天都蹲在各种博客里刷前端面试题,那我告诉你,这篇就是为你准备的。前端八股文这东西,被很多人诟病为“死记硬背”,但换个角度想,它其实是面试官在有限时…

2026/8/30 6:48:05
大模型幻觉的检测与缓解:从原理到工程实践

大模型幻觉的检测与缓解:从原理到工程实践

之前在做一个 AI Agent 项目时,我遇到过一个很典型的问题:模型会在回答里煞有介事地引用一篇不存在的论文,不仅作者、年份齐全,连期刊卷号都编得有模有样。后来在 Show HN 上看到一句话:Life Of AI – I hallucinate. …

2026/8/30 6:48:05
Transformer核心:多头注意力机制原理与PyTorch实现

Transformer核心:多头注意力机制原理与PyTorch实现

这次我们来看 Transformers 里最核心,也最容易在阅读源码时绕晕的一个模块:多头注意力。它属于 Transformer 章节 7.1.2 的内容,前接 7.1 注意力机制基础,后面直接通向 BERT、GPT、ViT 这些实际模型。很多同学在看结构图时觉得 Q、…

2026/8/30 6:48:05
STM32 STOP模式唤醒后GPS冷启动问题排查与修复实践

STM32 STOP模式唤醒后GPS冷启动问题排查与修复实践

直接说结论:这个现象我遇到过不止一次。板上STM32进入STOP模式低功耗待机,唤醒后GPS模块要么长时间无法定位,要么干脆连NMEA数据都不往外吐,每次都像刚上电一样重新搜星。问题表面看是“GPS module fails to cold-boot / re-acqui…

2026/8/30 6:43:05