Files
aiagent/docs/zhini-kefu/知你客服15号_循环工作流设计.md
renjianbo eabf90c496 feat: add AI学习助手 agent (KG+RAG ideal) and renshenguo feishu bot
- Add AI学习助手 agent creation script with all 39 tools, 3-layer KG+RAG memory
- Add renshenguo (人参果) feishu bot integration (app_service + ws_handler)
- Register renshenguo WS client in main.py startup
- Add RENSHENGUO_APP_ID / RENSHENGUO_APP_SECRET / RENSHENGUO_AGENT_ID config
- Reorganize docs from root into docs/ subdirectories
- Move startup scripts to scripts/startup/
- Various backend optimizations and tool improvements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-06 01:37:13 +08:00

7.2 KiB
Raw Permalink Blame History

知你客服 15 号 · Loop + 多轮 LLM 工作流设计(可落地版)

本文档说明如何在同一次 API 调用内,用 循环(loop/foreach)节点驱动「多轮」LLM 执行,并与现有 知你主线(Start → Cache → llm-unified → Cache → End)衔接;同时标明引擎行为边界与推荐降级方案。


1. 目标与两种能力层级

层级 做法 适用场景
A. 单节点多轮工具 在 llm-unified 的 data 中配置 max_tool_iterations(如 28),一次进入 LLM 节点内多轮 tool 调用 工具链较长、但不需要按「外部数组」拆成多次独立推理
B. 循环体多轮 LLM 在图中增加 loop,循环体里放 专用 LLM 子节点,对 items 数组每一项跑一遍模型(可带不同 loop_input) 需要「子任务列表 / 分步计划 / 固定 K 轮」等显式多段执行

15 号线已具备 A;若产品明确要求「画布上多次跑 LLM」,按 B 设计。


2. 与知你主线的衔接(推荐拓扑)

在不破坏原有缓存与记忆的前提下,典型插入方式为:

Start → Cache(读) → [准备循环数组] → Loop → [合并/写缓存] → End
                         ↑                    ↑
                    Transform/Code      循环体:LLM + 可选 Cache
  • 准备循环数组:用 Transform 或 Code 节点,在上游输出上增加一个 数组字段(见下节),供 loop 的 items_path 读取。
  • 合并:loop 的输出是数组;若 End 或下游 Cache 需要单条字符串回复,在 Loop 后增加 Transform,把数组折叠成 reply / right 等字段。

不要把原来的 llm-unified 同时当作「主答复」和「循环体里唯一 LLM」复用同一套 End 依赖,除非你已经用 Transform 明确产出最终 reply。


3. 驱动循环的数据:items_path 与数组形态

引擎从进入 loop 节点时的输入中,用 items_path(默认 items)取数组;若不是 list 会报错。

示例(简单 K 轮)
上游 Transform 产出:

{
  "query": "...",
  "loop_rounds": [1, 2, 3]
}

loop 节点配置:

  • items_path: loop_rounds
  • item_variable: round(则循环体内还有 round_index、round_total)

示例(子任务列表)
iteration_plan: [ {"id":"s1","desc":"..."}, ... ],items_path 填 iteration_plan,item_variable 填 step,提示词里用 {{step}} 或 {step} 引用(与现有 LLM 占位符规则一致)。


4. 循环体内:如何把「上一轮结果」带入下一轮

引擎行为(简化理解):

  • 每轮会构造 loop_input = { **原输入, item变量, item_index, item_total }。
  • 循环体内每执行一个节点,若输出为 dict,会 merge 进下一轮同轮内的 loop_input;非 dict 则写入 result 键。

因此:

  • 同轮内链式节点:后一节点能读到前一节点合并进 loop_input 的字段。
  • 轮与轮之间:下一轮会重新从原始 input_data 展开并覆盖 item;同轮内合并的字段不会自动跨轮保留,除非上游 Transform 把「需要跨轮的状态」写进不变的全局字段(例如仍来自 Start/Cache 的 memory),或在每轮依赖的数组项里自带「累计状态」。

若业务强依赖「第 N 轮必须读到第 N-1 轮 LLM 全文」,建议:

  • 在循环体末尾加 Code/Transform,把本轮产出写入结构化字段,并通过下一轮 item 内容(由上游数组生成)携带;或
  • 仍用 A 档(单节点 + max_tool_iterations) 在一轮推理里完成链式工具与总结。

5. 循环体拓扑与引擎限制(必读)

引擎对循环体实现为 简化版:

  1. 只走 loop 的第一条出边指向的单链,直到遇到 loop_end 或 end 类型节点停止。
  2. 不要在循环体内再嵌套复杂分支;多出口 loop 未覆盖的场景可能不符合预期。
  3. 错误处理:error_handling 为 continue 时失败轮次会往结果里塞 null;stop 则整段失败。

画布上需包含:loop → … → loop_end(或 end)的链,以满足「链尾」语义。


6. node_outputs、End 与「谁产出最终 reply」

主流程在跑完 loop 后,会把 loop 节点本身 的输出写入 node_outputs[loop节点id],值为 output: 每轮结果的数组(每轮取循环体最后一个节点的 output)。

重要:循环体内的 LLM 节点在引擎里会随 loop 被标记为已执行,但不会再走主线程里「每个节点写一次 node_outputs」的路径;因此依赖 _extract_reply_from_llm_node_outputs 等「扫描所有 LLM 节点输出」的逻辑,可能拿不到循环体内的那个 LLM。

推荐做法:

  • 把「给用户的一句话」放在 Loop 之后的 Transform 里,从 loop 输出数组 生成 reply / right;或
  • 让 End 的前驱只依赖 已合并好的单字段,而不是隐式依赖某个 llm-xxx 的 node_outputs。

7. 与「同一次 API 多次跑 LLM」的关系

  • Loop:同一请求内,对数组长度 N 次调用循环体(若体内含 LLM,即 N 次独立 execute_node LLM)。
  • max_tool_iterations:同一 LLM 节点一次调用 内的 tool 轮数,不是 N 次顶层 LLM。

二者可并存:例如 loop 两轮,每轮 LLM 再 max_tool_iterations=14,但总成本与延迟会明显上升,需在运营侧限制 items 长度与并发策略(若后续引擎支持)。


8. 最小示意(节点意图,非完整 JSON)

  • code-prepare:输出 loop_rounds: [1,2,3](或真实子任务数组)。
  • loop-zhini:items_path=loop_rounds,item_variable=round。
  • 子链:llm-subtask(专用 id,提示词含本轮任务与 {{round}})→ loop_end。
  • transform-merge:输入为 loop 输出数组 → 拼成最终 reply。
  • cache-save / end:只依赖 transform-merge。

9. 风险与降级

风险 应对
循环体只能单链、多分支不支持 业务拆成多段 Transform 或回到 A 档
跨轮状态不自动传递 用数组项携带状态,或单节点长链工具
End 收不到体内 LLM 必须经 loop 输出或后续 Transform 显式合并
成本/超时 限制 len(items),必要时产品侧改需求为单节点多工具

默认推荐:若仅为「多步工具 + 可持续任务汇报」,优先保持 15 号现有 llm-unified + max_tool_iterations + 提示词;仅在产品明确要求「按列表逐条推理」时启用 loop 方案。


10. 与脚本/文档的对应

  • 工作流脚本:backend/scripts/create_zhini_kefu_15.py(当前为单 LLM 主线;若落地 loop,需另存副本或版本化,避免破坏 14/15 默认行为)。
  • 能力说明:知你客服15号能力文档.md(可与本节交叉引用「进阶:Loop 多轮」)。

文档版本:与引擎 workflow_engine.py 中 loop / _execute_loop_body 行为对齐;若引擎升级多链循环或 node_outputs 写入规则变化,需同步修订本节。