Dify 工作流搭建操作手册:以信息化运维周报自动生成为例
一、适用范围与前置准备
本手册面向需要基于 Dify 编排「定时取数 + 数据整理 + LLM 渲染 + 文档导出」类工作流的开发者,以一份运维周报自动生成工作流为完整示例。示例涉及多数据源(MySQL 业务库、内网 HTTP 接口)、多插件(数据库查询、文本替换、ECharts 渲染、Markdown 导出)以及本地大模型调用,可作为搭建同类应用的通用参考。
开始搭建前,需确认以下前置条件已就绪:
1. Dify 环境:已部署并可通过浏览器访问 Dify 控制台,具备应用编排权限。本文基于高级对话(advanced-chat)模式应用编写。
2. 插件市场可用:需能从插件市场安装以下插件,对应文件中的依赖声明:
junjiem/db_query:数据库 SQL 查询工具(支持 MySQL/Oracle/PostgreSQL/MSSQL);
yizixuan/text_tools:文本查找与替换工具;
bowenliang123/md_exporter:Markdown 转 DOCX 文档;
hangboss1761/echarts_convert:将 ECharts 配置渲染为 SVG 图片;
langgenius/ollama:本地 Ollama 模型接入(示例使用 `deepseek-r1:8b`)。
3. 数据源可达:目标 MySQL 库、内网变更单接口均能从 Dify 所在网络访问。
4. 大模型可用:Ollama 已部署且模型已下载;若改用云端模型(如 `deepseek-chat`),在 LLM 节点中替换模型供应商即可,流程不变。
二、整体规划:先画数据流,再排节点
建议在动手前先明确数据流。本工作流的完整链路为:
用户输入 → 获取当前时间 → 计算时间范围 → 条件分支(判断是否为“本周”)
├─ 否 → 直接回复占位文案
└─ 是 → 并行数据采集(本周/上周/本月事件、定修、点检、故障、年度故障、变更单)
→ 各数据整理代码节点 → 统计分类与图表配置代码节点
→ LLM 文本渲染(对话路径 / 文档路径,两条路径并行)
→ 图表转图片 → 占位符替换插入图片 → Markdown 转 DOCX
→ 回答节点输出
规划时遵循以下原则:
先计算、后取数:所有数据库查询的时间参数由上游代码节点统一计算,避免在每条 SQL 中各自写死时间逻辑;
并行采集:相互独立的数据源(事件、定修、点检、故障、变更)之间无依赖关系,在画布上从同一代码节点引出多条连线即可并行执行;
整理与展示分离:SQL/接口返回的原始结果先由代码节点整理为统一结构,再交给 LLM,降低模型对脏数据的敏感度;
双路径渲染:对话展示与文档导出各自走一条 LLM 渲染链路,最终合并输出,便于分别定制模板。
三、分步搭建
3.1 创建应用并配置基本信息
1. 在控制台新建「高级对话」类型应用,命名为 `flow`(与 DSL 中 `name: flow` 对应)。
2. 配置应用的基础属性:`mode` 为 `advanced-chat`,`version` 保持默认(示例为 `0.5.0`),并设置图标与主题色。
3. 配置「功能」模块:
开场白:填写应用的默认问候语,示例为「您好!我是……运维天天报自动生成助手」;
推荐问题:添加「生成信息化本周周报 / 生成信息化本月月报 / 生成信息化本年年报」等快捷提问;
如需接收图片等附件,在「文件上传」中按需开启,并设置扩展名白名单与大小限制(示例限制单文件 10MB、批量 5 个)。
3.2 配置环境变量(数据库连接信息)
环境变量用于集中管理敏感配置,避免在每条 SQL 中重复填写。在编排界面左侧「环境变量」中新增:
| 变量名 | 类型 | 说明 |
| --- | --- | --- |
| `MySql_HOST` | string | 数据库地址 |
| `MySql_PORT` | integer | 端口 |
| `MySql_DATABASE` | string | 库名 |
| `MySql_USER` | string | 只读账号 |
| `MySql_PASSWORD` | string | 口令 |
安全注意事项:示例 DSL 中口令以明文存储,这仅适合内部演示环境。生产环境应改为由密钥管理服务注入,或至少对导出文件严格管控、定期轮换口令。
3.3 开始节点与条件分支
1开始节点:默认接收用户输入,无需额外配置。
2. 条件分支节点:配置一个条件——`系统变量 sys.query 包含「本周」`。该节点将输入路由为两条路径:
true分支进入完整报告生成链路;
false 分支连接「直接回复」节点,输出「目前正在开发」占位文案。
3. 客观提示:示例应用在开场白中承诺周报/月报/年报三类输出,但条件分支仅实现了「本周」判断,月报、年报实际落到占位回复。若要完整支持三类报告,应扩展为多分支(if-else 多 case)或引入 LLM 意图分类,再分别路由。
3.4 时间获取工具节点
1. 添加「工具」节点,选择内置 `time` 工具的 `current_time` 方法。
2. 配置参数:
format:`%Y-%m-%d `(输出日期字符串);
timezone:应选 `Asia/Shanghai`**。示例配置误用了 `UTC`,在东八区每日 0:00–8:00 期间获取到的「今天」会偏移到前一日,导致报告日期与统计区间整体错位一天。这是示例中一个实际存在的缺陷,请勿照抄。
3.5 时间范围计算代码节点
该节点是整个工作流的时间基准,承担「把用户一句『本周』翻译成具体日期区间」的职责。
1. 添加「代码」节点,语言选择 `python3`。
2. 配置输入变量 `time`,其值选择器引用时间工具节点的输出(`text` 字段)。
3. 代码逻辑要点:
兼容 `%Y.%m.%d`、`%Y-%m-%d`、`%Y年%m月%d日` 等常见日期格式解析;
解析失败时回退到 `datetime.now()`;
计算并输出八项:`today`、`curr_week_start`、`curr_week_end`、`last_week_start`、`last_week_end`、`month_start`、`month_end`、`year_start`。
4. 在「输出变量」中为上述字段声明类型(示例全部为 `string`),供后续节点引用。
3.6 多源数据采集:数据库查询工具节点
对每个数据源分别添加一个 `db_query` 工具的 `sql_query` 节点。以「事件(本周)」为例:
1. 在工具节点中填入连接参数,全部引用环境变量:
db_type:`mysql`(常量);
db_host:`{{#env.MySql_HOST#}}`;
db_port:选择器引用 `env.MySql_PORT`;
db_username/ db_password / db_name:对应引用环境变量。
2. 编写 query_sql,其中日期参数引用时间计算节点的输出:
- 例:AND createtime >= '{{#时间节点ID.curr_week_start#}}00:00:00'`;
- 例:AND createtime <= '{{#时间节点ID.curr_week_end#}}23:59:59'`。
3. 设置 output_format为 markdown(后续代码节点按 Markdown 表格解析)。
4. 同一业务的不同周期(本周/上周/本月)可复制节点后仅替换 SQL 中的时间字段与标题。
示例中事件表对 `tdcyw0010`、`tdcyw0015` 做 UNION 合并,并按部门、系统名、标题关键字过滤;定修、点检、故障表各有独立 SQL 与过滤条件。编写 SQL 时注意:**日期参数统一来自上游代码节点**,不要自行拼接用户输入,以降低注入风险。
3.7 变更单数据采集:网页爬取工具节点
对 HTTP 接口类数据源,使用内置 `webscraper` 的 `webscraper` 方法:
1. 配置 `url`:`http://内网地址/api/changeOrder/query?startTime={{#时间节点ID.curr_week_start#}}&endTime={{#时间节点ID.today#}}`;
2. `generate_summary` 设为 `false`(取原始内容);
3. `user_agent` 使用浏览器 UA。
客观提示:示例将内网 IP 硬编码在 URL 中,服务不可达时该节点直接失败且无降级分支。建议增加失败兜底(如用代码节点捕获空结果并输出空表)。
3.8 数据整理代码节点
每个采集节点后跟一个代码节点,将 Markdown/JSON 原始输出整理为统一结构。以「事件数据整理」为例:
1. 输入变量 `week_sql_result`、`last_week_sql_result`、`month_sql_result`,选择器分别引用三个事件查询节点的 `text` 输出。
2. 代码逻辑:
解析 Markdown 表格:逐行拆分 `|` 分隔符,识别表头与数据行,过滤分隔行;
计算 `week_event_count`、`last_week_event_count`;
将记录序列化为 JSON 字符串,输出 `week_event_list`、`month_event_list`。
3. 兜底策略:任何解析异常均返回计数 0 与空 JSON `"[]"`,确保下游不中断。这是示例中值得沿用的设计——所有整理节点(定修、点检、故障、变更)都实现了「空数据 → 输出空表 + 兜底文案」的分支。
3.9 统计分类与图表配置代码节点
该层把整理后的数据进一步加工为报告所需的统计文本与图表配置:
1. 数据分类节点:按关键词将事件归入「桌面系统 / L3 生产系统 / 其他业务系统」及「炼铁 / 炼钢 / 热轧 / 厚板 / 冷轧 / 生产运行中心 / 指中 / 外协」等类别,计算数量与占比(保留两位小数),输出自然语言统计结果。
2.统计表节点:按当前月自然周切分,将事件按「服务请求 / 故障报修 / 预防维护 / 其他事件」统计为 Markdown 周度表,并按 ±20% 阈值标记各周是否处于正常范围。
3. 统计折线图节点**:解析周度统计表,生成 ECharts 折线图配置,输出为 ```echarts``` 代码块。
4. 系统事件复合图节点:解析分类结果,生成「折线 + 饼图」复合图配置,同样输出 echarts 代码块。
图表节点统一以 `json.dumps(option, ensure_ascii=False, indent=2)` 序列化配置,并用 echarts``` 围栏包裹,这是后续渲染插件识别内容的约定格式。
3.10 LLM 文本生成节点
这是报告渲染的核心。以对话展示路径的 LLM 节点为例:
1. 选择模型:示例为 Ollama 的 `deepseek-r1:8b`。
2. 编写 System Prompt,示例的关键约束包括:
角色:运维周报撰写专家;
风格:专业客观、书面简洁工业公文风,禁止口语化;
零幻觉红线:所有数据必须 100% 来源于输入变量,禁止编造;
结构强制:严格保留输出模板的全部章节与表格,禁止删减;
占位符保留:`{tab_1}`、`{tab_2}` 两个标签必须原样保留(供后续文本替换插入图片);
计算口径:百分比保留两位小数,环比变化量/变化率公式明确,±20% 判定正常/异常;
兜底文案:数据缺失时使用固定文案(如「本周系统整体运行平稳,无重大生产级故障」)。
3. 在正文模板中引用上游变量,引用语法为 `{{#节点ID.输出字段#}}`,例如:
(日期);
(本周事件量);
(故障明细表)。
4. 在模板对应位置放置 `{tab_1}`、`{tab_2}` 占位标签。
客观提示:8B 量级的本地模型对「模板原样保留、零幻觉」的强约束遵循度有限,可能出现漏替换占位符或改写模板。建议在输出后增加校验节点(检查必填章节与标签是否残留),或在资源允许时使用更大规格模型。
3.11 图表转图片
对每条图表链路,添加 `echarts_convert` 工具节点:
1. `content`:引用对应图表代码节点的 `text` 输出;
2. `image_type`:`svg`;
3. `width` / `height`:按版面设置(示例为 850×500);
4. `concurrent_rendering`:简单图表设为 `1`。
该节点返回图片内容,供文本替换与文档导出使用。
3.12 占位符替换:插入图片
使用 `text_tools` 插件的 `text_replace` 方法,将 LLM 输出中的占位标签替换为图片:
1. 统计图插入:
input_text:引用文档路径 LLM 节点输出;
search_text:`{tab_1}`;
replace_text:引用统计折线图转图片节点输出;
use_regex:`true`,`regex_dotall`:`true`(让 `.` 匹配换行,保证图片内容完整匹配)。
2. 事件图插入:同样方式处理 `{tab_2}`,替换为复合图转图片节点输出。
该「占位符 + 文本替换」机制将 LLM 文本生成与图片插入解耦,是示例中最具复用价值的模式。
3.13 Markdown 转 DOCX 与回答输出
1. Markdown ⮕ DOCX 节点(`md_exporter`):
md_text:引用占位符替换完成后的文本节点输出;
output_filename:自定义文件名,示例为 `宝钢湛江钢铁有限公司_信息化系统运维周报_{{#时间节点ID.today#}}`;
可选传入 DOCX 模板文件以控制样式。
2. 直接回复节点:拼接对话路径的 LLM 文本与文档附件,例如 `{{#对话LLM节点.text#}} {{#DOCX节点.files#}}`,将文本与 Word 文档一并返回用户。
四、节点连线与执行顺序
在画布上按依赖关系连线,Dify 会依据连线自动推导执行顺序,同层无依赖节点并行执行。本工作流的连线要点:
开始节点 → 时间工具 → 时间计算代码节点 → 条件分支;
条件分支 true → 时间计算代码节点(作为并行采集的源头),由它分别连到各查询工具节点;
各查询工具节点 → 对应的整理代码节点;
整理节点 → 统计/分类/图表节点;
两类图表与统计结果 → 两条 LLM 渲染链路;
文档链路:LLM → 图表转图片 → 两次文本替换(串联)→ DOCX → 回答节点;
对话链路:LLM → 回答节点。
连线时注意:文本替换的两个节点有先后依赖(先替换 `{tab_1}` 再替换 `{tab_2}`),必须串联而非并联,否则占位符可能残留。
五、测试与调试要点
1. 分节点验证:先单独运行时间计算代码节点,确认八个日期字段在目标时区下正确;再逐个验证 SQL 查询节点返回的表头与行数是否符合预期。
2. 检查变量引用:出现 `{{#...}}` 原样输出时,通常是节点 ID 或输出字段名拼写错误;可在节点参数区选择器中选择,避免手写。
3.校验占位符替换:确认最终文档中不存在残留的 `{tab_1}`、`{tab_2}`;若残留,检查 `regex_dotall` 是否开启、图片节点输出是否为空。
4.验证空数据路径:在无事件、无故障的日期运行一次,确认兜底文案与空表正常输出,整条链路不中断。
5. 回归测试多周期:分别以月初、月中、月末日期测试,验证月统计切周逻辑与「上周/本月」区间边界正确。
6. 导出 DSL 备份:搭建完成后导出应用 DSL(即 `.yml` 文件)作为版本备份与迁移依据;导出前确认未包含不应外泄的明文凭据。
六、常见问题与规避建议
| 问题 | 原因 | 规避建议 |
| --- | --- | --- |
| 报告日期错位一天 | 时间工具时区为 UTC | 改为 `Asia/Shanghai` |
| 月报/年报提示「开发中」 | 条件分支只判断了「本周」 | 扩展多 case 分支或引入意图分类 |
| 图表未插入、占位符残留 | 替换未启用 DOTALL 或替换顺序错误 | 开启 `regex_dotall`,串联执行两次替换 |
| SQL 节点报错 | 环境变量未配置或端口类型不符 | 核对变量名与类型(PORT 为 integer) |
| 导出文件含明文口令 | 凭据直接写入 DSL | 改用密钥管理,导出前脱敏 |
| LLM 改写模板结构 | 小模型对强约束遵循度有限 | 增加输出校验节点,或升级模型规格 |
七、小结
本手册以一个完整的高级对话工作流为例,覆盖了「时间计算 → 并行取数 → 代码整理 → 统计图表 → LLM 渲染 → 占位符图文合并 → DOCX 导出」的全过程,并给出了变量引用语法、连线顺序、测试方法与常见问题规避。需要客观指出的是:该示例在时区、凭据安全、分支能力与模型稳定性上存在明确短板,复刻时应优先补齐上述缺陷,并将业务表结构、接口地址、报告类型等参数化,才能形成可长期维护的通用方案。
更多推荐

所有评论(0)