Claude Code Hooks 完整指南:14 種事件、3 種類型,打造 AI 編碼的自動化護欄 技術指南

重點摘要:Hooks 是 Claude Code 的事件驅動自動化系統,讓你在 AI 執行操作的每一個關鍵節點插入自訂邏輯。支援 14 種生命週期事件(從 Session 啟動到結束)、3 種 Hook 類型(shell 命令、LLM 判斷、Agent 驗證)。最強大的能力是 PreToolUse——在 AI 執行任何工具之前攔截,可以阻止危險操作、自動核准安全指令、甚至修改工具參數。這是 Claude Code 獨有的能力,Codex CLI 和 Gemini CLI 都沒有對應功能。1

什麼是 Hooks?

想像你僱了一個非常能幹的 AI 助手。它可以讀寫檔案、執行命令、搜尋程式碼。但你不想讓它毫無限制地做任何事——你想要護欄。

Hooks 就是這些護欄。它們是你預先定義的規則,在 Claude Code 的生命週期中自動觸發。不需要你每次下指令,不需要 AI「記得」要遵守——它們是確定性的(deterministic),100% 會執行。

一個簡單的例子:

// 每次 Claude 要執行 Shell 命令之前,自動檢查是否有 rm -rf
PreToolUse → matcher: "Bash" → 你的腳本檢查命令內容 → 阻止或放行

這就是 Hooks 的核心:在 AI 做事之前或之後,插入你的邏輯。

14 種事件:完整的生命週期覆蓋

Claude Code 的每個操作都被拆解為事件。你可以在任何一個節點掛上 Hook。

Session 生命週期

事件 觸發時機 可阻止? 典型用途
SessionStart 對話開始或恢復時 否 載入環境變數、偵測專案類型
SessionEnd 對話結束時 否 清理暫存檔、紀錄統計
PreCompact Context 壓縮前 否 保存重要上下文、注入摘要

使用者互動

事件 觸發時機 可阻止? 典型用途
UserPromptSubmit 使用者送出訊息,Claude 處理前 是 輸入驗證、敏感資訊過濾
Notification Claude 發送通知時 否 macOS 原生通知、Slack 推播

工具執行(最常用)

事件 觸發時機 可阻止? 典型用途
PreToolUse ⭐ 工具執行之前 是 安全檢查、自動核准、參數修改
PermissionRequest 權限對話框即將出現時 是 自動核准安全操作、攔截危險操作
PostToolUse 工具執行成功之後 否 自動格式化、觸發測試
PostToolUseFailure 工具執行失敗之後 否 錯誤紀錄、自動重試邏輯

Agent 與任務管理

事件 觸發時機 可阻止? 典型用途
Stop Claude 完成回應時 是 檢查任務是否真的完成
SubagentStart 子 Agent 啟動時 否 安全驗證、資源管控
SubagentStop 子 Agent 完成時 是 輸出品質驗證
TeammateIdle 團隊中的 Agent 即將閒置 是 品質閘門、防止過早結束
TaskCompleted 任務即將標記為完成 是 完成條件驗證

3 種 Hook 類型

1. Command Hook(Shell 命令)

最常用的類型。執行一個 Shell 腳本,透過 stdin 接收 JSON 輸入,用 exit code 控制行為。

{
  "type": "command",
  "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/security_check.py",
  "timeout": 60
}

適合:快速確定性檢查、檔案操作、外部工具整合。

2. Prompt Hook(LLM 判斷)

把決策交給一個輕量 LLM(通常是 Haiku)。它會根據 context 做出 yes/no 判斷。

{
  "type": "prompt",
  "prompt": "檢查以下操作是否安全:$ARGUMENTS。如果涉及刪除或修改系統檔案,回傳 deny。",
  "timeout": 30
}

適合:需要理解語意的判斷(例如「這段程式碼看起來有安全風險嗎?」)。

3. Agent Hook(多步驟驗證)

啟動一個有工具存取權(Read、Grep、Glob)的子 Agent,最多 50 個 tool-use 回合。

{
  "type": "agent",
  "prompt": "驗證修改是否符合專案規範:$ARGUMENTS",
  "timeout": 60
}

適合:複雜的多步驟驗證(例如檢查修改是否破壞其他檔案的相依性)。

三種類型比較

面向 Command Prompt Agent
速度 < 1 秒 3-30 秒 10-60 秒
邏輯類型 確定性規則 語意判斷 多步驟推理
額外成本 無 API tokens API tokens(更多)
可讀取檔案 透過腳本 只看 context Read/Grep/Glob
支援 async 是 否 否

Exit Code:Hook 的溝通語言

Command Hook 透過 exit code 告訴 Claude Code 下一步該怎麼做:

Exit Code 意義 行為
0 成功 放行。stdout 的 JSON 會被解析處理
2 阻止 操作被攔截。stderr 的文字回饋給 Claude
其他 非阻止性錯誤 操作照常進行,stderr 只在 verbose 模式顯示

這個設計的精妙之處:exit code 2 的 stderr 會直接回饋給 Claude,所以 AI 會「看到」你的攔截原因並據此調整行為。例如:

#!/bin/bash
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command // empty')

# 攔截 rm -rf
if [[ "$command" == *"rm -rf"* ]]; then
  echo "禁止使用 rm -rf。請使用更安全的刪除方式。" >&2
  exit 2  # Claude 會看到這個訊息,改用其他方法
fi

exit 0  # 放行

PreToolUse:最強大的事件

PreToolUse 是 Hooks 系統的核心。它在權限系統之前執行,擁有三種決策能力:

// JSON 輸出(exit 0 時)
{
  "hookSpecificOutput": {
    "permissionDecision": "allow",  // 或 "deny" 或 "ask"
    "permissionDecisionReason": "此操作已由 Hook 自動核准",
    "updatedInput": {               // 可以修改工具參數!
      "command": "npm run lint --fix"
    }
  }
}
  • "allow" — 直接放行,跳過權限對話框(使用者不會被詢問)
  • "deny" — 直接阻止,理由回饋給 Claude
  • "ask" — 交給使用者決定(顯示權限對話框)

updatedInput 更厲害——你可以偷偷修改 Claude 要執行的命令。例如強制加上 --dry-run 或修改檔案路徑。

配置層級

Hooks 可以在多個層級定義,優先順序由低到高:

位置 範圍 可共享?
~/.claude/settings.json 所有專案(全域) 否(本機)
.claude/settings.json 單一專案 是(可 commit)
.claude/settings.local.json 單一專案 否(gitignored)
Plugin hooks/hooks.json Plugin 啟用時 是(隨 Plugin)
Skill/Agent YAML frontmatter 元件執行時 是(定義在元件中)
組織管理政策 全組織 是(管理員控制)

配置範例(.claude/settings.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/validate-bash.sh"
          }
        ]
      },
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/protect-files.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write",
            "async": true
          }
        ]
      }
    ],
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude 需要你的注意\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

環境變數

變數 可用範圍 用途
$CLAUDE_PROJECT_DIR 所有 Hook 專案根目錄路徑
${CLAUDE_PLUGIN_ROOT} Plugin Hook Plugin 根目錄(可攜式路徑)
$CLAUDE_ENV_FILE 僅 SessionStart 寫入此檔案可持久化環境變數
$CLAUDE_CODE_REMOTE 所有 Hook 遠端環境時設為 "true"

$CLAUDE_ENV_FILE 是 SessionStart 的獨特能力。寫入這個檔案的環境變數,會在整個 Session 中持續生效:

#!/bin/bash
# SessionStart Hook:自動偵測專案類型
cd "$CLAUDE_PROJECT_DIR" || exit 1

if [ -f "package.json" ]; then
  echo "export PROJECT_TYPE=nodejs" >> "$CLAUDE_ENV_FILE"
  echo "export NODE_ENV=development" >> "$CLAUDE_ENV_FILE"
elif [ -f "Cargo.toml" ]; then
  echo "export PROJECT_TYPE=rust" >> "$CLAUDE_ENV_FILE"
elif [ -f "requirements.txt" ]; then
  echo "export PROJECT_TYPE=python" >> "$CLAUDE_ENV_FILE"
fi

exit 0

Matcher:精準過濾

Matcher 使用正規表達式決定 Hook 在哪些工具上觸發:

Pattern 匹配對象
Bash 只匹配 Bash 工具
Edit|Write Edit 或 Write 工具
mcp__.* 所有 MCP 工具
mcp__rss__.* RSS MCP 的所有工具
* 或省略 所有工具
注意:工具名稱是 PascalCase。寫 bash 不會匹配 Bash,而且不會有任何錯誤提示——Hook 就是靜默地不觸發。這是最常見的配置錯誤。

10 個實戰場景

1. 阻止危險的 Shell 命令

// PreToolUse + matcher: "Bash"
// 攔截 rm -rf、git push --force、DROP TABLE 等

2. 保護敏感檔案

// PreToolUse + matcher: "Edit|Write"
// 阻止修改 .env、credentials.json、*.pem

3. 自動格式化程式碼

// PostToolUse + matcher: "Edit|Write" + async: true
// 修改檔案後自動跑 prettier / black / rustfmt

4. 桌面通知

// Notification + command
// Claude 需要你注意時,發送 macOS 原生通知或 Slack 訊息

5. 自動設定開發環境

// SessionStart + CLAUDE_ENV_FILE
// 偵測專案類型,自動載入對應的環境變數

6. 安全掃描(我們在用的)

// PreToolUse + matcher: "Edit|Write|MultiEdit"
// 每次修改檔案前,掃描 SQL injection、XSS、command injection

7. 自動核准安全操作

// PreToolUse + matcher: "Bash"
// ls、pwd、echo、git status 等安全命令自動放行,不再彈權限對話框

8. 非同步測試

// PostToolUse + matcher: "Write|Edit" + async: true
// 修改檔案後在背景自動跑測試,不阻塞 Claude 繼續工作

9. 任務完成驗證

// Stop + type: "prompt"
// Claude 說「完成了」之前,讓 LLM 檢查是否真的全部做完

10. MCP 工具限流

// PreToolUse + matcher: "mcp__.*"
// 限制 MCP 工具的呼叫頻率,避免打爆外部 API

限制與注意事項

1. 啟動時快照,Session 中不可修改

Claude Code 在啟動時擷取 Hooks 的快照。Session 進行中修改設定檔不會生效,必須重啟或在 /hooks 選單中重新載入。這是安全設計,防止 Session 中途被注入惡意 Hook。

2. Stop Hook 無限迴圈

Stop Hook 可以阻止 Claude 停止,導致它繼續對話然後再次觸發 Stop,形成迴圈。必須檢查 stop_hook_active:

#!/bin/bash
INPUT=$(cat)
if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
  exit 0  # 已在 Stop Hook 中,直接放行
fi
# ... 你的檢查邏輯

3. Shell Profile 污染

.zshrc 或 .bashrc 中的 echo 輸出會污染 JSON 解析,導致 Hook 靜默失敗。解法:

# 在 .zshrc 中,只在互動模式才輸出
if [[ $- == *i* ]]; then
  echo "Shell ready"
fi

4. PostToolUse 無法撤銷

PostToolUse 在工具已經執行完之後才觸發。它能記錄、能通知,但不能撤銷已經發生的操作。想攔截必須用 PreToolUse。

5. PermissionRequest 不在 Headless 模式觸發

用 claude -p(headless/非互動模式)時,PermissionRequest Hook 不會觸發。CI/CD 場景要改用 PreToolUse。

6. 平行執行,無法互相依賴

同一事件的多個 Hook 平行執行,不保證順序。不能讓 Hook A 的結果影響 Hook B。

7. Exit Code 與 JSON 互斥

Exit code 2 時,stdout 的 JSON 會被忽略。想用 JSON 控制行為,必須 exit 0。兩者不能混用。

完整的 stdin 輸入格式

每個 Hook 透過 stdin 接收 JSON。所有事件共享的基礎欄位:

{
  "session_id": "abc123",
  "transcript_path": "/path/to/transcript.json",
  "cwd": "/current/working/dir",
  "permission_mode": "default",  // default|plan|acceptEdits|dontAsk|bypassPermissions
  "hook_event_name": "PreToolUse"
}

各事件會加上自己的特定欄位:

  • PreToolUse / PostToolUse:tool_name、tool_input(如 file_path、command)
  • UserPromptSubmit:user_prompt
  • Stop / SubagentStop:reason、stop_hook_active
  • SessionStart:source(startup/resume/compact)

與 Codex / Gemini 的比較

能力 Claude Code Hooks Codex CLI Gemini CLI
事件驅動自動化 14 種事件 無 無
攔截工具執行 PreToolUse 沙盒隔離 無
自動核准/拒絕 allow/deny/ask 無 無
修改工具參數 updatedInput 無 無
LLM 驅動判斷 prompt/agent Hook 無 無
安全護欄方式 細粒度行為控制 檔案系統沙盒 權限提示

Codex 選擇了沙盒隔離策略——把 Agent 關在圍欄裡。Claude Code 選擇了行為監控策略——讓 Agent 自由行動,但在每個關鍵節點安裝攝影機和警報器。兩種哲學各有優劣:沙盒更簡單安全,Hooks 更靈活強大。

結論:從「信任 AI」到「驗證 AI」

Hooks 體現了一個重要的理念轉變:從被動地信任 AI 的判斷,到主動地在每個節點驗證 AI 的行為。

這不是不信任 AI——而是工程上的最佳實踐。就像你不會讓 production server 裸奔而不設 monitoring 和 alerting,你也不應該讓 AI coding agent 在沒有任何護欄的情況下操作你的程式碼。

Hooks 讓這種護欄變得確定性的、自動的、可程式化的。它把 AI 安全從「希望 AI 記得遵守規則」提升到「系統層級保證規則被執行」。

這是 Claude Code 在 AI 編碼工具競爭中最獨特的差異化——不是模型更聰明或速度更快,而是給開發者最細粒度的控制權。

參考資料

  1. Anthropic, "Claude Code Hooks Reference", Official Documentation
  2. Anthropic, "Automate Workflows with Hooks", Official Guide
  3. Disler, "Claude Code Hooks Mastery", GitHub
  4. aiorg.dev, "Claude Code Hooks: Complete Guide with 20+ Examples"
  5. Pixelmojo, "Claude Code Hooks for Production Quality CI/CD Patterns"