---
title: "用 Hooks 接入自動檢查"
description: "基於官方 Codex Hooks 教程，講清 hooks 能做什麼、不能做什麼，以及如何從低風險檢查開始。"
verifiedAt: "2026-05-06"
---

import { Cards, Card } from 'fumadocs-ui/components/card';

Hooks 是 Codex 的擴充套件機制：在會話、提示詞提交、工具呼叫、許可權請求、工具呼叫結束、turn 停止等節點執行指令碼。它適合做自動檢查、日誌記錄、策略提醒和團隊規範執行。

> [!CAUTION]
> Hook 不是讓 Codex 更聰明的魔法。它是在工作流旁邊插入指令碼；指令碼寫錯了，會打斷體驗、洩露資訊，甚至放大許可權風險。

<Cards>
  <Card title="Hooks" href="https://developers.openai.com/codex/hooks">
    官方 Hooks 配置、事件、matcher 和輸出格式。
  </Card>
  <Card title="Build plugins" href="/zh-Hant/docs/codex/official/03-extensions/69-build-plugins">
    需要分發生命週期配置時，再把 hook 放進 plugin。
  </Card>
  <Card title="Approvals" href="/zh-Hant/docs/codex/official/02-config-security/07-approval-security">
    Hooks 不能替代 sandbox、approval 和程式碼審查。
  </Card>
</Cards>

## 它解決什麼

```mermaid
flowchart LR
    Prompt["UserPromptSubmit"] --> Check["敏感資訊 / 範圍檢查"]
    Tool["PreToolUse"] --> Policy["命令 / 路徑策略"]
    Result["PostToolUse"] --> Review["輸出審查"]
    Stop["Stop"] --> Continue["遺漏驗證時繼續"]
```

Hooks 適合做邊界清楚的檢查：

- 使用者提交 prompt 前，檢查是否誤貼上 API key。
- 工具執行前，檢查危險命令或禁止路徑。
- 許可權請求時，把團隊策略加到審批環節。
- 工具執行後，審查輸出或補充上下文。
- turn 停止時，要求再跑一次驗證。

Hooks 不適合做複雜業務邏輯，也不適合替代測試框架。它應該只做“是否允許繼續”“是否補充上下文”“是否提示使用者注意”的輕量決策。

## 啟用和載入位置

Hooks 需要在 `config.toml` 開啟 feature：

```toml
[features]
codex_hooks = true
```

Codex 會在 active config layers 旁邊發現：

- `hooks.json`
- `config.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 後，相同任務能恢復正常，說明沒有留下額外副作用。

## 官方資料

- [Hooks](https://developers.openai.com/codex/hooks)
- [Build plugins: bundled lifecycle config](https://developers.openai.com/codex/plugins/build#bundled-mcp-servers-and-lifecycle-config)
- [Agent approvals and security](https://developers.openai.com/codex/agent-approvals-security)
