跳到主要內容
Lab Grimoire
TW EN
請喝咖啡
Hook 守門系統:AI 寫的每一行 code 都過品管
動手實作

Hook 守門系統:AI 寫的每一行 code 都過品管

Agent 工作流實戰 · 第 6/19 篇
本頁目錄

想像一下,你的 AI 助手把整個專案資料夾「一鍵拆房」了

每天 120 次檔案操作,一次失控就夠了。

你有沒有算過,一個 AI Agent 每天幫你執行多少次檔案操作?我算過。平均 120 次以上。不誇張。這 120 次裡,只要有一次失控,就夠你哭了。

有一次讓 Claude Code 幫我整理專案目錄。它很認真地判斷某些檔案「看起來不需要了」。然後直接 rm -rf。整個工作目錄砸爛了。就像一個新來的實習生拿著碎紙機把整個檔案櫃都絞了。真的。那個工作目錄沒有即時備份。

什麼感覺?像看著自己的硬碟被格式化,手放在鍵盤上來不及按 Ctrl+C。

那之後我只學到一件事。AI Agent 再聰明,沒有守門員就不能讓它碰檔案系統。沒有。不能。就這樣。

以下介紹我後來建的防線:Hook 守門系統。就像在你家大門裝上安檢門。每個進出的包裹都要過 X 光。沒錯。Claude Code 的 hooks 機制怎麼運作?怎麼設定?我實際在用的幾條守門規則是什麼?這是我整套 AI Agent 系統裡最早建的安全層。原因很簡單。教訓來得最早。

Hook 守門系統是一種 AI Agent 品管機制,透過在工具呼叫前(PreToolUse,出門前檢查清單)與呼叫後(PostToolUse,回家後的驗收)插入檢查腳本,自動攔截危險操作、驗證輸出品質,確保 AI 的每次動作都通過預設的安全與品質關卡。

Hook 守門系統運作示意圖

Claude Code 的 Hooks 機制

內建功能,不用額外安裝。

先講好消息。Claude Code 原生內建 hooks 功能。不是外掛。不用另外裝。設定好就能跑。很簡單。就像你的大樓本來就有警衛室。只是你還沒告訴警衛要查什麼。

兩種觸發時機:

  • PreToolUse(出門前檢查清單):AI 準備呼叫某個工具「之前」觸發,用來攔截、審查、阻止危險操作。就像你出門前摸口袋:鑰匙帶了沒?瓦斯關了沒?
  • PostToolUse(回家後的驗收):AI 完成工具呼叫「之後」觸發,用來驗證結果、自動修正、跑測試。像你網購收到包裹,拆開來檢查東西對不對。

白話講:PreToolUse 是進料檢查。原料有問題就擋在門外。PostToolUse 是成品檢查。做完再驗一次。兩道關卡。中間是 AI 的操作。就這樣。

設定位置

設定寫在專案根目錄的 .claude/settings.json。這份設定檔就像守門員的工作手冊。誰能進?誰該擋?進來之後查什麼?全寫在裡面。基本結構:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/check-frontmatter.sh",
            "timeout": 5
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/auto-test.sh",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

關鍵欄位:

欄位 說明
matcher 指定觸發的工具名稱,支援正則表達式,也就是偵測暗語的密碼表(如 Edit|Write 表示兩者都觸發)
type 目前只有 command 一種,執行 shell 指令
command 實際執行的腳本路徑
timeout 超時秒數,超過就跳過此 hook

實戰:攔截一鍵拆房指令,強制軟刪除

踩坑之後最快寫出來的那條規則。

我建的第一條規則。也是踩坑之後用最快速度寫出來的那條。

問題很直接。AI 整理檔案時可能呼叫 rm。這個一鍵拆房指令。刪掉了,沒版控沒備份?就像把房子炸了才發現存摺還在抽屜裡。永別了。解法是在 PreToolUse 插一個守門員。掃描即將執行的 Bash 指令裡有沒有 rm。有?直接擋。告訴 AI 改用 mv 搬到 _DELETE_ 前綴的位置。不是拆房。是先搬到倉庫。確定不要了再處理。

核心邏輯:

#!/bin/bash
# .claude/hooks/protect-sensitive-files.sh
# 讀取 AI 即將執行的工具輸入
INPUT=$(cat /dev/stdin)

# 檢查是否包含 rm 指令
if echo "$INPUT" | grep -qE '\brm\b'; then
  echo "BLOCKED: 偵測到 rm 指令。"
  echo "請改用 mv 檔案 _DELETE_檔案,保留回溯時間線。"
  exit 1
fi

exit 0

腳本回傳 exit code 非 0?Claude Code 就擋下那次工具呼叫。把訊息丟回給 AI。就像守門員把可疑包裹退回去。附上一張紙條:「這個不行,換個方式再來。」沒錯。AI 看到「請改用 mv」,就會自己改寫指令重來。

這條規則上線之後?誤刪事件:零。三個月了。零。不誇張。過去誤刪率大約 8%。上了 hook 之後直接歸零。這個守門員從不打瞌睡。也不會罷工。

實戰:Markdown frontmatter 自動檢查

漏 frontmatter 的機率直接歸零。

我的系統裡所有 Markdown 文件都要有 YAML frontmatter。title、date、tags 之類的。AI 偶爾會忘記加。偶爾是客氣的說法。剛開始大概每五個檔案就漏一個。漏件率約 20%。真的。

解法一樣。在出門前檢查清單上多加一項。AI 要寫入 .md 檔案?守門員先翻開來看第一頁。有沒有完整的 frontmatter?沒有?退件。就這樣:

#!/bin/bash
# .claude/hooks/check-md-frontmatter.sh
INPUT=$(cat /dev/stdin)

# 只檢查 .md 檔案
FILE_PATH=$(echo "$INPUT" | grep -o '"file_path":"[^"]*"' | head -1)
if ! echo "$FILE_PATH" | grep -q '\.md"'; then
  exit 0
fi

# 檢查是否有 frontmatter 開頭
CONTENT=$(echo "$INPUT" | python3 -c "
import sys, json
data = json.load(sys.stdin)
print(data.get('content', ''))
" 2>/dev/null)

if ! echo "$CONTENT" | head -1 | grep -q '^---'; then
  echo "WARNING: Markdown 檔案缺少 YAML frontmatter。"
  echo "請確保檔案開頭有 --- 包裹的 YAML 區塊。"
  exit 1
fi

exit 0

從此以後,所有 AI 產出的 Markdown 都得過這關。漏 frontmatter 的情況?直接歸零。沒錯。歸零。

實戰:寫入後自動跑程式碼品質工具

寫完自動驗貨,我最爽的一條 hook。

這條是我最爽的一條 hook。AI 寫完 Python 程式碼,可能有未使用的 import。格式亂掉。甚至語法錯誤。結果呢?回家後的驗收機制直接在每次寫入或編輯 .py 檔之後自動跑 ruff 跟 pytest。就像工廠產線尾端的品管員。每件成品都要過手檢查才能出貨:

{
  "matcher": "Edit|Write",
  "hooks": [
    {
      "type": "command",
      "command": "bash .claude/hooks/ruff-autofix.sh",
      "timeout": 10
    },
    {
      "type": "command",
      "command": "bash .claude/hooks/auto-pytest.sh",
      "timeout": 30
    }
  ]
}

ruff hook 自動修正格式。移除未使用的 import 之類。pytest hook 跑相關測試。測試沒過?AI 收到錯誤訊息。自己試著修。就這樣。

這形成了一個自動回饋迴圈。寫 code。守門員驗貨。退件。AI 修正。守門員再驗。放行。就像乒乓球來回彈。直到品質過關才停。整個過程不需要人介入。真的。我試過最誇張的一次,AI 連修了四輪才通過所有測試。程式碼品質提升約 2 倍。我在旁邊喝咖啡。

Hook 自動回饋迴圈示意圖

我目前的 Hook 清單

前門攔截加後門驗收,共 5 項

我目前實際在用的 hook 配置:

Hook 類型 matcher 功能 timeout
PreToolUse Write Markdown frontmatter 檢查 5s
PreToolUse Edit|Write 敏感檔案保護(攔截對記憶檔、設定檔的未授權修改) 5s
PostToolUse Edit|Write ruff 自動修正(Python 檔案) 10s
PostToolUse Edit|Write 程式碼審查關卡 10s
PostToolUse Edit|Write 自動跑 pytest 30s

總共 5 個守門員。兩個站前門。負責出門前檢查清單。三個站後門。負責回家後的驗收。邏輯很簡單。前門管「不該做的別做」。後門管「做完了要確認品質」。不多不少。就像一間小公司的品管部門。人不多但每個人盯一個關卡。

設計 Hook 的幾個原則

快、清楚、一次加一個。

跑了幾個月,幾條心得:

快。 守門員動作要快。不能讓排隊的人等到不耐煩。PreToolUse 我設 5 秒 timeout。PostToolUse 設 10 到 30 秒。超過 30 秒的檢查?別放在安檢門裡。拆出去當獨立步驟。太慢的 hook 會拖垮整個工作流。AI 等你的守門員跑完它才能動。很簡單。

訊息要清楚。 擋下操作時,輸出訊息要讓 AI 知道「為什麼被擋」跟「該怎麼改」。我犯過一次錯。訊息只寫「操作被拒絕」。結果呢?AI 就一直用同一個指令重試。重試了五次才放棄。很煩。寫清楚「請改用 mv」?AI 第一次就會改。

PreToolUse 只攔不改。 攔截跟警告就好。別在 hook 裡直接修改 AI 的輸入。讓 AI 自己根據回饋修正。它會在那次對話裡「記住」正確做法。

一次加一個。 別一口氣請十個守門員。你會 debug 到瘋掉。從最痛的問題開始。通常是一鍵拆房的誤刪檔案。確認能跑再加下一個。我的五個守門員是三個月內慢慢疊上去的。就像蓋房子先打地基再砌牆。

值得注意的是,Hook 也有侷限。它只能攔截 Claude Code 原生支援的工具呼叫。如果 AI 透過其他管道操作檔案?比如在 Python 腳本裡寫 os.remove()?hook 攔不到。沒辦法。這不是萬能盾牌。是第一道防線。就這樣。

Hook 守門系統 vs 傳統 CI/CD

定位不同,粒度差在即時與延遲。

寫過軟體的人可能覺得:「這不就是 CI/CD pipeline 嗎?」對。有像。但定位完全不同:

面向 CI/CD Pipeline Hook 守門系統
觸發時機 git push / PR 建立 AI 每次工具呼叫
回饋對象 開發者(人) AI Agent
回饋速度 數分鐘到數十分鐘 數秒
主要目的 部署前品保 即時防護 + 即時修正
操作粒度 整個 commit 單次檔案操作

關鍵差異在粒度。CI/CD 像是月底盤點庫存。問題可能已經存在半小時了。Hook 守門員是每筆交易當場驗。抓到就擋。沒錯。兩者不衝突。可以並存。守門員管即時品管。CI/CD 管部署前的完整測試。

常見問題

以下回應常見疑問,包括這套做法的限制與潛在風險。

Q:Hook 會不會讓 AI 變慢?

A:會。但幾乎感覺不到。出門前檢查清單通常 1-2 秒。回家後的驗收跑 ruff/pytest 大約 5-15 秒。AI 自己回應就要 10-30 秒了。守門員那點延遲根本不痛。而且想想看。不裝安檢門的話,出錯之後你要花多久修?上次我花了 40 分鐘在追一個被 AI 搞壞的設定檔。花 2 秒過安檢門,還是花 40 分鐘收拾殘局?

Q:所有專案都需要 Hook 嗎?

A:看情況。如果你的 AI 只拿來聊天、不碰檔案?守門員沒什麼用。但只要 AI 會寫檔案、執行指令、改設定?至少在前門裝一個「防一鍵拆房」的安檢門。就一個。五分鐘的事。可以救你一整個專案。

Q:Hook 腳本寫錯了會怎樣?

A:hook 腳本本身出錯?語法錯或執行失敗?Claude Code 會跳過那個 hook。不會擋住 AI 操作。預設行為是「放行」。不是「全擋」。但寫完 hook 還是手動測一次。別上線才發現腳本根本跑不動。

Q:可以用 Hook 來限制 AI 只能操作特定目錄嗎?

A:可以。PreToolUse hook 裡檢查 AI 要操作的檔案路徑,不在允許的目錄範圍就擋下。我就是用這個方法保護記憶系統的核心檔案。避免 AI 不該改的時候動到它們。

Q:Hook 有沒有被繞過的風險?

A:有。Hook 只攔截 Claude Code 工具呼叫層的操作。如果 AI 在 bash 腳本裡呼叫其他腳本?而那個腳本裡面包含危險操作?hook 不一定能偵測到巢狀指令。沒辦法。所以安全規則不能只靠 hook。還要搭配 CLAUDE.md 裡的軟約束跟 CI/CD 的最終防線。一層不夠,就多疊幾層。就像你家鑰匙壞了不會只補漆了事。得換鎖。

Q:Hook 跟 CLAUDE.md 裡寫規則有什麼差別?

A:CLAUDE.md 裡的規則是軟約束。就像公司的員工手冊。大家大多數時候會遵守。但偶爾就是會忘。Hook 守門員是硬約束。像裝在門口的實體門禁卡。腳本寫死的檢查不會被忘記。AI 再怎麼「創意詮釋」也刷不過去。真的。最穩的做法:CLAUDE.md 定原則。守門員做把關。軟硬兼施。


想更深入?

Hook 守門系統搭配Skill 路由引擎效果更好。路由引擎像 GPS 確保 AI 走對的路線。守門員確保每一站都過品管。安全設計的完整哲學在AI Agent 安全底線設計

我整理了一份《Claude Code 快速上手速查表》。安裝、CLAUDE.md 配置、記憶系統基礎、常用指令一頁搞定。

免費下載速查表

下一篇:多平台同步:一套記憶跑遍 Claude/Copilot/Gemini

常見問題

Hook 會不會讓 AI 變慢?

會,但幅度很小。PreToolUse 通常在 1-2 秒內完成,PostToolUse 的 ruff/pytest 大約 5-15 秒。相比 AI 自己的回應時間(通常 10-30 秒),hook 增加的延遲可以接受。這些品管節省的是「出錯後花半小時修復」的時間。

所有專案都需要 Hook 嗎?

不一定。如果 AI 操作範圍很小(比如只是對話、不涉及檔案操作),hook 意義不大。但只要 AI 會寫檔案、執行指令、修改設定,建議至少有一個「防誤刪」的 PreToolUse hook。

Hook 腳本寫錯了會怎樣?

如果 hook 腳本本身出錯(語法錯誤或執行失敗),Claude Code 會跳過該 hook,不會阻擋 AI 操作。這是安全的預設行為。建議寫完 hook 後手動測試一次,確認腳本能正常執行。

可以用 Hook 來限制 AI 只能操作特定目錄嗎?

完全可以。在 PreToolUse hook 裡檢查 AI 要操作的檔案路徑,如果不在允許的目錄範圍內就擋下。這是「敏感檔案保護」hook 的核心邏輯。

Hook 跟 CLAUDE.md 裡寫規則有什麼差別?

CLAUDE.md 裡的規則是「軟約束」,AI 通常會遵守但偶爾會忘記。Hook 是「硬約束」,寫成腳本的檢查不會被忘記,也不會被 AI 的創意詮釋繞過。兩者搭配最有效:CLAUDE.md 設定原則,Hook 執行把關。

覺得這篇有幫助?

追蹤以收到新的 AI × 生醫研究筆記:

或請我喝杯咖啡,讓新內容持續產出。

☕ 請我喝杯咖啡