03 · Agent 的大腦是怎麼工作的
理解 OpenClaw Agent runtime、Agent loop、Tools、Skills、Hooks 與許可權邊界如何組成一個可執行的大腦。
前兩篇已經講清楚兩件事:OpenClaw 不是單純聊天視窗,一條訊息也不是直接丟給模型就結束。本篇繼續往裡看一層:真正讓 Agent 能做事的不是某個模型 API,而是一套執行時迴圈。
一句話先記住:
OpenClaw 的 Agent 大腦 = Agent runtime + session context + model inference + tool execution + streaming reply + persistence。
模型負責判斷下一步,OpenClaw 負責把工作空間、會話、工具、技能、許可權、事件流和最終回覆串起來。
1. 先把 Agent 看成執行中的工作單元
OpenClaw 官方把 Agent runtime 描述成一個嵌入式執行時:每個 Gateway 裡執行一個 Agent 程序,它擁有自己的 workspace、bootstrap files 和 session store。
這和“呼叫一次大模型介面”不是同一個層級。
flowchart LR
Gateway[Gateway]
Runtime[Embedded Agent Runtime]
Workspace[Workspace]
Session[Session Store]
Tools[Built-in Tools]
Skills[Skills Snapshot]
Gateway --> Runtime
Runtime --> Workspace
Runtime --> Session
Runtime --> Tools
Runtime --> Skills
幾個關鍵點:
- Workspace:
agents.defaults.workspace是工具和上下文的工作目錄,可以理解成 Agent 的辦公桌。 - Bootstrap files:
AGENTS.md、SOUL.md、TOOLS.md等會被注入上下文,是 Agent 的長期工作說明。 - Session store:會話轉錄存為 JSONL,是 Agent 的本輪工作記錄。
- Built-in tools:
read、exec、edit、write等受 tool policy 控制,是 Agent 的手腳。 - Skills:
SKILL.md資料夾會進入提示詞和技能快照,是 Agent 的操作手冊。
這裡最容易誤解的是 TOOLS.md:它不是授權開關。官方說得很明確,核心工具是否存在由 tool policy 決定,TOOLS.md 只是“希望工具怎麼用”的指導。
TOOLS.md 是使用說明,不是授權系統。真正的工具可用性由 tool policy 控制。
2. Agent loop 是一次真實執行
官方對 Agent loop 的定義很直接:
intake → context assembly → model inference → tool execution → streaming replies → persistence
翻譯成中文,就是:
sequenceDiagram
participant U as User
participant G as Gateway
participant R as Agent runtime
participant M as Model
participant T as Tools
participant S as Session
U->>G: message
G->>R: agent run
R->>S: load session and context
R->>M: model inference
M-->>R: assistant text or tool call
R->>T: execute tool if needed
T-->>R: tool result
R->>M: continue with observation
R-->>G: assistant/tool/lifecycle stream
G-->>U: final or streamed reply
R->>S: persist transcript
這就是 Agent 的大腦迴圈。
它不是“先規劃所有步驟,再線性執行”,而是:
- 先把當前訊息、會話、workspace 說明和技能裝進上下文。
- 讓模型判斷下一步是回答、呼叫工具,還是繼續思考。
- 如果呼叫工具,OpenClaw 執行工具並把結果作為 observation 交回模型。
- 模型基於觀察結果繼續生成下一步。
- 直到迴圈結束,再產出可見回覆並寫入會話。
如果你讓 Agent “檢查專案測試為什麼失敗”,一次真實 loop 可能長這樣:
flowchart TD
A[使用者: 檢查測試失敗] --> B[組裝上下文]
B --> C[模型判斷需要讀檔案]
C --> D[read package config]
D --> E[模型判斷需要執行測試]
E --> F[exec test command]
F --> G[讀取失敗日誌]
G --> H[模型定位失敗原因]
H --> I[edit or apply_patch]
I --> J[再次執行測試]
J --> K[最終回覆]
Agent 看起來像在“自主工作”,本質上是模型決策和 OpenClaw 執行層反覆交替。
Agent loop 不是一次 API 呼叫,而是“模型判斷 → 工具執行 → 觀察結果 → 再判斷”的閉環。
3. OpenClaw 在 loop 裡做了哪些系統工作
官方 agent RPC 會先驗證引數、解析 session、持久化 session metadata,然後立刻返回 { runId, acceptedAt }。真正的 Agent 工作隨後進入 agentCommand 和嵌入式 runtime。
從學習角度,不需要先記函式名,但要理解這幾層職責:
| 階段 | OpenClaw 做什麼 | 為什麼重要 |
|---|---|---|
| 接收請求 | 解析 sessionKey / sessionId,建立 runId | 後續可以追蹤這次執行 |
| 準備執行 | 解析模型、thinking、verbose、trace 預設值 | 同一 Agent 可以有穩定預設行為 |
| 載入技能 | 載入或複用 skills snapshot | 本輪知道可用技能 |
| 啟動 runtime | 呼叫嵌入式 Agent runtime | 進入真正的模型-工具迴圈 |
| 事件橋接 | 把 runtime 事件轉成 OpenClaw stream | UI 和聊天渠道可以看到進度 |
| 完成等待 | agent.wait 等 lifecycle end/error | 呼叫方能知道執行是否結束 |
OpenClaw 的關鍵價值在這裡:它不是隻把訊息轉發給模型,而是在模型外面維護會話一致性、工具執行、許可權控制、流式事件和最終回覆。
4. 序列化保證同一個會話不打架
官方文件強調:OpenClaw 的 loop 是 single, serialized run per session。同一個 session key 下的執行會排隊,必要時還會經過全域性佇列。
這解決的是一個現實問題:Agent 會讀寫 session transcript,也可能呼叫 exec、write、edit 等工具。如果同一個會話裡兩個 run 同時改狀態,很容易出現:
- 兩次回覆順序錯亂。
- 工具結果寫進錯誤的輪次。
- session history 被併發覆蓋。
- 使用者後來發的訊息被過早或過晚注入。
所以 OpenClaw 把 Agent loop 當成“一個會話的一次事務性執行”來處理。
flowchart LR
M1[message A] --> L[session lane]
M2[message B] --> L
M3[message C] --> L
L --> R1[run A]
R1 --> R2[run B]
R2 --> R3[run C]
這也是為什麼第二篇講訊息佇列時會提到 collect、steer、followup:這些模式最終都要喂進 session lane,不能繞過會話一致性。
5. Context 決定大腦看見什麼
模型不是憑空推理。它每一步能做什麼,取決於本輪 prompt 裡有什麼。
OpenClaw 在 prompt assembly 階段會組合:
- OpenClaw base prompt。
- skills prompt。
- bootstrap context。
- per-run overrides。
- session messages。
- 模型限制與 compaction reserve tokens。
這解釋了一個常見現象:同樣一個模型,在不同 OpenClaw workspace 裡表現會完全不同。因為它看到的 AGENTS.md、SOUL.md、TOOLS.md、skills 和歷史上下文不同。
可以把大腦分成兩層:模型能力負責語言理解、推理、工具呼叫判斷,主要透過換 model 或 provider 改;上下文工程負責角色、規則、工具習慣、專案知識,主要透過 workspace 檔案、skills、hooks、memory 改。
下一篇會專門講記憶系統,這裡先記住:OpenClaw Agent 的“聰明”不是隻來自模型,也來自上下文裝配。
6. Tools 是 Agent 的可執行能力
工具讓 Agent 從“會說”變成“會做”。
以 exec 為例,官方定義是:在 workspace 中執行 shell commands,支援前臺和後臺執行;如果 process 可用,還可以管理後臺程序。exec 有幾個關鍵引數:
| 引數 | 作用 |
|---|---|
command | 要執行的 shell 命令 |
workdir | 命令工作目錄 |
env | 環境變數覆蓋 |
yieldMs / background | 後臺執行控制 |
timeout | 單次命令超時 |
pty | 需要 TTY 的命令 |
host | auto、sandbox、gateway、node |
security / ask | host/node 執行的策略和審批 |
elevated | sandbox 中請求跳到宿主執行 |
OpenClaw 還會把工具事件作為 tool stream 發出。也就是說,使用者或 UI 不只看到最終答案,還可以看到工具開始、更新、結束。
這對遠端 Agent 很重要:如果 Agent 在微信、Discord、Telegram 或 Control UI 裡執行,你需要知道它正在查檔案、跑命令還是等待審批。
7. Skills 是 Agent 的操作手冊
Tools 解決“能不能做”,Skills 解決“應該怎麼做”。
OpenClaw 使用 AgentSkills-compatible skill folders。每個 skill 是一個目錄,裡面至少有 SKILL.md,透過 YAML frontmatter 描述名稱和用途,再寫具體操作說明。
官方當前的載入優先順序是:
| 優先順序 | 來源 | 路徑 |
|---|---|---|
| 1 | Workspace skills | <workspace>/skills |
| 2 | Project agent skills | <workspace>/.agents/skills |
| 3 | Personal agent skills | ~/.agents/skills |
| 4 | Managed/local skills | ~/.openclaw/skills |
| 5 | Bundled skills | 隨安裝包提供 |
| 6 | Extra skill folders | skills.load.extraDirs |
同名 skill 衝突時,高優先順序覆蓋低優先順序。這裡有兩個實踐結論:
- 專案專用流程放
<workspace>/skills,不要汙染全域性。 - 通用個人習慣放
~/.agents/skills或~/.openclaw/skills,但要知道它會影響很多 Agent。
Skill 還有 allowlist。agents.defaults.skills 可以設預設可見技能,agents.list[].skills 可以替換某個 Agent 的技能集合。非空列表是最終集合,不會和 defaults 合併。
8. 許可權邊界要拆成三層
舊式理解經常把許可權說成“允許 Agent 用工具”一句話。OpenClaw 當前文件把它拆得更清楚:
| 控制層 | 決定什麼 | 典型配置 |
|---|---|---|
| Sandbox | 工具在哪裡執行 | agents.defaults.sandbox.* |
| Tool policy | 哪些工具可用 | tools.*、tools.sandbox.tools.*、agents.list[].tools.* |
| Elevated | sandbox 中的 exec 是否能跳到宿主 | tools.elevated.* |
三個層次不能混為一談。
flowchart TD
A[Agent wants to run exec] --> B{Tool policy allows exec?}
B -- No --> X[blocked]
B -- Yes --> C{Session sandboxed?}
C -- No --> D[host exec policy applies]
C -- Yes --> E{Elevated requested and allowed?}
E -- No --> F[run inside sandbox]
E -- Yes --> G[run on gateway or node with approvals]
幾個硬規則:
deny總是贏。- 如果
allow非空,其他工具預設視為 blocked。 - Tool policy 是硬停止點,
/exec不能覆蓋被 deny 的exec。 /exec只改當前 session 的 exec 預設引數,不授予工具訪問權。- Elevated 隻影響
exec,不授予額外工具,也不覆蓋 tool allow/deny。 /elevated full會跳過 exec approvals,但前提仍然是 elevated 可用且 allowlist 透過。
這部分很關鍵。把許可權層次講清楚,才不會把“工具不可用”“sandbox 裡跑不到宿主路徑”“審批沒過”“skill 沒載入”混成同一個問題。
排查工具問題時先分層:tool policy 是否允許、session 是否 sandboxed、elevated 是否可用、審批是否透過。
9. Hooks 不是一個東西
OpenClaw 現在有兩套容易混淆的 hook:
- Internal hooks:執行在 Gateway 事件指令碼層,適合
/new、/reset、/stop、agent:bootstrap、gateway lifecycle、message events。 - Plugin hooks:執行在外掛內程序擴充套件點,適合改 prompt、攔截 tool call、控制訊息傳送、觀察 session lifecycle。
Internal hooks 的事件包括:
command:newcommand:resetcommand:stopsession:compact:beforesession:compact:afteragent:bootstrapgateway:startupmessage:receivedmessage:preprocessedmessage:sent
Plugin hooks 才包含 before_tool_call、after_tool_call、before_prompt_build、before_agent_reply 等更深的 Agent loop 擴充套件點。
所以實踐上要這樣選:
/new時儲存一份會話摘要:Internal hook。- Gateway 啟動時跑
BOOT.md:Internal hook。 - 在系統 prompt 構建前注入動態上下文:Plugin hook。
- 在工具呼叫前要求審批或改引數:Plugin hook。
- 出站訊息傳送前重寫或取消:Plugin hook。
不要把 internal hook 當成萬能攔截器。它適合事件自動化;真正要進入模型、工具、訊息派發鏈路,應該用 Plugin hooks。
10. Streaming、timeout 和靜默回覆
Agent loop 執行時會發三類主要事件流:lifecycle 負責 start、end、error;assistant 負責 assistant deltas;tool 負責 tool start/update/end。
這也是為什麼 OpenClaw 可以在聊天渠道里邊做邊回,或者在 Control UI 裡展示工具過程。
超時也分層:
agent.wait預設只是等待 30 秒,不代表 Agent 被停止。- Agent runtime 有
agents.defaults.timeoutSeconds,官方預設值是 48 小時。 - Model idle timeout 會在模型長時間沒有輸出 chunk 時中止請求。
exec自己也有每個命令的 timeout。
最終回覆階段還有一個特殊規則:精確的 NO_REPLY / no_reply 會從出站 payload 裡過濾掉。這個能力適合 Agent 已經透過 messaging tool 傳送過可見回覆、或者某些自動化任務不需要再重複確認。
11. 常見誤解
常見誤解可以按這組邊界校正:
- Agent 不是 ChatGPT 套殼。Agent 是 runtime 驅動的迴圈,模型只是其中一層。
- Tool 寫在
TOOLS.md裡不等於能用。工具可用性由 tool policy 決定,TOOLS.md只是指導。 - Skill 不等於工具。Skill 是說明書,工具才是執行能力。
- Hook 不是都能攔截工具呼叫。
before_tool_call屬於 Plugin hooks,不是普通 internal hook。 - Elevated 不等於超級管理員。Elevated 隻影響 sandbox 中的
exec,不能覆蓋 tool policy。 agent.wait超時不等於 Agent 停了。agent.wait只是等待超時,不等於執行被取消。
這些區別看起來細,但後面排障會頻繁用到。
12. 給 Agent 的實踐任務
把下面任務交給你的 OpenClaw Agent,觀察它的過程:
请解释你处理这条消息时会经历哪些阶段:
1. 哪些 workspace 文件会影响你的回答?
2. 你现在有哪些 tools 和 skills?
3. 如果要运行 shell 命令,sandbox、tool policy、elevated 分别会影响什么?
4. 什么时候应该用 internal hook,什么时候应该用 plugin hook?你要看的不是答案是否漂亮,而是它能不能把 runtime、context、tools、skills、policy、hooks 分層說清楚。
如果它把 TOOLS.md 當成授權配置,或者把 before_tool_call 寫成普通 internal hook,就說明這章還沒吃透。
13. 本章自檢
讀完這一篇,你應該能回答:
- 為什麼說 Agent loop 不是一次 API 呼叫?
- OpenClaw 為什麼要按 session 序列化 Agent run?
- Workspace、bootstrap files、session store 分別影響什麼?
- Tools 和 Skills 的邊界是什麼?
- Sandbox、tool policy、elevated 三層分別控制什麼?
- Internal hooks 和 Plugin hooks 的區別是什麼?
NO_REPLY為什麼不會作為普通回覆發出去?
能回答這些問題,再進入下一篇記憶系統,才不會把“Agent 記住了什麼”和“Agent 本輪看見了什麼”混在一起。
14. 接下來去哪
04 · 記憶系統
繼續拆 session history、memory search、compaction、workspace memory 和長期知識。
02 · 一條訊息的旅程
回到訊息鏈路,確認訊息如何進入 runtime、session 和 Agent loop。
官方教程:Agents
對照官方 Agents 頁繼續看 workspace、runtime、tools 和 agent 配置。