用 Hooks 接入自動檢查
基於官方 Codex Hooks 教程,講清 hooks 能做什麼、不能做什麼,以及如何從低風險檢查開始。
Hooks 是 Codex 的擴充套件機制:在會話、提示詞提交、工具呼叫、許可權請求、工具呼叫結束、turn 停止等節點執行指令碼。它適合做自動檢查、日誌記錄、策略提醒和團隊規範執行。
Hook 不是讓 Codex 更聰明的魔法。它是在工作流旁邊插入指令碼;指令碼寫錯了,會打斷體驗、洩露資訊,甚至放大許可權風險。
Hooks
官方 Hooks 配置、事件、matcher 和輸出格式。
Build plugins
需要分發生命週期配置時,再把 hook 放進 plugin。
Approvals
Hooks 不能替代 sandbox、approval 和程式碼審查。
它解決什麼
flowchart LR
Prompt["UserPromptSubmit"] --> Check["敏感資訊 / 範圍檢查"]
Tool["PreToolUse"] --> Policy["命令 / 路徑策略"]
Result["PostToolUse"] --> Review["輸出審查"]
Stop["Stop"] --> Continue["遺漏驗證時繼續"]
Hooks 適合做邊界清楚的檢查:
- 使用者提交 prompt 前,檢查是否誤貼上 API key。
- 工具執行前,檢查危險命令或禁止路徑。
- 許可權請求時,把團隊策略加到審批環節。
- 工具執行後,審查輸出或補充上下文。
- turn 停止時,要求再跑一次驗證。
Hooks 不適合做複雜業務邏輯,也不適合替代測試框架。它應該只做“是否允許繼續”“是否補充上下文”“是否提示使用者注意”的輕量決策。
啟用和載入位置
Hooks 需要在 config.toml 開啟 feature:
[features]
codex_hooks = trueCodex 會在 active config layers 旁邊發現:
hooks.jsonconfig.toml裡的 inline[hooks]
常見位置:
~/.codex/hooks.json~/.codex/config.toml<repo>/.codex/hooks.json<repo>/.codex/config.toml
專案本地 hooks 只會在專案 .codex/ layer 受信任時載入。一個層級裡不要同時維護 hooks.json 和 inline hooks;官方會合並並給 warning,但新手排障會更難。
事件怎麼選
UserPromptSubmit:使用者輸入發給模型前。適合檢查敏感資訊、任務範圍、是否需要補充上下文。PreToolUse:工具執行前。適合攔截危險 shell、禁止路徑、提醒確認。PermissionRequest:許可權請求時。適合把團隊審批策略放進請求前後。PostToolUse:工具執行後。適合審查命令輸出或把額外上下文反饋給 Codex。Stop:turn 結束時。適合發現測試沒跑、文件沒同步時讓 Codex 繼續。SessionStart:session 啟動、恢復或清空時載入上下文。
注意兩個細節:
UserPromptSubmit和Stop當前不使用 matcher。PreToolUse、PermissionRequest、PostToolUse的 matcher 過濾 tool name,例如Bash、apply_patch或 MCP tool name。
第一版怎麼做
第一版只做一個只讀 hook,例如在 UserPromptSubmit 上檢查 prompt 是否包含疑似 key。不修改檔案,不執行復雜命令。
第二版再做 PreToolUse,只針對 Bash 或 apply_patch。matcher 要窄,不要全域性匹配所有工具。
第三版再做 PostToolUse 或 Stop。這時你已經知道 hook 輸入輸出長什麼樣,也知道它對體驗的影響。
不要一開始就把所有事件都掛上指令碼。官方說明,同一個 event 上多個匹配 command hooks 會併發啟動,一個 hook 不能阻止另一個匹配 hook 啟動。
輸出語義要寫對
所有 command hook 都會從 stdin 收到一個 JSON 物件,常見欄位包括 session id、當前 cwd、hook event name、模型、turn id 等。
UserPromptSubmit 可以輸出額外 developer context,也可以 block prompt。
PostToolUse 發生在工具完成後,所以它不能撤銷已經執行的 Bash 命令。它能把反饋傳回 Codex,讓後續處理從 hook 反饋繼續。
Stop 的 block 不是拒絕本輪,而是讓 Codex 繼續,並把 reason 作為 continuation prompt。Stop 退出 0 時需要輸出 JSON,plain text 對這個事件無效。
常見坑
- Hook 裡做太多事:它應該短、小、可預測。
- matcher 太寬:每次操作都觸發指令碼,體驗會變慢,也更容易誤攔截。
- 忘記併發:多個匹配 hooks 會併發啟動。
- 把 prompt、cwd、tool input、token 寫進日誌。
- 以為
PostToolUse能撤銷命令。 - 忽略
Stop的 continuation 語義。 - 在不受信任專案裡期待 project hook 生效。
驗收清單
- 啟動後沒有 hooks 配置 warning。
- 目標事件確實觸發。
- hook 能收到必要欄位,但日誌不儲存敏感內容。
- 允許時不打斷流程,攔截時給出人能理解的原因。
- 指令碼異常、超時或輸出非法 JSON 時,Codex 行為符合預期。
- 關閉 hook 後,相同任務能恢復正常,說明沒有留下額外副作用。