Dify 中级实验(04):迭代进阶------如何批量处理数据并守住性能边界?
Dify 实验系列 · 中级 04/20 | 实验编号:DIFY-102-05
1. 实验目的
掌握 Iteration(迭代) 节点的高阶用法:嵌套迭代、逐条质量过滤、条件分流、输出结构设计,以及性能边界------迭代不是无限的,30 个元素上限、10 分钟超时、并行数限制,都是真实约束。
适合场景:批量取数、逐条审核、分页采集、批处理流水线------任何「拿到一个数组,逐条处理」的需求。
2. 场景设计
从多个数据源拉取客户反馈,每个源返回多条评论,需要:
- 外层迭代遍历数据源列表(3 个源);
- 内层迭代对每个源的评论逐条做质量过滤(内容过短、纯标点、重复字符判为低质);
- 只有质量合格的评论才送 LLM 做情感分析;
- 最终汇总「扫描总数 / 有效数 / 拦截数」。
输入(sources,JSON 数组,每项含 name/url/limit):
json
[
{"name": "App Store", "url": "https://api.example.com/reviews/app", "limit": 3},
{"name": "Google Play", "url": "https://api.example.com/reviews/android", "limit": 2},
{"name": "官方论坛", "url": "https://api.example.com/reviews/forum", "limit": 4}
]
输出:总扫描 9 条、有效分析 N 条、被拦截 M 条 + 各源明细。
3. 节点拓扑
text
开始(sources:JSON)
↓
解析数据源配置(Code:json.loads + 截断 [:20])
↓
外层迭代:遍历数据源(iter_sources)
├─ 模拟获取数据源评论(Code:按 limit 生成 mock + 0.2s 延迟)
│ ↓
│ 内层迭代:逐条质量过滤与分析(iter_reviews)
│ ├─ 质量过滤(Code:quality_ok 判定)
│ │ ↓
│ │ 质量合格判断(IF-ELSE)
│ │ ├─ case_ok → 情感分析(LLM)→ 汇聚分析结果(Code)
│ │ └─ case_bad → 汇聚分析结果(Code)
↓
汇总统计(Code)→ 结束
4. 关键配置
4.1 开始节点变量
yaml
variables:
- label: 数据源配置(JSON 数组,每项含 name/url/limit)
required: true
type: paragraph # 长 JSON 粘贴,paragraph 而非 text-input
variable: sources
4.2 外层迭代容器
迭代输入数组有 30 个元素上限,解析节点先截断留余量:
python
def main(sources_text: str) -> dict:
import json
try:
data = json.loads(sources_text or "[]")
if not isinstance(data, list):
data = []
except Exception:
data = []
data = data[:20] # 迭代上限 30,提前截断
return {"source_items": data, "total": len(data)}
外层迭代容器配置(节选):
yaml
- data:
error_handle_mode: terminated
is_parallel: false
iterator_selector: [cd_parse, source_items]
output_selector: [iter_reviews, output] # 内层迭代的输出
output_type: array[string]
parallel_nums: 10
start_node_id: itstart0
title: 外层迭代:遍历数据源
type: iteration
id: iter_sources
4.3 质量过滤(Code)
低质判定逻辑输出 quality_ok------注意布尔值展平为字符串:变量选择器看不到 boolean 类型,下游 if-else 也只用字符串比较:
python
def main(review: dict) -> dict:
import re
review = review or {}
content = str(review.get("content", "") or "")
quality_issues = []
if len(content) < 3:
quality_issues.append("内容过短")
if re.match(r"^[!!.。??,,。]+$", content):
quality_issues.append("无实质内容")
if len(set(content)) <= 2 and len(content) > 1:
quality_issues.append("疑似垃圾评论")
return {
"quality_ok": "true" if len(quality_issues) == 0 else "false", # 字符串,不是布尔
"quality_issues": quality_issues,
...
}
4.4 内层分支与 LLM
IF-ELSE 用 is 比较字符串(不能用 =):
yaml
cases:
- case_id: case_ok
conditions:
- comparison_operator: is
value: "true"
variable_selector: [cd_quality, quality_ok]
logical_operator: and
- case_id: case_bad
conditions:
- comparison_operator: is
value: "false"
variable_selector: [cd_quality, quality_ok]
logical_operator: and
迭代内 LLM 引用当前元素用 {``{#iter_reviews.item.字段#}},且必须显式 reasoning_format: separated------否则思考过程混入 text,整个迭代输出数组都被污染:
yaml
prompt_template:
- id: p_analyze
role: system
text: |
分析以下用户评价:
平台:{{#iter_reviews.item.platform#}}
用户:{{#iter_reviews.item.user#}}
评分:{{#iter_reviews.item.rating#}}/5
评价内容:{{#iter_reviews.item.content#}}
输出分析结论(50字以内):
1. 情感倾向(正面/中性/负面)
2. 核心关注点
3. 可采取的行动建议
reasoning_format: separated
5. 运行验证
输入上方 sources 测试数据,观察:
| 检查项 | 预期 | 实测 |
|---|---|---|
| 外层迭代次数 | 3(3 个数据源) | 3 |
| 内层迭代总次数 | 9(3+2+4) | 9 |
| 质量过滤拦截 | 低质评论被拦,不走 LLM | 与预期一致 |
| 汇总输出 | 扫描 9 条 / 有效 N 条 / 拦截 M 条 | 与预期一致 |
进阶对比:把外层迭代 is_parallel 打开(并行数 3)再跑一次,对比串行/并行耗时------本实验 mock 延迟 0.2s,数据量小看不出差距,数据量大了差异明显。
6. 采坑点
| 坑 | 现象 | 修复 |
|---|---|---|
| 迭代输入数组超 30 个 | 运行报 then length of var "item" must be less than 30 elements |
上游代码节点 data[:20] 提前截断留余量 |
| output_selector 选 arrayobject | 迭代输出为空数组,下游取不到 | 内部代码节点 json.dumps 序列化为 string,output_type: array[string] |
| 布尔输出给下游判断 | 变量选择器看不到 boolean,取不到值 | 输出 "true"/"false" 字符串,if-else 用 is 比较 |
| 嵌套迭代内部节点 parentId 写错层级 | 校验报「parentId=None 不是 iteration 节点」 | parentId 是节点外层字段(与 id 同级),不是 data 内 |
| 迭代内 LLM 缺 reasoning_format | 思考过程混入 text,判断逻辑全乱 | 显式 reasoning_format: separated |
💡 嵌套迭代格式本身能通过校验,但 Dify 运行层对「迭代套迭代」支持有限------如果你的场景不需要逐源再逐条的两级结构,优先用「串联迭代 + 展平代码节点」更稳。
7. 实验文档及源码获取
- 实验文档 (完整操作步骤):DIFY-05:迭代进阶------批量处理的边界与陷阱.md
- 源码 (可直接导入):dify102_05_批量反馈分析器.yml
文章聚焦核心配置与采坑点;实验的完整分步操作(节点搭建/参数表/调试指引)见实验文档原文。
下一篇:Dify 中级实验(05):并行执行------如何让多路任务同时跑?