Fundamentals
代理程式迴圈
代理迴圈是依工作階段序列化的執行流程,會將訊息轉換為 動作與回覆:接收、組裝內容、模型推論、工具 執行、串流、持久化。
進入點
- 閘道 RPC:
agent和agent.wait。 - 命令列介面:
openclaw agent。
執行順序
agentRPC 會驗證參數、解析工作階段(sessionKey/sessionId)、持久化工作階段中繼資料,並立即傳回{ runId, acceptedAt }。agentCommand會執行該輪次:解析模型及思考/詳細/追蹤預設值、載入 Skills 快照、呼叫runEmbeddedAgent;如果內嵌迴圈尚未發出事件,則發出備援的生命週期結束/錯誤事件。runEmbeddedAgent:透過每工作階段佇列及全域佇列序列化執行、解析模型及驗證設定檔、建立 OpenClaw 工作階段、訂閱執行階段事件、串流助理/工具差異、強制執行逾時限制(到期時中止),並傳回承載資料及用量中繼資料。對於 Codex app-server 輪次,如果已接受的輪次在終止事件前停止產生 app-server 進度,也會將其中止。subscribeEmbeddedAgentSession會將執行階段事件橋接至agent串流:工具事件傳至stream: "tool"、助理差異傳至stream: "assistant"、生命週期事件傳至stream: "lifecycle"(phase: "start" | "end" | "error")。agent.wait(waitForAgentRun)會在runId上等待生命週期結束/錯誤,並傳回{ status: ok|error|timeout, startedAt, endedAt, error? }。
佇列與並行處理
執行會依每個工作階段金鑰(工作階段通道)序列化,並可選擇性地再經過全域通道,以防止工具/工作階段競爭。訊息通道會選擇佇列模式(steer/followup/collect/interrupt)送入此通道系統;請參閱命令佇列。
逐字記錄寫入還會受到工作階段檔案上的工作階段寫入鎖保護。此鎖可感知處理程序且以檔案為基礎,因此可偵測繞過處理程序內佇列或來自其他處理程序的寫入者。寫入者預設最多等待 60 秒(可由環境變數 OPENCLAW_SESSION_WRITE_LOCK_ACQUIRE_TIMEOUT_MS 覆寫),之後便會回報工作階段忙碌中。
工作階段寫入鎖預設不可重入。若輔助程式刻意巢狀取得同一把鎖,同時仍維持單一邏輯寫入者,則必須透過 allowReentrant: true 明確選擇啟用。
工作階段與工作區準備
- 解析並建立工作區;沙箱化執行可能會重新導向至沙箱工作區根目錄。
- 載入 Skills(或從快照重複使用),並注入環境與提示詞。
- 解析啟動/內容檔案,並注入系統提示詞。
- 在開始串流前取得工作階段寫入鎖,並準備工作階段逐字記錄目標。之後任何逐字記錄重寫、壓縮或截斷路徑,都必須先取得同一把鎖,才能修改 SQLite 逐字記錄資料列。
提示詞組裝
系統提示詞由 OpenClaw 的基礎提示詞、Skills 提示詞、啟動內容及每次執行的覆寫項目建構而成。系統會強制執行模型專屬限制與壓縮保留權杖數。關於模型可見的內容,請參閱系統提示詞。
鉤子
OpenClaw 有兩套鉤子系統:
- 內部鉤子(閘道鉤子):用於命令與生命週期事件的事件驅動指令碼。
- 外掛鉤子:代理/工具生命週期與閘道流水線內的擴充點。
內部鉤子(閘道鉤子)
agent:bootstrap:在系統提示詞定稿前建立啟動檔案時執行。可用來新增或移除啟動內容檔案。- 命令鉤子:
/new、/reset、/stop及其他命令事件(請參閱鉤子文件)。
設定與範例請參閱鉤子。
外掛鉤子
這些鉤子會在代理迴圈或閘道流水線內執行:
| 鉤子 | 執行時機 |
|---|---|
before_model_resolve |
工作階段前(無 messages),用於在解析前以確定性方式覆寫供應商/模型。 |
before_prompt_build |
載入工作階段後(含 messages),用於在提交前注入 prependContext、systemPrompt、prependSystemContext 或 appendSystemContext。每輪動態文字請使用 prependContext;屬於系統提示詞空間的穩定指引則使用系統內容欄位。 |
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 與註冊詳細資料請參閱外掛鉤子。
測試框架可以調整這些鉤子。Codex app-server 測試框架會保留 OpenClaw 外掛鉤子,作為文件所述鏡像介面的相容性合約;Codex 原生鉤子則是另一套更底層的 Codex 機制。
串流
- 助理差異會從代理執行階段以
assistant事件串流傳送。 - 區塊串流可在
text_end或message_end時發出部分回覆。 - 推理串流可以是獨立串流或區塊回覆。
- 關於分塊與區塊回覆行為,請參閱串流。
工具執行
- 工具開始/更新/結束事件會在
tool串流上發出。 - 工具結果會先針對大小與影像承載資料進行清理,再記錄/發出。
- 系統會追蹤訊息工具傳送,以抑制重複的助理確認。
回覆塑形
最終承載資料由助理文字(加上選用的推理)、行內工具摘要(啟用詳細模式且允許時),以及模型發生錯誤時的助理錯誤文字組裝而成。
- 輸出承載資料會篩除完全相符的靜默權杖
NO_REPLY。 - 最終承載資料清單會移除訊息工具的重複項目。
- 若沒有剩餘可呈現的承載資料且工具發生錯誤,除非訊息工具已傳送使用者可見的回覆,否則會發出備援的工具錯誤回覆。
壓縮與重試
自動壓縮會發出 compaction 串流事件,並可觸發重試。重試時,記憶體內緩衝區與工具摘要會重設,以避免重複輸出。請參閱壓縮。
事件串流
lifecycle:由subscribeEmbeddedAgentSession發出(也可由agentCommand作為備援發出)。assistant:來自代理執行階段的串流差異。tool:來自代理執行階段的串流工具事件。
閘道會將生命週期及工具開始/終止事件投影至有界、 僅含中繼資料的稽核帳本。此投影會記錄來源與 結果代碼,而不會將提示詞、訊息、工具引數、工具結果 或原始錯誤複製出逐字記錄/執行階段路徑。
聊天通道處理
助理差異會緩衝至聊天 delta 訊息中。發生生命週期結束/錯誤時,會發出聊天 final。
逾時
| 逾時 | 預設值 | 備註 |
|---|---|---|
agent.wait |
30s | 僅等待;timeoutMs 參數會覆寫此值。不會停止底層執行。 |
代理程式執行階段(agents.defaults.timeoutSeconds) |
172800s (48h) | 由 runEmbeddedAgent 的中止計時器強制執行。設定 0 可使用無限制的執行預算;模型串流存活監控仍然適用。 |
| 命令列介面後端無輸出監控 | 依每次全新/恢復的命令列介面執行計算 | 與代理程式執行階段分開,並由已註冊的後端外掛負責。命令列介面內部背景工作與父子程序共用生命週期,不會在整體代理程式逾時後繼續存活。 |
| 排程隔離的代理程式輪次 | 由排程負責 | 排程器會在執行開始時啟動自己的計時器,在設定的期限到達時中止執行,接著執行有界限的清理後再記錄逾時,避免過期的子工作階段讓該執行通道持續卡住。 |
| 模型閒置逾時 | 雲端 120s;自行託管 300s | 若在閒置時間範圍內未收到任何回應區塊,OpenClaw 會中止模型要求。models.providers.<id>.timeoutSeconds 可延長此閒置監控時間,以支援較慢的本機/自行託管供應商,但仍受任何較短的有限 agents.defaults.timeoutSeconds 或特定執行逾時限制,因為這些逾時管控整個代理程式執行。即使執行預算無限制,仍會保留供應商類別的閒置監控。由排程觸發且未明確設定模型/代理程式逾時的雲端模型執行會使用相同預設值;若明確設定排程執行逾時,雲端模型串流停滯的上限為 60s,讓設定的模型後援仍能在外層排程期限前執行。由排程觸發且使用真正本機端點(回送/私有 baseUrl)的執行,會保留本機閒置逾時停用機制;使用網路 baseUrl 的自行託管供應商則採用隱含的 300s 監控。若明確設定排程執行逾時,本機/自行託管停滯的上限為該逾時值。針對較慢的本機供應商,請設定 models.providers.<id>.timeoutSeconds。 |
| 供應商 HTTP 要求逾時 | models.providers.<id>.timeoutSeconds |
涵蓋連線、標頭、本文、SDK 要求逾時、受保護擷取的中止處理,以及該供應商的模型串流閒置監控。若本機/自行託管供應商(例如 Ollama)速度較慢,請先使用此設定,再提高整體代理程式執行階段逾時;若模型要求需要執行更久,請將代理程式/執行階段逾時保持在至少同樣長度。 |
卡住的工作階段診斷
啟用診斷後,內建的兩分鐘門檻會對長時間未觀察到回覆、工具、狀態、封鎖或 ACP 進度的 processing 工作階段進行分類:
- 進行中的內嵌執行、模型呼叫和工具呼叫會回報為
session.long_running。由擁有者負責且無輸出的模型呼叫會維持session.long_running,直到達到中止門檻,避免過早將較慢或非串流供應商標記為停滯。 - 近期沒有進度的進行中工作會回報為
session.stalled。由擁有者負責的模型呼叫會在達到或超過中止門檻時切換為session.stalled;沒有擁有者的過期模型/工具活動不會被隱藏為長時間執行。 session.stuck保留給可復原的過期工作階段記錄,包括具有過期且無擁有者模型/工具活動的閒置排隊工作階段。
中止門檻至少為 5 分鐘,且為警告門檻的 3 倍。過期工作階段記錄會在通過復原關卡後立即釋放受影響的工作階段執行通道;停滯的內嵌執行只會在達到中止門檻後進行中止排空,因此排隊工作可繼續執行,而不會中斷僅僅是較慢的執行。復原會發出結構化的已要求/已完成結果;只有在相同處理世代仍為目前世代時,診斷狀態才會標記為閒置,而且工作階段維持不變時,重複的 session.stuck 診斷會採用退避機制。
可能提前結束的位置
- 代理程式逾時(中止)
- AbortSignal(取消)
- 閘道中斷連線或 RPC 逾時
agent.wait逾時(僅等待,不會停止代理程式)