Dify 中级实验(05):并行执行——如何让多路任务同时跑?

Dify 中级实验(05):并行执行------如何让多路任务同时跑?

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

1. 实验目的

掌握 并行分支(Parallel Branch) 的使用:从开始节点拉出多条独立路径同时执行,理解并行 vs 串行的权衡、分支间变量隔离规则,以及结果合并这一并行架构的真正瓶颈。

适合场景:一个综合问题需要多路取数(知识库 + API + 搜索)、多源信息汇总、互不依赖的子任务并发。

2. 场景设计

用户提出一个综合问题,需要同时从三个维度取数才能完整回答:

  • 分支 A:知识库检索产品技术文档 → 摘要;
  • 分支 B:库存/价格 API(模拟,0.5s 延迟);
  • 分支 C:互联网搜索市场动态(模拟,0.8s 延迟)。

串行总耗时 = 三步之和(约 1.3s+);并行总耗时 ≈ 最慢分支(约 0.8s)。最后 LLM 整合三路信息,带来源标注输出。

输入user_query(用户问题)、product_name(产品名称)。

3. 节点拓扑

text 复制代码
开始(user_query / product_name)
  ├─ 产品知识库检索(KB,top_k 5)→ 知识摘要(LLM)──┐
  ├─ 模拟价格库存 API(Code,0.5s)───────────────┼→ 整合情报(LLM)→ 结束
  └─ 模拟互联网搜索(Code,0.8s)─────────────────┘

三条线互不依赖,从开始节点直接拉出三路;唯一汇聚点是最后的 LLM。

4. 关键配置

4.1 知识库分支

yaml 复制代码
- data:
    dataset_ids:
    - 87e2a4af-3f5c-4fb4-8468-a42609c5834c   # 导入后替换为你的知识库 ID
    output_retrieval_result: true             # 必须 true,否则 result 为空
    query_variable_selector: [start, user_query]
    retrieval_mode: single
    top_k: 5
    title: 产品知识库检索
    type: knowledge-retrieval
  id: kb_retrieval

摘要 LLM 直接用三花括号引用检索结果------KB → LLM 用 {``{#kb_retrieval.result#}},context 保持 enabled: false

yaml 复制代码
prompt_template:
- id: p_summary
  role: system
  text: |
    根据以下产品文档信息,提取和问题相关的内容:
    问题:{{#start.user_query#}}
    文档:{{#kb_retrieval.result#}}
    格式要求:用 2-3 句话概括核心信息。如果文档中没有相关信息,说明"文档中未找到相关信息"。
reasoning_format: separated

4.2 模拟 API 与搜索分支

python 复制代码
# 分支 B:模拟价格库存 API(0.5s 延迟)
def main(product_name: str) -> dict:
    import time
    time.sleep(0.5)
    mock_data = {
        "产品A": {"price": 99.9, "stock": 500, "discount": "新品9折"},
        "产品B": {"price": 199.0, "stock": 23, "discount": "限时8折"},
        "产品C": {"price": 59.9, "stock": 0, "discount": "无"},
    }
    data = mock_data.get(product_name, {"price": "未知", "stock": "未知", "discount": "无"})
    status = "有货" if data.get("stock", 0) > 0 else "缺货"
    text = "产品:{};价格:{}元;库存:{};状态:{};优惠:{}".format(
        product_name or "未知", data.get("price"), data.get("stock"), status, data.get("discount"))
    return {"price_text": text}

4.3 合并 LLM

三路输出通过 variables 映射进 prompt,要求带来源标注:

yaml 复制代码
prompt_template:
- id: p_merge
  role: system
  text: |
    你是一个情报分析师。请整合以下三路信息,给用户一个全面、结构化的回答。
    用户问题:{{#start.user_query#}}
    ━━━ 来源 A:[知识库] 产品文档摘要 ━━━
    {{#lm_summary.text#}}
    ━━━ 来源 B:[库存API] 价格与库存信息 ━━━
    {{#cd_price.price_text#}}
    ━━━ 来源 C:[搜索] 市场动态 ━━━
    {{#cd_search.search_text#}}
    要求:
    1. 以「来源标注」标注每条信息的出处([知识库]/[库存API]/[搜索])
    2. 如果不同来源信息冲突,明确指出
    3. 最终给出综合建议
reasoning_format: separated

⚠️ prompt 里引用上游字段一律写 {``{#节点id.字段#}} 三花括号 ------{``{变量名}} 双花括号在 1.16 里不会被替换,会字面传给模型(实测踩坑,见第 6 节)。

5. 运行验证

输入 期望行为 实测
product: 产品A,query: 有什么优惠? 三路并行,合并回答带 知识库/库存API/搜索 标注 与预期一致
product: 产品C,query: 如何购买? 知识库有信息,但库存为 0,回答指出缺货 与预期一致

耗时对比:单分支串行约 1.3s,并行约 0.8s------并行收益 = 最慢分支耗时,而不是所有分支之和。打开执行日志,展开并行分支看每路独立耗时与交叉的日志流。

6. 采坑点

现象 修复
并行分支间互相引用变量 分支 B 想读分支 A 的中间结果,取不到 分支内变量互不可见,只能在下游汇聚节点消费各分支输出
prompt 用 {``{变量名}} 双花括号 LLM 收到字面占位符,回答「参考资料为空」 一律 {``{#节点id.字段#}} 三花括号(实测:同应用两个 LLM 对照验证)
KB 结果在 LLM 模板取不到 误以为必须开 context 模式 {``{#kb_retrieval.result#}} 直接引用 + context.enabled: false
并行日志交叉难读 多分支日志混在一起,定位问题慢 单次只调试一个分支,或把每个分支的摘要打印到输出
以为并行必然更快 CPU 密集型任务并行无收益,甚至更慢 并行只对 I/O 密集型(API/检索)有效;合并节点复杂度可能吃掉加速收益

💡 并行架构的设计顺序:先定汇聚点,再画分支。三条线最后都要在同一个 LLM/聚合节点汇合,分支越多,合并 prompt 的编排成本越高------这是并行方案真正的成本。

7. 实验文档及源码获取

文章聚焦核心配置与采坑点;实验的完整分步操作(节点搭建/参数表/调试指引)见实验文档原文。


下一篇:Dify 中级实验(06):变量聚合------如何确定性合并多路分支结果?

相关推荐
武子康1 小时前
SWE-1.7 的提升究竟来自哪里?接受大量强化学习后训练的 Kimi K2.7 为起点,继续进行大规模 RL
人工智能·llm·agent
布列瑟农的星空2 小时前
LoRA微调BERT模型实践
人工智能·agent
用户469368483202 小时前
kimi-code 深度掌握系列文章-工具系统:从注册到执行(六)
llm·agent
jsl_jsl_jsl2 小时前
claudecode学习 第 9 章 · Subagents
agent
lbzlbss2 小时前
AI 自动化测试流水线实战(二):Analyst 把 PRD 变 L0/L1 用例套件
agent
鱼日先生3 小时前
Dify 中级实验(04):迭代进阶——如何批量处理数据并守住性能边界?
agent·工作流·dify
circuitsosk3 小时前
不止于API调用:大模型推理加速与云原生服务化部署指南
python·云原生·agent·vllm·推理加速·大模型部署·ensorrt-llm
@Mr_LiuYang4 小时前
《深入理解 AI Agent:设计原理与工程实践 》实验1-2 深度搜索能力
人工智能·agent