---
read_when:
    - 你需要代理迴圈或生命週期事件的精確逐步說明
    - 你正在變更工作階段佇列、對話記錄寫入或工作階段寫入鎖定行為
summary: 代理迴圈生命週期、串流與等待語意
title: 代理程式迴圈
x-i18n:
    generated_at: "2026-07-12T14:26:56Z"
    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
---

代理迴圈是每個工作階段中序列化執行的流程，將訊息轉化為
動作與回覆：接收、組裝上下文、模型推論、工具
執行、串流、持久化。

## 進入點

- 閘道 RPC：`agent` 與 `agent.wait`。
- 命令列介面：`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-TW/concepts/queue)。

逐字稿寫入另由工作階段檔案上的工作階段寫入鎖保護。此鎖具備程序感知能力並以檔案為基礎，因此能偵測略過程序內佇列或來自其他程序的寫入者。寫入者最多等待 `session.writeLock.acquireTimeoutMs`（預設為 `60000` ms；可透過環境變數 `OPENCLAW_SESSION_WRITE_LOCK_ACQUIRE_TIMEOUT_MS` 覆寫），之後便會回報工作階段忙碌中。

工作階段寫入鎖預設不可重新進入。若輔助函式刻意巢狀取得同一把鎖，同時維持單一邏輯寫入者，則必須以 `allowReentrant: true` 明確啟用。

## 工作階段與工作區準備

- 解析並建立工作區；沙箱化執行可能會重新導向至沙箱工作區根目錄。
- 載入 Skills（或從快照重複使用），並注入環境與提示詞。
- 解析啟動程序/上下文檔案，並注入系統提示詞。
- 在串流開始前取得工作階段寫入鎖，並準備工作階段逐字稿目標。之後任何逐字稿重寫、壓縮或截斷路徑，都必須先取得同一把鎖，才能修改 SQLite 逐字稿資料列。

## 提示詞組裝

系統提示詞由 OpenClaw 的基礎提示詞、Skills 提示詞、啟動程序上下文及每次執行的覆寫設定組成。系統會強制套用模型特定限制與壓縮保留權杖。若要了解模型可見的內容，請參閱[系統提示詞](/zh-TW/concepts/system-prompt)。

## 鉤子

OpenClaw 有兩套鉤子系統：

- **內部鉤子**（閘道鉤子）：針對命令與生命週期事件的事件驅動指令碼。
- **外掛鉤子**：代理/工具生命週期與閘道管線內的擴充點。

### 內部鉤子（閘道鉤子）

- **`agent:bootstrap`**：在系統提示詞定案前建構啟動程序檔案時執行。可用於新增或移除啟動程序上下文檔案。
- **命令鉤子**：`/new`、`/reset`、`/stop` 與其他命令事件（請參閱鉤子文件）。

設定方式與範例請參閱[鉤子](/zh-TW/automation/hooks)。

### 外掛鉤子

這些鉤子會在代理迴圈或閘道管線內執行：

| 鉤子                                                    | 執行時機                                                                                                                                                                                                                                                                                        |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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`                                        | 操作者安裝政策執行後，針對已暫存的 Skill/外掛安裝內容執行；前提是目前程序已載入外掛鉤子。                                                                                                                                                           |
| `tool_result_persist`                                   | 在工具結果寫入 OpenClaw 擁有的工作階段逐字稿前，同步轉換結果。                                                                                                                                                                                      |
| `message_received` / `message_sending` / `message_sent` | 傳入與傳出訊息鉤子。                                                                                                                                                                                                                                                         |
| `session_start` / `session_end`                         | 工作階段生命週期邊界。                                                                                                                                                                                                                                                               |
| `gateway_start` / `gateway_stop`                        | 閘道生命週期事件。                                                                                                                                                                                                                                                                   |

傳出訊息/工具防護的鉤子決策規則：

- `before_tool_call`：`{ block: true }` 為終止性決策，會停止優先順序較低的處理常式。`{ block: false }` 不執行任何操作，也不會清除先前的封鎖。
- `before_install`：終止/無操作語意同上。對於由操作者掌控、且必須涵蓋命令列介面安裝與更新路徑的允許/封鎖安裝決策，請使用 `security.installPolicy`，而非 `before_install`。
- `message_sending`：`{ cancel: true }` 為終止性決策，會停止優先順序較低的處理常式。`{ cancel: false }` 不執行任何操作，也不會清除先前的取消。

鉤子 API 與註冊詳細資料請參閱[外掛鉤子](/zh-TW/plugins/hooks)。

測試框架可以調整這些鉤子。Codex app-server 測試框架會保留 OpenClaw 外掛鉤子，作為文件所述鏡像介面的相容性合約；Codex 原生鉤子則是另一套更底層的 Codex 機制。

## 串流

- 助理增量會以 `assistant` 事件從代理執行階段串流送出。
- 區塊串流可在 `text_end` 或 `message_end` 時發出部分回覆。
- 推理串流可作為獨立串流或區塊回覆。
- 分塊與區塊回覆行為請參閱[串流](/zh-TW/concepts/streaming)。

## 工具執行

- 工具開始/更新/結束事件會在 `tool` 串流上發出。
- 工具結果在記錄/發出前，會針對大小與圖片承載資料進行清理。
- 系統會追蹤訊息工具的傳送，以避免重複的助理確認訊息。

## 回覆塑形

最終承載資料由助理文字（加上選用的推理內容）、內嵌工具摘要（啟用詳細模式且允許時），以及模型發生錯誤時的助理錯誤文字組成。

- 完全相符的靜默權杖 `NO_REPLY` 會從傳出承載資料中濾除。
- 訊息工具產生的重複項目會從最終承載資料清單中移除。
- 若沒有剩餘可呈現的承載資料，且工具發生錯誤，除非訊息工具已傳送使用者可見的回覆，否則會發出備援工具錯誤回覆。

## 壓縮與重試

自動壓縮會發出 `compaction` 串流事件，並可能觸發重試。重試時，記憶體內緩衝區與工具摘要會重設，以避免重複輸出。請參閱[壓縮](/zh-TW/concepts/compaction)。

## 事件串流

- `lifecycle`：由 `subscribeEmbeddedAgentSession` 發出（亦可由 `agentCommand` 作為備援發出）。
- `assistant`：來自代理執行階段的串流增量。
- `tool`：來自代理執行階段的串流工具事件。

閘道會將生命週期及工具開始/終止事件投影至有界、
僅含中繼資料的[稽核帳本](/zh-TW/cli/audit)。此投影會記錄來源與
結果代碼，而不會將提示詞、訊息、工具引數、工具結果
或原始錯誤複製到逐字稿/執行階段路徑之外。

## 聊天通道處理

助理增量會緩衝至聊天 `delta` 訊息中。發生**生命週期結束/錯誤**時，會發出聊天 `final`。

## 逾時

| 逾時                                             | 預設值                                 | 備註                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agent.wait`                                     | 30s                                    | 僅等待；`timeoutMs` 參數可覆寫。這不會停止底層執行。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Agent 執行時間（`agents.defaults.timeoutSeconds`） | 172800s (48h)                          | 由 `runEmbeddedAgent` 的中止計時器強制執行。設為 `0` 可提供無限制的執行時間預算；模型串流存活監控仍然適用。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| 排程隔離的 Agent 回合                              | 由排程擁有                             | 排程器會在執行開始時啟動自己的計時器，在設定的截止時間中止執行，接著執行有界清理，再記錄逾時，以免過期的子工作階段讓該執行通道持續卡住。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| 模型閒置逾時                                     | 雲端 120s；自架 300s                   | 若在閒置時間範圍內未收到任何回應區塊，OpenClaw 會中止模型要求。`models.providers.<id>.timeoutSeconds` 可為速度較慢的本機／自架提供者延長此閒置監控時間，但仍受任何更低且有限的 `agents.defaults.timeoutSeconds` 或執行特定逾時限制，因為這些設定控制整個 Agent 執行。即使執行時間預算無限制，提供者類別的閒置監控仍會保留。由排程觸發且未明確設定模型／Agent 逾時的雲端模型執行也使用相同預設值；若明確設定排程執行逾時，雲端模型串流停滯最多為 60s，讓已設定的模型備援仍可在外層排程截止時間前執行。由排程觸發且使用真正本機端點（回送／私人 baseUrl）的執行會保留本機閒置監控停用設定；使用網路 baseUrl 的自架提供者則會套用隱含的 300s 監控。若明確設定排程執行逾時，本機／自架模型的停滯上限為該逾時值。對速度較慢的本機提供者設定 `models.providers.<id>.timeoutSeconds`。 |
| 提供者 HTTP 要求逾時                              | `models.providers.<id>.timeoutSeconds` | 涵蓋連線、標頭、本文、SDK 要求逾時、受防護擷取的中止處理，以及該提供者的模型串流閒置監控。對速度較慢的本機／自架提供者（例如 Ollama），請先使用此設定，再提高整個 Agent 執行時間逾時；若模型要求需要執行更久，請將 Agent／執行時間逾時維持在至少相同的長度。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

### 工作階段卡住的診斷

啟用診斷後，`diagnostics.stuckSessionWarnMs`（預設為 `120000` 毫秒）會將長時間處於 `processing` 狀態，且未觀察到回覆、工具、狀態、區塊或 ACP 進度的工作階段分類如下：

- 執行中的內嵌執行、模型呼叫和工具呼叫會回報為 `session.long_running`。有擁有者但無輸出的模型呼叫會維持 `session.long_running`，直到達到 `diagnostics.stuckSessionAbortMs`，以免過早將緩慢或非串流提供者標記為停滯。
- 執行中但最近沒有進度的工作會回報為 `session.stalled`。有擁有者的模型呼叫會在達到或超過中止門檻時切換為 `session.stalled`；沒有擁有者且已過時的模型／工具活動不會以長時間執行為由而隱藏。
- `session.stuck` 保留用於可復原但已過時的工作階段簿記狀態，包括閒置的佇列工作階段，其中含有已過時且沒有擁有者的模型／工具活動。

`diagnostics.stuckSessionAbortMs` 預設至少為 5 分鐘，且為警告閾值的 3 倍。復原閘門通過後，過時的工作階段簿記會立即釋放受影響的工作階段通道；停滯的嵌入式執行只有在超過中止閾值後才會中止並清空，因此佇列中的工作可繼續執行，而不會中斷僅是速度較慢的執行。復原會發出結構化的已請求／已完成結果；只有在同一處理世代仍為目前世代時，診斷狀態才會標記為閒置，而且工作階段維持不變時，重複的 `session.stuck` 診斷會採用指數退避。

## 哪些情況可能提早結束

- 代理程式逾時（中止）
- AbortSignal（取消）
- 閘道中斷連線或 RPC 逾時
- `agent.wait` 逾時（僅停止等待，不會停止代理程式）

## 相關內容

- [工具](/zh-TW/tools) - 可用的代理程式工具
- [鉤子](/zh-TW/automation/hooks) - 由代理程式生命週期事件觸發的事件驅動指令碼
- [壓縮](/zh-TW/concepts/compaction) - 如何摘要長篇對話
- [執行核准](/zh-TW/tools/exec-approvals) - shell 命令的核准閘門
- [思考](/zh-TW/tools/thinking) - 思考／推理層級設定
