ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Dify 中级实验(04):迭代进阶——如何批量处理数据并守住性能边界?

Dify 中级实验(04):迭代进阶——如何批量处理数据并守住性能边界?

Dify 中级实验(04):迭代进阶——如何批量处理数据并守住性能边界?

Dify 实验系列 · 中级 04/20 | 实验编号:DIFY-102-05

上篇:Dify 中级实验(03):模板转换实战——如何用零 Token 完成文本加工?

1. 实验目的

掌握Iteration(迭代)节点的高阶用法:嵌套迭代、逐条质量过滤、条件分流、输出结构设计,以及性能边界——迭代不是无限的,30 个元素上限、10 分钟超时、并行数限制,都是真实约束。

适合场景:批量取数、逐条审核、分页采集、批处理流水线——任何「拿到一个数组,逐条处理」的需求。

2. 场景设计

从多个数据源拉取客户反馈,每个源返回多条评论,需要:

  1. 外层迭代遍历数据源列表(3 个源);
  2. 内层迭代对每个源的评论逐条做质量过滤(内容过短、纯标点、重复字符判为低质);
  3. 只有质量合格的评论才送 LLM 做情感分析;
  4. 最终汇总「扫描总数 / 有效数 / 拦截数」。

输入(sources,JSON 数组,每项含 name/url/limit):

[{"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. 节点拓扑

开始(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 开始节点变量

variables:-label:数据源配置(JSON 数组,每项含 name/url/limit)required:truetype:paragraph# 长 JSON 粘贴,paragraph 而非 text-inputvariable:sources

4.2 外层迭代容器

迭代输入数组有30 个元素上限,解析节点先截断留余量:

defmain(sources_text:str)->dict:importjsontry:data=json.loads(sources_textor"[]")ifnotisinstance(data,list):data=[]exceptException:data=[]data=data[:20]# 迭代上限 30,提前截断return{"source_items":data,"total":len(data)}

外层迭代容器配置(节选):

-data:error_handle_mode:terminatedis_parallel:falseiterator_selector:[cd_parse,source_items]output_selector:[iter_reviews,output]# 内层迭代的输出output_type:array[string]parallel_nums:10start_node_id:itstart0title:外层迭代:遍历数据源type:iterationid:iter_sources

4.3 质量过滤(Code)

低质判定逻辑输出quality_ok——注意布尔值展平为字符串:变量选择器看不到 boolean 类型,下游 if-else 也只用字符串比较:

defmain(review:dict)->dict:importre review=reviewor{}content=str(review.get("content","")or"")quality_issues=[]iflen(content)<3:quality_issues.append("内容过短")ifre.match(r"^[!!.。??,,。]+$",content):quality_issues.append("无实质内容")iflen(set(content))<=2andlen(content)>1:quality_issues.append("疑似垃圾评论")return{"quality_ok":"true"iflen(quality_issues)==0else"false",# 字符串,不是布尔"quality_issues":quality_issues,...}

4.4 内层分支与 LLM

IF-ELSE 用is比较字符串(不能用=):

cases:-case_id:case_okconditions:-comparison_operator:isvalue:"true"variable_selector:[cd_quality,quality_ok]logical_operator:and-case_id:case_badconditions:-comparison_operator:isvalue:"false"variable_selector:[cd_quality,quality_ok]logical_operator:and

迭代内 LLM 引用当前元素用{{#iter_reviews.item.字段#}},且必须显式reasoning_format: separated——否则思考过程混入 text,整个迭代输出数组都被污染:

prompt_template:-id:p_analyzerole:systemtext:|分析以下用户评价: 平台:{{#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 选 array[object]迭代输出为空数组,下游取不到内部代码节点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):并行执行——如何让多路任务同时跑?

返回列表