別只會用 Codex:Hook 才是進階玩法

整理 Codex Hook 的核心用法:它能在 Codex 的關鍵生命週期事件中執行自訂腳本,適合做隱私檢查、命令審查、會話記錄、結果校驗和團隊規範約束。

很多人用 Codex 時,重點都放在「讓它幫我寫程式碼、改檔案、跑命令」。這當然是 Codex 最直觀的能力,但如果只停留在這裡,很容易忽略一個更適合進階使用的功能:Hook

Hook 的價值不在於讓 Codex 更會寫程式碼,而在於讓 Codex 更按規矩工作。它可以在 Codex 的關鍵生命週期事件裡執行自訂腳本,例如使用者提交 prompt 時、工具呼叫前、工具呼叫後、請求權限時、會話停止時等。這樣一來,你可以把團隊規則、安全檢查、隱私保護和自動化記錄放進 Codex 的工作流裡,而不是每次都靠人工提醒。

一個典型例子是隱私檢查:當使用者把 prompt 發給 Codex 前,先用 Hook 掃一遍是否包含 API key、token、私鑰、手機號、內部位址或其他敏感資訊。如果命中規則,就阻止這次提交,或者給出明確提示,讓使用者先清理內容。

Hook 是什麼

Codex Hook 可以理解為 Codex 工作流裡的生命週期處理器。它會在指定事件發生時觸發,並把目前上下文以 JSON 形式傳給你的腳本。腳本可以回傳提示資訊、附加上下文,也可以在部分事件裡阻止後續動作。

官方文件裡提到,Hook 可以用於這些場景:

  • 把對話傳送到自訂日誌或分析系統;
  • 掃描團隊 prompt,阻止誤貼 API key;
  • 自動總結對話,生成持久記憶;
  • 在一輪對話結束時執行自訂校驗;
  • 根據目前目錄補充特定提示或規則。

所以 Hook 更像一層「工作流控制」和「安全護欄」,而不是普通的提示詞技巧。提示詞告訴 Codex 應該怎麼做,Hook 則能在 Codex 做事前後插入檢查、記錄和約束。

Hook 放在哪裡

Codex 可以從 hooks.json 載入 Hook,也可以從 config.toml 裡的 [hooks] 表載入內聯配置。常用位置有四個:

  • ~/.codex/hooks.json
  • ~/.codex/config.toml
  • <repo>/.codex/hooks.json
  • <repo>/.codex/config.toml

使用者級 Hook 適合放個人通用規則,例如「不要把疑似密鑰發送出去」「每次結束時做摘要」。專案級 Hook 適合放倉庫規範,例如「禁止直接改生成目錄」「提交前檢查 front matter」「執行命令前攔截危險操作」。

需要注意的是,專案級 .codex/ 配置只有在該專案層被信任後才會載入;使用者級 Hook 則不依賴專案是否被信任。這個設計很重要,因為專案裡的 Hook 本質上是會執行本地腳本的配置,不能對陌生倉庫無條件信任。

常見觸發時機

Hook 不是只有一個觸發點。不同事件適合不同用途。

UserPromptSubmit 發生在使用者 prompt 即將提交時。它適合做隱私檢查、敏感詞檢查、提示詞規範檢查。比如發現 prompt 裡疑似包含 sk- 開頭的 key,就直接阻止提交。

PreToolUse 發生在 Codex 呼叫工具前。它適合攔截命令、檔案寫入或 MCP 工具呼叫。例如檢測到 rm -rf、向系統目錄寫檔案、讀取敏感路徑,就回傳拒絕理由。

PermissionRequest 發生在 Codex 準備請求權限時。它適合自動批准或拒絕某些明確的權限請求。比如團隊可以允許固定的測試命令自動通過,但拒絕存取某些目錄。

PostToolUse 發生在工具執行後。它適合檢查命令輸出、掃描生成檔案、提醒後續步驟。它不能撤銷已經發生的副作用,但可以讓 Codex 在繼續前看到額外回饋。

SessionStart 發生在會話開始或恢復時。它適合載入專案約定、團隊規範、常用上下文或本地提示。

Stop 發生在一輪回應準備停止時。它適合做收尾檢查,例如確認是否執行測試、是否還存在 TODO、是否需要繼續補一輪驗證。

一個隱私檢查 Hook 應該怎麼設計

隱私檢查最適合放在 UserPromptSubmit,因為它發生在使用者內容真正進入 Codex 工作流之前。設計時不要追求一步到位,先覆蓋最容易誤貼的內容就夠了。

可以優先檢查這些模式:

  • OpenAI、GitHub、雲廠商等 API key;
  • -----BEGIN PRIVATE KEY----- 這類私鑰塊;
  • .env 檔案片段;
  • 存取令牌、Bearer token、JWT;
  • 內網域名、資料庫連線字串;
  • 身分證、手機號、電子郵件等個人資訊。

Hook 腳本接收 JSON 輸入後,讀取其中的 prompt 欄位,使用正則或規則表掃描。如果發現問題,可以回傳阻止結果:

1
2
3
4
{
  "decision": "block",
  "reason": "檢測到疑似 API key,請先移除敏感資訊後再提交。"
}

也可以不阻止,只回傳額外上下文,讓 Codex 在後續回答中注意某些約束。不過對於密鑰、私鑰和令牌這類高風險內容,更穩妥的做法是直接阻止。

hooks.json 配置示例

如果使用倉庫級配置,可以建立 .codex/hooks.json

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python .codex/hooks/privacy_check.py",
            "timeout": 10,
            "statusMessage": "Checking prompt privacy"
          }
        ]
      }
    ]
  }
}

對應的腳本可以從標準輸入讀取 JSON:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import json
import re
import sys

payload = json.load(sys.stdin)
prompt = payload.get("prompt", "")

patterns = [
    r"sk-[A-Za-z0-9_-]{20,}",
    r"ghp_[A-Za-z0-9_]{20,}",
    r"-----BEGIN [A-Z ]*PRIVATE KEY-----",
    r"Bearer\s+[A-Za-z0-9._-]{20,}",
]

for pattern in patterns:
    if re.search(pattern, prompt):
        print(json.dumps({
            "decision": "block",
            "reason": "檢測到疑似密鑰、令牌或私鑰,請先移除敏感資訊。"
        }, ensure_ascii=False))
        raise SystemExit(0)

這個示例只演示思路,實際使用時應該把規則拆成可維護的列表,並控制誤報。比如普通文件裡出現 Bearer 示例不一定就是洩露,專案裡也可能有專門用於測試的假 key。規則越嚴格,越容易誤攔;規則越寬鬆,越容易漏掉真正的風險。

config.toml 內聯寫法

如果不想單獨維護 hooks.json,也可以寫在 config.toml 裡。官方文件示例中,內聯 TOML Hook 和 hooks.json 使用同樣的事件結構:

1
2
3
4
5
6
7
8
[[hooks.PreToolUse]]
matcher = "^Bash$"

[[hooks.PreToolUse.hooks]]
type = "command"
command = 'python ".codex/hooks/pre_tool_use_policy.py"'
timeout = 30
statusMessage = "Checking Bash command"

如果同一層配置裡同時存在 hooks.json 和內聯 [hooks],Codex 會同時載入並給出警告。實際專案裡最好二選一,避免規則分散後難以排查。

使用 Hook 時要注意什麼

第一,Hook 會執行本地命令,所以一定要審查來源。非託管 Hook 需要被 review 和 trust 後才會執行;Hook 內容變化後,也需要重新信任。陌生倉庫裡的 .codex/hooks.json 不應該隨便放行。

第二,多個匹配的 Hook 可能都會執行。不要假設只有一個 Hook 能攔住所有事情,也不要把規則寫得互相衝突。團隊環境裡要明確哪些是使用者級規則,哪些是專案級規則,哪些是管理員託管規則。

第三,Hook 是護欄,不是完整安全邊界。比如 PreToolUse 可以攔截很多工具呼叫,但官方也明確提示,它還不能覆蓋所有 shell 呼叫路徑,也不能攔截所有非 shell、非 MCP 工具。真正高風險的場景仍然需要權限配置、沙箱、程式碼審查和最小權限配合。

第四,Hook 腳本要快。隱私掃描、命令審查這類 Hook 發生在互動鏈路中,如果腳本每次跑幾十秒,會直接拖慢體驗。能用規則完成的事情,不要每次都呼叫大型外部服務。

第五,輸出格式要嚴格。不同事件支援的回傳欄位不完全一樣。比如 UserPromptSubmit 可以用 decision: "block" 阻止 prompt,PreToolUse 則有自己的 hookSpecificOutput 結構。寫 Hook 前先看對應事件的輸入輸出約定,不要混用欄位。

哪些場景最值得先做 Hook

如果剛開始用 Hook,不建議一下子做成複雜的企業級策略系統。可以先從三個小場景開始。

第一個是隱私檢查。它最容易帶來真實收益,也最適合個人和團隊通用。誤貼密鑰、token、.env 片段,是 AI 編程工作流裡很現實的問題。

第二個是危險命令攔截。可以針對 BashPreToolUse 做基礎規則,例如阻止遞迴刪除、阻止改寫系統目錄、阻止向未知遠端上傳檔案。

第三個是收尾檢查。用 StopPostToolUse 提醒 Codex 在結束前確認測試、構建、格式化、文件和未提交改動。這類 Hook 不一定要強制阻斷,但能顯著減少「差一步就收工」的情況。

結論

Codex Hook 的進階之處,不是讓 Codex 多一個花俏功能,而是把「規則」接進了 Codex 的執行循環。

普通用法裡,你靠 prompt 告訴 Codex 應該怎麼做;進階用法裡,你用 Hook 在關鍵節點檢查它是否按規矩做。隱私檢查、命令審查、權限策略、會話摘要、結束前校驗,這些都可以從口頭提醒變成可執行的工作流。

如果你已經開始把 Codex 用在真實專案裡,Hook 值得盡早配置。它不替代人工判斷,也不替代沙箱和權限控制,但它能把很多容易遺忘的安全和流程要求,變成每次都會自動觸發的預設動作。

參考來源:OpenAI Codex Advanced Configuration - HooksOpenAI Codex Hooks

记录并分享
使用 Hugo 建立
主題 StackJimmy 設計