Dify 高级实验(06):自动化报告——如何让系统定时自动生成周报?
Dify 高级实验(06):自动化报告——如何让系统定时自动生成周报?
Dify 实验系列 · 高级 06/10 | 实验编号:DIFY-103-06
1. 实验目的
掌握自动化报告流水线的完整链路:并行数据采集 → 变量聚合 → 指标计算与异常检测 → LLM 分析结论 → 模板转换生成报告 → Webhook 推送。核心能力:
- 三路并行采集:销售/客服/用户数据互不依赖,同时拉取(实验用 Code 模拟,真实场景换 HTTP 节点);
- 变量聚合(variable-aggregator):把多分支输出确定性合并,替代手写代码拼接;
- 模板转换双格式:同一个 Template Transform 按
output_format输出 Markdown 或 JSON; - 可开关推送:
push_enabled布尔开关控制是否推送到企业微信/飞书机器人。
适合:运营周报/日报、经营分析、定时报表自动化。前置要求:中级实验 03 模板转换、05 并行执行、06 变量聚合。
2. 场景设计
每周一早上要出上周运营周报,涉及销售、客服、用户三个维度。原来数据分析师要花半天,现在一键全自动:拉数据 → 算环比 → 检测异常 → 生成报告 → 推送。
输入:report_week(报告周次,默认「上周」)、output_format(markdown/json 下拉)、push_enabled(checkbox 推送开关,演示时关掉)。
输出:完整周报(核心指标 + 趋势分析 + 异常预警),可选推送到企业微信机器人。
3. 节点拓扑
开始(report_week / output_format / push_enabled)
├─ 销售数据采集(Code)────┐
├─ 客服数据采集(Code)────┼→ 变量聚合(合并三路 JSON)
└─ 用户数据采集(Code)────┘
→ Code 指标计算与异常检测(环比/满意度/活跃用户 + anomalies)
→ LLM 分析结论(300 字以内,直接输出正文)
→ 模板转换(Markdown/JSON 双格式报告)
→ Code Webhook 推送(模拟 HTTP 200)
→ 结束
4. 关键配置
4.1 三路采集(cd_sales / cd_customer / cd_support)
每个采集节点同时输出两份:object 结构数据(sales)给下游代码节点与模板消费,json 字符串(sales_json)给变量聚合器合并:
def main():
return {
"sales": {"current": {"total_revenue": 1285000, "total_orders": 342, "avg_order": 3757},
"previous": {"total_revenue": 1150000, "total_orders": 310, "avg_order": 3709},
"daily": [{"date": "周一", "revenue": 185000, "orders": 48}]},
"sales_json": '{"current": {...}, "previous": {...}}' # json.dumps 序列化
}
4.2 变量聚合(va_merge)
variables 是 [[节点id, 字段], ...] 嵌套数组格式,output_type: string:
- data:
output_type: string
title: 变量聚合(合并数据)
type: variable-aggregator
variables:
- [cd_sales, sales_json]
- [cd_customer, customer_json]
- [cd_support, support_json]
4.3 指标计算与异常检测(cd_analyze)
环比计算必须除零保护;has_anomaly 展平为字符串(boolean 在变量选择器不可见):
def main(sales, customer, support):
issues = []
sales = sales or {}; customer = customer or {}; support = support or {}
cur = sales.get("current") or {}; prev = sales.get("previous") or {}
prev_rev = prev.get("total_revenue") or 0
rev_change = (cur.get("total_revenue", 0) - prev_rev) / prev_rev * 100 if prev_rev else 0
if rev_change < -10:
issues.append(f"营收环比下降 {abs(rev_change):.1f}%,需关注")
# 客服满意度 < 4.0、活跃用户环比 < -5% 同理检测……
return {"revenue_change_pct": round(rev_change, 1), "anomalies": issues,
"has_anomaly": "true" if issues else "false", "summary": "...", "analysis": {...}}
4.4 分析结论 LLM(lm_analysis)
你是一个运营数据分析师。根据以下本周({{#start.report_week#}})运营数据,生成中文分析结论。
核心指标摘要:{{#cd_analyze.summary#}}
环比变化:营收 {{#cd_analyze.revenue_change_pct#}}%,客服工单 {{#cd_analyze.ticket_change_pct#}}%,活跃用户 {{#cd_analyze.user_change_pct#}}%
异常项列表:{{#cd_analyze.anomalies#}}
要求:
1. 分析营收、订单、客服、用户四个维度的环比变化趋势
2. 指出异常项(如有)
3. 给出 2-3 条可执行的行动建议
4. 控制在 300 字以内
5. 直接输出正文,不要输出任何解释性文字
4.5 模板转换(tmpl_report)
模板开头一组 {% set %} 做空值保护,计算处全部 if prev else 0 除零保护;所有输入走 variables 映射,模板内用 {{ var }} 引用:
{% set s = sales if sales else {} %}
{% set cur = s.current if s.current else {} %}
{% set prev = s.previous if s.previous else {} %}
{% set issues = analysis.anomalies if analysis and analysis.anomalies else [] %}
{% set rev_pct = analysis.revenue_change_pct if analysis and analysis.revenue_change_pct is defined else 0 %}
{% if output_format == 'json' %}
{ "report_week": "{{ report_week }}", "revenue": {{ cur.total_revenue | default(0) }},
"anomalies": [{% for issue in issues %}"{{ issue }}"{% if not loop.last %}, {% endif %}{% endfor %}] }
{% else %}
# 运营周报({{ report_week }})
## 核心指标
- 营收:¥{{ cur.total_revenue | default(0) }}(环比 {{ rev_pct }}%)
- 订单:{{ cur.total_orders | default(0) }} 单
## 趋势分析
{{ llm_analysis }}
## 异常预警
{% if issues | length > 0 %}{% for issue in issues %}- ⚠️ {{ issue }}{% endfor %}
{% else %}- 无异常,各项指标正常 ✅{% endif %}
{% endif %}
4.6 推送(cd_push)
push_enabled 为 true 时模拟调用企业微信机器人(真实场景换 http-request 节点,URL 指向机器人 Webhook)。
5. 运行验证
| 输入 | 期望行为 | 实测 |
|---|---|---|
| report_week=上周,output_format=markdown,push_enabled=关 | 输出完整 Markdown 周报(核心指标/趋势分析/异常预警三节) | 与预期一致 |
| output_format=json | 输出 JSON 结构报告(report_week/revenue/anomalies/analysis 字段) | 与预期一致 |
| push_enabled=开 | push_status = 已推送到企业微信机器人(模拟 Webhook 调用成功,HTTP 200) | 与预期一致 |
| 三路数据置空(冒烟测试) | 模板空值保护生效,输出空报告而不是运行报错 | 与预期一致({% set %} 兜底) |
6. 采坑点
| 坑 | 现象 | 修复 |
|---|---|---|
| 模板变量为 null/空时直接计算 | {{ x | length }}、x | map(...) | sum / (x | length) 运行报错(0/0 除零、None 切片),冒烟输入空数据直接崩溃 |
模板开头 {% set %} 兜底默认值 + 计算处 (sum / length) if (length) > 0 else 0(dify102 全量验证实测) |
长报告 text 返回空字符串 |
DeepSeek 把内容写进思考部分,或思考与输出共享 max_tokens 预算被挤空 | 报告类节点 max_tokens 提到 4000-8000 + prompt 明确「直接输出正文,不要输出任何解释性文字」(dify103_09 lm_format 实测) |
has_anomaly 用 boolean 类型输出 |
下游 LLM 模板 {{#cd_analyze.has_anomaly#}} 取不到值(boolean 变量选择器不可见) |
代码输出 "true" if x else "false" 字符串,模板语义不变(2026-07-31 dify-103 实测) |
模板里直接写 {{#node.field#}} 引用 code 的 object 字段 |
validate_dsl.py 模板正则扫描报错,或跨节点引用不可见字段 | 所有输入走 variables 映射(value_selector),模板内用 {{ var }} 引用(dify102-2 21 实证) |
7. 实验文档及源码获取
- 实验文档(完整操作步骤):DIFY-103-06:自动化报告生成.md
- 源码(可直接导入):dify103_06_自动化报告生成.yml
文章聚焦核心配置与采坑点;实验的完整分步操作(节点搭建/参数表/调试指引)见实验文档原文。
下一篇:Dify 高级实验(07):智能审批——如何让机器自动完成流程审批?
💬 你在这个实验的场景里踩过什么坑?欢迎评论区分享你的实战经验。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)