目錄
2 分鐘閱讀 2026

八個讓 AI Agent 百分之百照做的 Hook

CLAUDE.md 的規則大概有八成會被遵守。Hook 則是百分之百執行。六個月測試下來,這八個從來沒被我移除過。

CLAUDE.md 是建議,不是命令。寫下「提交前先跑 Prettier」,大約三次裡就有一次會被跳過。把規則寫得更詳細也沒用。八成的遵從率不是模型能力的問題,而是結構上的限制:規則放在 context window 裡,只能靠模型決定要不要理會。

Hook 運作在完全不同的層次。它是在特定生命週期節點自動執行的腳本,不管模型怎麼決策都照跑。PreToolUse 在 Agent 修改檔案或執行指令的前一刻觸發,PostToolUse 在之後觸發。模型沒有選擇要不要執行的餘地,它就是會跑。

實際感受差異立刻就出來了。在 CLAUDE.md 加十行規則,跟在 .claude/settings.json 裡加一個 Hook,是完全不同層級的介入。Exit code 2 直接封鎖 Agent 的動作,exit code 0 放行,其他 exit code 記錄警告但不阻擋。因為 Hook 存在 settings.json 裡,提交一次之後整個團隊就透過 git 共享了。

執行前的四道關卡

我跑 Hook 超過六個月了。這四個 PreToolUse Hook 在每個專案上都活了下來,一次都沒被移除。

封鎖危險指令透過正規表示式比對 rm -rfgit reset --hardDROP TABLE 等破壞性指令,比對到就回傳 exit code 2,在動作發生前就掐掉。我親眼看過 Agent 試圖對不該碰的目錄跑 rm -rf。沒有這個 Hook,損失會是真實的。

保護敏感檔案攔截任何試圖修改 .envpackage-lock.json*.pem 等檔案的動作。Agent 連覆寫 lock 檔案或把憑證洩漏到 commit 裡的機會都沒有。

開 PR 前先跑測試把建立 pull request 的動作鎖定在測試通過之後。把 matcher 設成 mcp__github__create_pull_request,Agent 就真的無法在測試失敗的狀態下開 PR。「下次 PR 再補測試」這種事不會再發生。

記錄所有指令把 Agent 執行的每一條 bash 指令連同時間戳記寫進 .claude/command-log.txt。三天後發現哪裡不對,可以追溯到底發生過什麼。

執行後的三道檢查

PostToolUse Hook 在 Agent 修改完檔案後立即執行。我把三個串在一起依序跑。

自動格式化對每個被修改的檔案跑 Prettier。Python 專案換成 Black,Go 專案換成 gofmt。不管 Agent 有沒有記得格式化,格式化都會發生。

自動 Lint格式化完馬上跑 ESLint。ESLint 發現錯誤,Agent 立刻就知道,在同一輪就修掉。能進到人工 code review 的 lint 問題幾乎降到零。

自動測試每次檔案變動後跑相關的測試套件。測試失敗,Agent 幾秒內就知道並嘗試修正。輸出用 tail -5 只保留摘要,避免測試輸出把 context window 塞爆。

執行順序很重要。Prettier 先,再 ESLint,再測試。人看到程式碼的時候,格式和 lint 都已經過了。code review 上的風格意見幾乎消失。

Agent 停下來之後保住工作成果

Stop Hook 只需要一個:自動 commit。每次 Agent 完成一個回應就跑 git add -A && git commit。每一個工作單位都有自己的 commit,兩個任務不會混進同一個 commit。

搭配 git worktree 使用,就能在 feature branch 上自動得到以分支為單位的 commit。Agent 崩潰或你手動中斷,最後一段工作也不會消失。

哪些地方沒那麼順

Hook 串接聽起來很優雅,但一個串鏈失敗的時候,比除錯單一腳本難得多。自動測試 Hook 開始無聲失敗,因為測試執行器在新專案裡根本沒裝,我花了一個小時追 Agent 為什麼一直在生沒測試過的程式碼。問題是 Hook 回傳了 exit code 0,因為找不到指令這件事被 shell 當成非阻擋條件處理掉了。最後必須在呼叫測試執行器之前先加上明確的存在性檢查。

效能是另一個限制。常見的擔心是 Hook 多了會變慢,但問題其實不在總數。真正的問題是每一個 Hook 能不能在 200 毫秒內跑完。Prettier 對單一檔案大約 50ms,ESLint 大約 80ms,測試視範圍而定,但只跑受影響的檔案多數都能控制在快的範圍。哪個 Hook 超過一秒,Agent 的回饋迴圈就會開始感覺遲鈍。

為什麼這跟更大的格局是同一件事

OpenAI 的 Harness Engineering 部落格提到,Agent 在嚴格的邊界和可預測的結構裡表現最好。React 的設計哲學對元件說的也是同一件事:有明確生命週期的可組合單元。

Claude Code 的 Hook 遵循同樣的抽象。狀態對應 session 和記憶體,Hook 是在生命週期邊界上介入的函式。PreToolUse 設定邊界,PostToolUse 讓結構可以預期,Stop 保住結果。

以前我在 CLAUDE.md 裡放著「跑 Prettier」這行規則。現在那行不見了。Hook 每次都會跑,不用開口要求。

訂閱電子報

獲取最新 AI 洞見。