ARCHITECTURE · 05
Agent Loop:DeepSeek Harness 的智能体循环怎么转
直接答案
DeepSeek Harness 的智能体循环本身也是可替换插件:agent 包定义约定,agent-loop 是默认实现。基本单位是步骤(一次模型请求加它调用的工具)和轮次(零个或多个步骤)。输入先进统一收件箱,认领后按"决策、请求模型、执行工具、回填结果"循环,直到不欠任何工作就关闭轮次。循环是可替换的插件,不是硬编码内核
agent 包拥有公开约定:Agent 接口、活跃注册表、agent/* 实时事件词汇和 ctx.agents 服务。agent-loop 只是这套约定的默认实现(ctx.agentLoop)。官方规定:扩展插件只依赖 agent 包,绝不直接依赖 agent-loop——所以整个驱动器是可以替换的。这呼应了架构总览里的"不存在特权内核"。
两个基本单位:步骤与轮次
- 步骤(step):一次模型请求,加上它调用的工具。
- 轮次(turn):零个或多个步骤。轮次在领取首条输入前打开,在"不再欠任何工作"时关闭。
注意"零个步骤"是真实存在的:输入在 pre-step(步骤前决策)阶段被拒绝或改写为空,循环也会关闭一个不含步骤的持久轮次——这次尝试会留在日志里,不会静默消失。所以"轮次"不等于"一轮一问一答"。
一个轮次的完整流程
以官方 docs/architecture.zh.md 的 turn-flow 伪代码和 docs/agent-lifecycle.zh.md 时序图为准,一个轮次依次经历:
turn/start:轮次打开;- 认领输入;
agent/pre-step:步骤前决策(waterfall 模式,监听器可以拒绝或改写消息)——它决定模型最终看到什么;step/start:步骤开始,把用户消息追加进日志;- 从会话日志派生模型历史(不是单独存的历史,见会话页);
agent/request→llm/stream:向模型发请求并流式接收;- 模型回复以
assistant/chunk→assistant/message落日志; - 模型要调工具时:
tool/call→tools/pre-execute(审批把关)→tools/execute→tools/post-execute→tool/result落日志; step/end:步骤结束。如果还欠工具结果或来了新输入,进入下一步;agent/turn-stopping→turn/end:轮次收尾关闭。
其中 agent/pre-step、agent/request、llm/stream、tools/* 都是 waterfall(瀑布)模式——监听器必须调 next() 才能委托下游(规则见 Cordis 框架页);agent/turn-stopping 是 serial(串行)模式,没有 next()。
输入怎么进来:统一收件箱与三种预设发送方式
所有输入都经过统一 inbox(收件箱)到达,inbox 里有两条有序列表:next-turn(排下一轮)和 next-step(插入当前轮)。对外是同一个发送函数 send(message, target, wakeup),三个常用叫法是它的预设别名:
- followup:排队到下一轮,并唤醒 agent;
- steer:中途引导,在最近的步骤边界被消费——你在 Agent 干活中途插话走的就是这条;
- inject:注入模型可见上下文,但不唤醒 agent。
从可观测状态看,Agent 只有 idle(空闲)和 running(运行中)两个值;running 覆盖整个驱动器排空区间,可以跨连续多个轮次。dispose(销毁)不是第三个状态。实操中怎么用中途引导,见教程《Agent 模式》。
出错怎么办:重试与压缩挂在哪
- 请求失败:步骤失败后、轮次结束前,会运行
agent/request-error(waterfall)。监听器返回{ kind: 'retry' }就触发重试;默认返回undefined,保持终态不重试。 - 上下文太长:compaction(上下文压缩)通过两个钩子工作——用
agent/pre-step处理日常的上下文压力,用agent/request-error处理"请求直接超出上下文"的溢出错误。
想深入工具执行那段流水线,见工具系统页。
实时事件与持久事件的分工
轮次流程里你会看到两类事件名字混在一起,性质完全不同:
turn/*、step/*、user/message、assistant/*、tool/*是持久会话事件:落盘的事实,可回放;agent/*是实时协调接口:运行中的信号,不构成历史。
SDK 或外部系统要回放完整交互记录,应该消费 session/event 广播,而不是去订阅实时事件。
EVIDENCE
证据与来源
本页包含:官方事实
| # | 事实声明 | 状态 | 来源 |
|---|---|---|---|
| 1 | agent 包拥有公开约定、agent-loop 是默认实现、扩展不直接依赖 agent-loop | 官方事实 | |
| 2 | step / turn 定义、零步骤轮次会持久记录 | 官方事实 | |
| 3 | 轮次流程骨架(turn/start 到 turn/end) | 官方事实 | |
| 4 | 各事件的 waterfall / serial 分发模式 | 官方事实 | |
| 5 | pre-step 决定模型看到什么、可拒绝或改写 | 官方事实 | |
| 6 | inbox 两条有序列表、followup / steer / inject 是 send() 预设别名 | 官方事实 | |
| 7 | Agent 仅 idle / running 两态、dispose 非第三态 | 官方事实 | |
| 8 | request-error 重试机制 { kind: 'retry' }、compaction 双钩子 | 官方事实 | |
| 9 | 持久事件与实时事件分工、SDK 消费 session/event | 官方事实 |