世界上有一种过程叫 Agent Loop,它就像 AI 的「一圈生命」。从你发出消息的那一刻起,AI 就开始了一圈奇妙的旅程:接收消息 → 组装上下文 → 调用模型 → 执行工具 → 流式输出 → 保存状态。这就是一个完整的「代理循环」。
🤔 什么是 Agent Loop?
代理循环是 AI 代理的完整「真实」运行过程:输入 → 上下文组装 → 模型推理 → 工具执行 → 流式回复 → 持久化。这是将消息转换为行动和最终回复的权威路径,同时保持会话状态的一致性。
在 OpenClaw 中,循环是每个会话的单个序列化运行,发出生命周期和流事件,因为模型在思考、调用工具和流式输出。
🚀 入口点
- Gateway RPC:
agent和agent.wait - CLI:
agent命令
🔄 工作流程(高级)
-
agent RPC 验证参数、解析会话、持久化会话元数据,立即返回
{ runId, acceptedAt } -
agentCommand 运行代理:
- 解析模型 + thinking/verbose 默认值
- 加载技能快照
- 调用
runEmbeddedPiAgent - 如果嵌入式循环未发出,则发出生命周期结束/错误
-
runEmbeddedPiAgent:
- 通过每会话 + 全局队列序列化运行
- 解析模型 + 认证配置并构建 Pi 会话
- 订阅 Pi 事件并流式传输助手/工具增量
- 强制超时 → 超时则中止运行
- 返回 payloads + 使用元数据
-
subscribeEmbeddedPiSession 将 Pi 事件桥接到 OpenClaw
agent流:- 工具事件 →
stream: "tool" - 助手增量 →
stream: "assistant" - 生命周期事件 →
stream: "lifecycle"(phase: "start" | "end" | "error")
- 工具事件 →
-
agent.wait 使用
waitForAgentJob:等待runId的生命周期结束/错误
⏳ 队列与并发
- 运行通过每会话键(会话队列)序列化,可选通过全局队列
- 这防止工具/会话竞态,保持会话历史一致
- 消息频道可以选择队列模式(collect/steer/followup)
📂 会话与工作区准备
- 解析并创建工作区;沙盒运行可能会重定向到沙盒工作区根目录
- 加载技能(或从快照重用)并注入环境和提示
- 解析引导/上下文文件并注入系统提示
- 获取会话写锁;SessionManager 在流式传输前打开和准备
💬 提示组装与系统提示
- 系统提示由 OpenClaw 基础提示、技能提示、引导上下文和每运行覆盖构建
- 强制执行模型特定限制和压缩保留 Token
🪝 钩子点(你可以拦截的地方)
OpenClaw 有两个钩子系统:
内部钩子(Gateway Hooks)
agent:bootstrap:在构建引导文件时运行,系统提示定稿前- 命令钩子:
/new,/reset,/stop等命令事件
插件钩子(代理 + Gateway 生命周期)
| 钩子 | 说明 |
|---|---|
before_model_resolve | 会话前运行,确定性覆盖提供者/模型 |
before_prompt_build | 会话加载后运行,注入上下文 |
agent_end | 检查最终消息列表和运行元数据 |
before_compaction / after_compaction | 观察或注释压缩周期 |
before_tool_call / after_tool_call | 拦截工具参数/结果 |
tool_result_persist | 同步转换工具结果后再写入会话转录 |
message_received / message_sending / message_sent | 入站 + 出站消息钩子 |
session_start / session_end | 会话生命周期边界 |
gateway_start / gateway_stop | Gateway 生命周期事件 |
钩子决策规则:
before_tool_call:{ block: true }是终止性的,停止低优先级处理程序message_sending:{ cancel: true }是终止性的,停止低优先级处理程序
🌊 流式传输与部分回复
- 助手增量从 Pi 代理核心流式传输并作为
assistant事件发出 - 块流式传输可以在
text_end或message_end发出部分回复 - 推理流式传输可以作为单独流或块回复发出
🔧 工具执行与消息工具
- 工具开始/更新/结束事件在
tool流上发出 - 工具结果在记录/发出前进行大小和图像 payload 清理
- 消息工具发送被跟踪以抑制重复的助手确认
✏️ 回复塑形与抑制
- 最终 payloads 从助手文本(+ 可选推理)、内联工具摘要(verbose + 允许时)和助手错误文本组装
NO_REPLY被视为静音 token 并从传出 payloads 中过滤- 消息工具重复项从最终 payload 列表中删除
- 如果没有可渲染的 payloads 且工具出错,则发出回退工具错误回复
📦 压缩与重试
- 自动压缩发出
compaction流事件并可以触发重试 - 重试时,重置内存缓冲区和工具摘要以避免重复输出
📡 事件流(当前)
lifecycle:由subscribeEmbeddedPiSession发出(和agentCommand作为回退)assistant:从 Pi 代理核心流式传输的增量tool:从 Pi 代理核心流式传输的工具事件
⏱️ 超时
agent.wait默认:30s(仅等待)- 代理运行时:
agents.defaults.timeoutSeconds默认 600s;在runEmbeddedPiAgent中强制执行
🛑 可能提前结束的地方
- 代理超时(中止)
- AbortSignal(取消)
- Gateway 断开或 RPC 超时
agent.wait超时(仅等待,不停止代理)