---
read_when:
    - 你需要 Agent loop 或生命周期事件的详细说明
    - 你正在更改会话队列、对话记录写入或会话写入锁行为
summary: 智能体循环生命周期、流与等待语义
title: Agent loop
x-i18n:
    generated_at: "2026-07-12T14:25:28Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 15
    provider: openai
    source_hash: 3793a2c765c72f7f4bb8e790ce4d61abc279cf3a8a7367ecf8759428d0192279
    source_path: concepts/agent-loop.md
    workflow: 16
---

智能体循环是按会话串行执行的运行流程，它将消息转化为操作和回复：接收、上下文组装、模型推理、工具执行、流式传输、持久化。

## 入口点

- Gateway 网关 RPC：`agent` 和 `agent.wait`。
- CLI：`openclaw agent`。

## 运行顺序

1. `agent` RPC 验证参数、解析会话（`sessionKey`/`sessionId`）、持久化会话元数据，并立即返回 `{ runId, acceptedAt }`。
2. `agentCommand` 执行当前轮次：解析模型以及 thinking/verbose/trace 默认值、加载 Skills 快照、调用 `runEmbeddedAgent`；如果嵌入式循环尚未发出相应事件，则发出兜底的**生命周期结束/错误**事件。
3. `runEmbeddedAgent`：通过按会话队列和全局队列串行执行运行任务，解析模型和身份验证配置文件，构建 OpenClaw 会话，订阅运行时事件，以流式方式传输助手/工具增量，强制执行运行超时（到期时中止），并返回载荷及用量元数据。对于 Codex app-server 轮次，如果已接受的轮次在终止事件之前停止产生 app-server 进度，它也会中止该轮次。
4. `subscribeEmbeddedAgentSession` 将运行时事件桥接到 `agent` 流：工具事件发送到 `stream: "tool"`，助手增量发送到 `stream: "assistant"`，生命周期事件发送到 `stream: "lifecycle"`（`phase: "start" | "end" | "error"`）。
5. `agent.wait`（`waitForAgentRun`）等待某个 `runId` 的**生命周期结束/错误**事件，并返回 `{ status: ok|error|timeout, startedAt, endedAt, error? }`。

## 队列与并发

运行任务按会话键（会话通道）串行执行，并可选择再通过全局通道执行，以防止工具/会话竞态。消息渠道选择一种队列模式（steer/followup/collect/interrupt），将任务送入此通道系统；请参阅[命令队列](/zh-CN/concepts/queue)。

会话文件上的会话写入锁还会额外保护会话记录写入。该锁可感知进程并基于文件实现，因此能够捕获绕过进程内队列或来自其他进程的写入方。写入方最多等待 `session.writeLock.acquireTimeoutMs`（默认 `60000` ms；可通过环境变量 `OPENCLAW_SESSION_WRITE_LOCK_ACQUIRE_TIMEOUT_MS` 覆盖），之后会报告会话正忙。

默认情况下，会话写入锁不可重入。如果某个辅助函数有意嵌套获取同一把锁，同时仍保持单一逻辑写入方，则必须通过 `allowReentrant: true` 选择启用。

## 会话和工作区准备

- 解析并创建工作区；沙箱隔离的运行可能会重定向到沙箱工作区根目录。
- 加载 Skills（或从快照复用），并将其注入环境和提示词。
- 解析引导/上下文文件，并将其注入系统提示词。
- 在流式传输开始之前获取会话写入锁，并准备会话记录目标。之后的任何会话记录重写、压缩或截断路径，都必须先获取同一把锁，再修改 SQLite 会话记录行。

## 提示词组装

系统提示词由 OpenClaw 的基础提示词、Skills 提示词、引导上下文和按运行设置的覆盖项构建而成。系统会强制执行模型特定的限制和压缩保留 token 数。有关模型所见内容，请参阅[系统提示词](/zh-CN/concepts/system-prompt)。

## Hooks

OpenClaw 有两套钩子系统：

- **内部钩子**（Gateway 网关钩子）：用于命令和生命周期事件的事件驱动脚本。
- **插件钩子**：智能体/工具生命周期和 Gateway 网关管线中的扩展点。

### 内部钩子（Gateway 网关钩子）

- **`agent:bootstrap`**：在系统提示词最终确定之前构建引导文件时运行。可用于添加或移除引导上下文文件。
- **命令钩子**：`/new`、`/reset`、`/stop` 和其他命令事件（请参阅 Hooks 文档）。

有关设置和示例，请参阅 [Hooks](/zh-CN/automation/hooks)。

### 插件钩子

这些钩子在智能体循环或 Gateway 网关管线内运行：

| 钩子                                                    | 运行时机                                                                                                                                                                                                                                                                                    |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `before_model_resolve`                                  | 会话前（无 `messages`），用于在解析之前以确定性方式覆盖提供商/模型。                                                                                                                                                                                                                         |
| `before_prompt_build`                                   | 加载会话之后（包含 `messages`），用于在提交前注入 `prependContext`、`systemPrompt`、`prependSystemContext` 或 `appendSystemContext`。将 `prependContext` 用于每轮动态文本，将系统上下文字段用于应置于系统提示词空间中的稳定指导。 |
| `before_agent_start`                                    | 可能在任一阶段运行的旧版兼容钩子；优先使用上述显式钩子。                                                                                                                                                                                                                                    |
| `before_agent_reply`                                    | 内联操作之后、调用 LLM 之前。允许插件接管当前轮次并返回合成回复，或完全不作回复。                                                                                                                                                                                                            |
| `agent_end`                                             | 完成后运行，并接收最终消息列表和运行元数据。                                                                                                                                                                                                                                                |
| `before_compaction` / `after_compaction`                | 观察压缩周期或为其添加注释。                                                                                                                                                                                                                                                                |
| `before_tool_call` / `after_tool_call`                  | 拦截工具参数/结果。                                                                                                                                                                                                                                                                         |
| `before_install`                                        | 操作员安装策略运行之后，在暂存的 Skills/插件安装材料上运行，前提是当前进程已加载插件钩子。                                                                                                                                                                                                   |
| `tool_result_persist`                                   | 在工具结果写入 OpenClaw 所有的会话记录之前，同步转换这些结果。                                                                                                                                                                                                                              |
| `message_received` / `message_sending` / `message_sent` | 入站和出站消息钩子。                                                                                                                                                                                                                                                                        |
| `session_start` / `session_end`                         | 会话生命周期边界。                                                                                                                                                                                                                                                                          |
| `gateway_start` / `gateway_stop`                        | Gateway 网关生命周期事件。                                                                                                                                                                                                                                                                  |

出站/工具防护钩子的决策规则：

- `before_tool_call`：`{ block: true }` 为终止性结果，并停止优先级更低的处理程序。`{ block: false }` 不执行任何操作，也不会清除先前的阻止结果。
- `before_install`：与上述规则具有相同的终止/无操作语义。对于必须覆盖 CLI 安装和更新路径、由操作员负责的安装允许/阻止决策，请使用 `security.installPolicy`，而不是 `before_install`。
- `message_sending`：`{ cancel: true }` 为终止性结果，并停止优先级更低的处理程序。`{ cancel: false }` 不执行任何操作，也不会清除先前的取消结果。

有关钩子 API 和注册详情，请参阅[插件钩子](/zh-CN/plugins/hooks)。

Harness 可以适配这些钩子。Codex app-server harness 将 OpenClaw 插件钩子作为已记录镜像表面的兼容性契约；Codex 原生钩子是独立且更底层的 Codex 机制。

## 流式传输

- 助手增量从智能体运行时以 `assistant` 事件的形式流式传输。
- 分块流式传输可以在 `text_end` 或 `message_end` 时发出部分回复。
- 推理流式传输可以使用单独的流，也可以阻塞回复。
- 有关分块和分块回复行为，请参阅[流式传输](/zh-CN/concepts/streaming)。

## 工具执行

- 工具开始/更新/结束事件在 `tool` 流中发出。
- 在记录日志/发出事件之前，会根据大小和图像载荷对工具结果进行清理。
- 系统会跟踪消息工具发送，以避免重复的助手确认消息。

## 回复整形

最终载荷由助手文本（以及可选的推理内容）、内联工具摘要（启用 verbose 且允许时）和模型出错时的助手错误文本组装而成。

- 精确的静默 token `NO_REPLY` 会从出站载荷中过滤掉。
- 消息工具产生的重复内容会从最终载荷列表中移除。
- 如果没有剩余的可渲染载荷且工具发生错误，系统会发出兜底的工具错误回复，除非消息工具已经发送了用户可见的回复。

## 压缩和重试

自动压缩会发出 `compaction` 流事件，并且可能触发重试。重试时，内存缓冲区和工具摘要会重置，以避免重复输出。请参阅[压缩](/zh-CN/concepts/compaction)。

## 事件流

- `lifecycle`：由 `subscribeEmbeddedAgentSession` 发出（`agentCommand` 也会作为兜底发出）。
- `assistant`：来自智能体运行时的流式增量。
- `tool`：来自智能体运行时的流式工具事件。

Gateway 网关将生命周期事件以及工具开始/终止事件投影到有界、仅含元数据的[审计账本](/zh-CN/cli/audit)中。此投影记录来源和结果代码，但不会将提示词、消息、工具参数、工具结果或原始错误从会话记录/运行时路径中复制出去。

## 聊天渠道处理

助手增量会缓冲到聊天 `delta` 消息中。在**生命周期结束/错误**时发出聊天 `final`。

## 超时

| 超时                                             | 默认值                                 | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agent.wait`                                     | 30s                                    | 仅等待；`timeoutMs` 参数可覆盖此值。不会停止底层运行。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Agent 运行时（`agents.defaults.timeoutSeconds`） | 172800s (48h)                          | 由 `runEmbeddedAgent` 的中止计时器强制执行。设为 `0` 可获得无限运行预算；模型流活跃性看门狗仍然适用。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| Cron 隔离的 Agent 轮次                           | 由 cron 管理                           | 调度器在执行开始时启动自己的计时器，在配置的截止时间中止运行，然后执行有界清理，之后再记录超时，以免过期的子会话导致该执行通道一直卡住。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| 模型空闲超时                                     | 云端 120s；自托管 300s                 | 如果在空闲窗口结束前没有收到响应分块，OpenClaw 会中止模型请求。对于较慢的本地/自托管提供商，`models.providers.<id>.timeoutSeconds` 可延长此空闲看门狗，但仍受任何更低的有限 `agents.defaults.timeoutSeconds` 或运行特定超时的约束，因为它们控制整个 Agent 运行。无限运行预算仍会保留按提供商类别设置的空闲看门狗。由 Cron 触发且未显式设置模型/Agent 超时的云端模型运行使用相同的默认值；如果显式设置了 Cron 运行超时，云端模型流停滞时间上限为 60s，以便配置的模型回退仍可在外层 Cron 截止时间前运行。由 Cron 触发且使用真正本地端点（loopback/私有 baseUrl）的运行会保留本地空闲超时退出机制；使用网络 baseUrl 的自托管提供商会获得隐式的 300s 看门狗。如果显式设置了 Cron 运行超时，本地/自托管停滞时间上限为该超时值。对于较慢的本地提供商，请设置 `models.providers.<id>.timeoutSeconds`。 |
| 提供商 HTTP 请求超时                             | `models.providers.<id>.timeoutSeconds` | 涵盖连接、响应头、响应体、SDK 请求超时、受保护的 fetch 中止处理，以及该提供商的模型流空闲看门狗。在提高整个 Agent 运行时超时之前，请先将其用于较慢的本地/自托管提供商（例如 Ollama）；如果模型请求需要运行更长时间，请确保 Agent/运行时超时至少与其相同。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

### 卡住的会话诊断

启用诊断后，`diagnostics.stuckSessionWarnMs`（默认 `120000` ms）会对长时间处于 `processing` 状态，且未观察到回复、工具、状态、分块或 ACP 进度的会话进行分类：

- 活跃的嵌入式运行、模型调用和工具调用报告为 `session.long_running`。由所有者管理的静默模型调用会保持 `session.long_running` 状态，直到达到 `diagnostics.stuckSessionAbortMs`，避免过早将较慢或非流式提供商标记为停滞。
- 没有近期进度的活跃工作报告为 `session.stalled`。由所有者管理的模型调用会在达到或超过中止阈值时切换为 `session.stalled`；无所有者的过期模型/工具活动不会被隐藏为长时间运行。
- `session.stuck` 专用于可恢复的过期会话记录状态，包括存在无所有者的过期模型/工具活动的空闲排队会话。

`diagnostics.stuckSessionAbortMs` 默认为至少 5 分钟，且为警告阈值的 3 倍。恢复门禁通过后，过期会话记录状态会立即释放受影响的会话执行通道；停滞的嵌入式运行仅会在达到中止阈值后执行中止并排空，因此排队工作可以恢复，而不会截断仅仅是运行较慢的任务。恢复过程会发出结构化的已请求/已完成结果；仅当同一处理代次仍为当前代次时，才会将诊断状态标记为空闲；会话保持不变期间，重复的 `session.stuck` 诊断会进行退避。

## 可能提前结束的位置

- Agent 超时（中止）
- AbortSignal（取消）
- Gateway 网关断开连接或 RPC 超时
- `agent.wait` 超时（仅等待，不会停止 Agent）

## 相关内容

- [工具](/zh-CN/tools) - 可用的 Agent 工具
- [Hooks](/zh-CN/automation/hooks) - 由 Agent 生命周期事件触发的事件驱动脚本
- [压缩](/zh-CN/concepts/compaction) - 如何总结长对话
- [Exec 审批](/zh-CN/tools/exec-approvals) - shell 命令的审批门禁
- [思考](/zh-CN/tools/thinking) - 思考/推理级别配置
