Skip to content

Step 循环

内置 ReActAgentStrategy节点驱动 Step 循环运行:LLM 决定计划,框架 走完它,一切可观测、可中断。

Step 解剖

intro_step ──► NATIVE_WHILE(iter_cond) ──► STEP_EXEC(一轮工具)──► leave_step
                   ▲                                   │
                   └──────── after_iteration ◄─────────┘
阶段发生什么
decompose首次 intro_step:LLM 决定 simple 还是 DAG {needs_decomposition, dag, reason}
intro_step选取下一个就绪 DAG 节点(graphlib.TopologicalSorter 拓扑序);消费 peer 消息;发出 step_intro 事件 + 元数据
STEP_EXEC一轮 single_execute():模型 → 工具 → 结果;after_iteration()循环内运行停滞检测
leave_step摘要(主谓短语)、完成节点、压缩历史;发出 step_leave 事件 + 元数据

语义状态:AgentRunState

所有 step 级状态在 AgentRunState 中(在 AgentLoopState.run_statestrategy.run_state 之间桥接——同一实例):

字段含义
step_index全局 step 计数器
current_phase / current_step_id活动 DAG 节点
plan / completed_step_ids任务 DAG + 进度
step_tool_signatures当前 Step 内的工具签名(停滞窗口)
stall_injectedgive-up prompt 已注入(每 Step 一次)
last_summary前一个 Step 的主谓摘要
tokens真实 API token 统计(压缩触发)
exec_finished策略完成工具调用 → 迭代循环结束

停滞防护

  1. _should_cancel_tool_call —— 执行前,第 N 个相同签名被取消,返回 "Cancelled: Reach the max limit of repeatly calling tool."
  2. after_iteration —— 每轮钩子(循环!)在窗口重复时注入 give-up prompt;设置 stall_injected/exec_finished 使 iter_cond 立即停止 循环——不再烧 token。

历史教训:停滞检测必须在循环内after_iteration)运行,而非 leave_step(循环外)——否则卡住的 agent 永远到不了检测器。

生命周期事件

事件时机可变
agent.step_introStep 开始override_phase
agent.step_leaveStep 结束override_verb / override_object
agent.step_iteration每轮工具end_step
agent.tool_call常规工具前arguments / cancel
agent.tool_return常规工具后result / skip_append

Matcher 可修改事件或抛 StepAbortError(控制流)。内置工具 (REASONING / UPDATE_STEP / STOP)不触发事件。

Step 元数据

MessageWithMetadata 发出(type="step"):

extra_type内容
decompose决策、DAG id + 描述、原因
introphase、step_index、simple_mode、节点描述
leavephase、停滞标志、摘要动词/宾语
stall重复签名、注入标志
compressprompt tokens、阈值

update_step 工具

agent 可中途修订计划:replan(替换 DAG)、mark_doneadd_stepremove_step。每次修订递增 plan_revision;执行保持线性(DAG 是语义层, 不是并行图)。

Peer 消息

intro_step 消费反向流(send_to_producer)并追加 [peer message] 用户 消息——见挂起与恢复

下一步

工作流调试——单步执行解释器。

Apache 2.0 许可证(一些内容可能没有完全翻译成中文,请以英文文档为准。)