Skip to content
广告 · 本站推荐广告

Agent 循环

Agent Loop(智能体循环)是 OpenClaw 处理每条消息的核心流水线。每次用户发送消息后,Agent 都会执行一个完整的循环来生成回复。

基本原则

串行化执行

每个 Session(会话)在同一时刻只运行一个 Agent Loop。新消息在前一个循环完成前会进入队列等待。

Agent Loop 采用单线程串行模型,确保同一会话内的消息按序处理,避免竞态条件。

五阶段流水线

┌─────────┐    ┌────────────┐    ┌───────────┐    ┌───────────┐    ┌────────────┐
│  Entry   │───▶│ Preparation│───▶│ Execution │───▶│ Streaming │───▶│ Completion │
│  入口    │    │  准备阶段  │    │  执行阶段 │    │ 流式输出  │    │  完成阶段  │
└─────────┘    └────────────┘    └───────────┘    └───────────┘    └────────────┘

阶段 1:Entry(入口)

入口阶段负责验证与路由:

  • 验证请求参数(消息内容、渠道信息、会话 ID)
  • 通过 RPC 或 CLI 解析目标 Session
  • 检查 Agent 是否在线与可用
  • 应用消息预处理规则
typescript
// 入口验证伪代码
function entry(params: AgentRequest) {
  validateParams(params)
  const session = resolveSession(params.sessionKey)
  return { session, message: params.message }
}

阶段 2:Preparation(准备)

准备阶段构建 Agent 运行所需的完整上下文:

  1. 加载技能(Skills) — 根据配置加载 bundled、managed 和 workspace 技能
  2. 解析工作区 — 读取 AGENTS.md、SOUL.md 等工作区文件
  3. 构建系统提示词 — 组装完整的 System Prompt

性能优化

工作区文件会被缓存,仅在文件修改后重新加载。技能列表在 Agent 启动时预构建。

阶段 3:Execution(执行)

核心执行阶段调用 runEmbeddedPiAgent 方法:

Per-Session Queue → Global Queue → LLM Call → Tool Execution → Loop
  • Per-session 队列确保同一会话串行
  • Global 队列限制并发 LLM 调用数量
  • LLM 可能返回工具调用(Tool Call),触发工具执行后再次循环

工具结果清洗

工具执行结果在返回 LLM 前会进行清洗:

  • 大小限制 — 超出阈值的结果会被截断
  • 图片载荷 — 自动转换为引用格式,避免 Token 浪费

阶段 4:Streaming(流式输出)

流式阶段将 LLM 的输出实时传递给用户:

typescript
// 流式事件类型
type StreamEvent =
  | { stream: 'tool', name: string, status: string }  // 工具事件
  | { stream: 'text', delta: string }                   // 文本增量
  | { stream: 'end' }                                   // 结束标记
  • 工具事件 — 以 stream: 'tool' 形式发送,通知用户正在执行哪个工具
  • 文本增量 — Assistant 的回复以 delta(增量)形式实时推送
  • 不支持流式的渠道会缓冲完整回复后一次性发送

阶段 5:Completion(完成)

完成阶段执行收尾工作:

  1. 组装最终载荷 — 合并所有流式片段为完整响应
  2. 过滤静默 Token — 移除内部标记(如 <silent> 标签)
  3. 发出生命周期事件 — 触发 lifecycle:end 事件
  4. 持久化 — 将对话记录写入 JSONL 转录文件

响应塑形(Response Shaping)

Agent Loop 根据上下文调整最终输出:

场景处理方式
正常回复直接输出 LLM 文本
工具执行成功内联摘要(Inline Summary)
工具执行失败错误文本 + 重试建议
上下文过长触发 Compaction(压缩)

完整流程图

用户消息


┌─────────────────────┐
│  1. Entry 入口      │
│  - 参数验证         │
│  - Session 解析     │
└─────────┬───────────┘


┌─────────────────────┐
│  2. Preparation 准备│
│  - 加载技能         │
│  - 构建系统提示词   │
└─────────┬───────────┘


┌─────────────────────┐
│  3. Execution 执行  │◄──┐
│  - LLM 调用        │   │
│  - 工具执行        │───┘ (工具循环)
└─────────┬───────────┘


┌─────────────────────┐
│  4. Streaming 流式  │
│  - 实时推送        │
└─────────┬───────────┘


┌─────────────────────┐
│  5. Completion 完成 │
│  - 持久化          │
│  - 生命周期事件    │
└─────────────────────┘

错误处理

执行失败

当 Agent Loop 中的 LLM 调用失败时,系统会:

  1. 检查是否有 Failover(故障转移)模型
  2. 根据错误类型决定重试还是切换模型
  3. 所有模型均失败后返回错误消息给用户

下一步

基于MIT协议开源 | 内容翻译自 官方文档,同步更新