Claude Code Hook 進階應用:6 個 Lifecycle Points 和 12+ 實戰場景

Hook 看起來簡單,但它的威力來自於「在正確的時刻介入」。本篇深入 Hook 的生命週期,展示 6 個不同的 Hook 觸發點(lifecycle points),提供 12+ 個實戰場景範例,以及具體的配置和部署步驟。

🔄 Hook 的完整生命週期

Claude Code 在執行工作時,會經過多個檢查點。Hook 就是在這些檢查點上「攔截」執行流程,進行驗證、轉換或防禦。

用戶輸入
  ↓
[PreRequest Hook] ← Hook 1:攔截請求前
  ↓
驗證認證和權限
  ↓
[PreToolUse Hook] ← Hook 2:在工具執行前
  ↓
執行工具(bash、read、edit 等)
  ↓
獲取工具結果
  ↓
[PostToolUse Hook] ← Hook 3:在工具執行後
  ↓
結果驗證和轉換
  ↓
[Stop Hook] ← Hook 4:決定是否需要暫停和修正
  ↓
返回結果給用戶
  ↓
[PostResponse Hook] ← Hook 5:響應後的清理
  ↓
異常處理
  ↓
[OnError Hook] ← Hook 6:異常發生時的恢復
  ↓
完成

📍 6 個 Hook 觸發點詳解

1️⃣ PreRequest Hook(最上游的防禦)

觸發時機:用戶提交請求時,在任何工具執行前

使用場景:

  • 🔴 防禦場景 1:檢查用戶是否試圖讀取敏感檔案(.env, .ssh, .config)
  • 🟠 檢查場景 2:驗證請求是否包含危險關鍵字(git reset –hard, rm -rf)
  • 🟡 轉向場景 3:根據時間或上下文自動拒絕某些類型的請求
# 配置位置:~/.claude/settings.json 或 settings.local.json

{
  "hooks": {
    "pre_request": {
      "enabled": true,
      "rules": [
        {
          "name": "block_sensitive_files",
          "pattern": "(read|cat).*(\\.env|\\.key|\\.ssh|credentials)",
          "action": "block",
          "message": "⚠️ Cannot access sensitive files"
        },
        {
          "name": "warn_destructive",
          "pattern": "git (reset --hard|push --force)|rm -rf",
          "action": "confirm",
          "message": "⚠️ This command is destructive. Continue?"
        }
      ]
    }
  }
}

2️⃣ PreToolUse Hook(工具執行前的最後檢查)

觸發時機:具體工具(bash、read、edit 等)即將執行時

使用場景:

  • 🔴 防禦場景 1:攔截特定工具(禁止 rm、禁止 git push 到 main)
  • 🟠 檢查場景 2:驗證檔案路徑存在性(避免編輯不存在的檔案)
  • 🟡 轉換場景 3:修改命令參數(將 rm 改為 mv to trash)
  • 🟢 記錄場景 4:記錄所有敏感操作的日誌
# 例子:PreToolUse Hook - 禁止直接刪除

{
  "hooks": {
    "pre_tool_use": {
      "enabled": true,
      "rules": [
        {
          "name": "prevent_direct_deletion",
          "tool": "bash",
          "pattern": "^rm ",
          "action": "transform",
          "transform": "echo 'Using rm is disabled. Use: mv $file ~/.trash' && false"
        },
        {
          "name": "verify_branch_safety",
          "tool": "bash",
          "pattern": "git push.*main",
          "action": "confirm",
          "message": "Push to main? This is permanent."
        },
        {
          "name": "auto_backup_on_edit",
          "tool": "edit",
          "action": "pre_action",
          "command": "cp {file} {file}.backup"
        }
      ]
    }
  }
}

3️⃣ PostToolUse Hook(工具執行後的驗證和轉換)

觸發時機:工具執行完畢,獲得結果後

使用場景:

  • 🟡 驗證場景 1:檢查 bash 命令是否成功(exit code = 0)
  • 🟠 轉換場景 2:格式化輸出(JSON 格式化、表格美化)
  • 🟢 記錄場景 3:自動保存重要操作結果
  • 🔵 優化場景 4:清理大型輸出(截斷日誌)
# 例子:PostToolUse Hook - 自動格式化和驗證

{
  "hooks": {
    "post_tool_use": {
      "enabled": true,
      "rules": [
        {
          "name": "validate_bash_success",
          "tool": "bash",
          "action": "validate",
          "check": "exit_code == 0",
          "on_fail": "log_error"
        },
        {
          "name": "auto_format_json",
          "tool": "bash",
          "pattern": "jq|json",
          "action": "transform",
          "transform": "jq '.' (automatically format JSON output)"
        },
        {
          "name": "save_large_results",
          "tool": "bash",
          "pattern": "curl|wget",
          "action": "post_action",
          "command": "save_to_file ~/.cache/last_result.json"
        },
        {
          "name": "truncate_verbose_output",
          "tool": "bash",
          "action": "transform",
          "condition": "output_size > 10000",
          "transform": "head -100 + '... (truncated {remaining} lines)'"
        }
      ]
    }
  }
}

4️⃣ Stop Hook(驗證器決策點)

觸發時機:結果返回給用戶前,決定是否需要暫停和修正

使用場景:

  • 🔴 驗證場景 1:JSON 格式驗證(無效 JSON 需要修正)
  • 🟠 邏輯場景 2:檢查結果合理性(SQL 查詢應該有行,否則可能是錯誤)
  • 🟡 決策場景 3:判斷結果是否完整(檔案大小是否符合預期)
# 例子:Stop Hook with Validator - JSON 驗證和自動修復

{
  "hooks": {
    "stop_hook": {
      "enabled": true,
      "validator": {
        "name": "json_validator",
        "rules": [
          {
            "id": "valid_json",
            "check": "is_valid_json(result)",
            "on_fail": "stop_and_request_fix",
            "message": "JSON is malformed. Please fix and retry.",
            "auto_attempt": 3
          },
          {
            "id": "non_empty_result",
            "check": "len(result) > 10",
            "on_fail": "warn",
            "message": "Result might be incomplete (too short)"
          },
          {
            "id": "api_error_check",
            "check": "'error' not in result.lower()",
            "on_fail": "stop_and_request_fix",
            "message": "API returned an error. Review and retry."
          }
        ]
      }
    }
  }
}

5️⃣ PostResponse Hook(執行後的清理和通知)

觸發時機:結果已返回給用戶,工作完成後

使用場景:

  • 🟢 清理場景 1:刪除臨時檔案(/tmp 下的中間結果)
  • 🔵 通知場景 2:記錄到監控系統(重要操作記錄)
  • 🟣 統計場景 3:更新執行統計(執行次數、成功率)
# 例子:PostResponse Hook - 清理和通知

{
  "hooks": {
    "post_response": {
      "enabled": true,
      "rules": [
        {
          "name": "cleanup_temp_files",
          "action": "cleanup",
          "targets": ["/tmp/*.temp", "/tmp/claude-*"],
          "condition": "age > 1h"
        },
        {
          "name": "log_sensitive_operations",
          "action": "log",
          "condition": "tool in ['bash', 'edit'] AND (git|deploy|delete) in command",
          "log_file": "~/.claude/audit.log"
        },
        {
          "name": "notify_on_error",
          "action": "notify",
          "condition": "exit_code != 0",
          "channels": ["stderr", "log_file"]
        }
      ]
    }
  }
}

6️⃣ OnError Hook(異常情況處理)

觸發時機:工具執行失敗或發生異常時

使用場景:

  • 🔴 恢復場景 1:自動回滾(某個命令失敗,執行恢復操作)
  • 🟠 重試場景 2:自動重試(網絡超時自動重試)
  • 🟡 降級場景 3:使用備選方案(API 1 失敗,嘗試 API 2)
# 例子:OnError Hook - 自動恢復和重試

{
  "hooks": {
    "on_error": {
      "enabled": true,
      "rules": [
        {
          "name": "auto_retry_network_errors",
          "error_pattern": "(timeout|connection refused|ECONNREFUSED)",
          "action": "retry",
          "max_attempts": 3,
          "backoff": "exponential"
        },
        {
          "name": "rollback_on_git_error",
          "error_pattern": "git (push|merge|rebase)",
          "action": "execute",
          "command": "git reset --hard HEAD"
        },
        {
          "name": "fallback_api_endpoint",
          "error_pattern": "api1\\.example\\.com",
          "action": "retry_with",
          "new_command": "replace(api1, api2)"
        }
      ]
    }
  }
}

🛠️ 如何正確配置和部署 Hook

步驟 1:選擇配置位置

  1. 全局配置:~/.claude/settings.json(所有項目適用)
  2. 項目級配置:{project}/.claude/settings.local.json(單個項目)
  3. 團隊配置:{team}/.claude/team-settings.json(團隊共享)

🔵 最佳實踐

敏感規則(.env 保護、刪除防禦)→ 全局 settings.json

項目特定規則(特定分支政策、特定工具限制)→ settings.local.json

步驟 2:編寫 Hook 規則

Hook 規則的通用結構:

{
  "hook_type": "pre_tool_use",      // 觸發點
  "name": "rule_name",               // 規則名稱
  "tool": "bash",                    // 適用工具(可選)
  "pattern": "regex_pattern",        // 匹配模式(可選)
  "action": "block|confirm|transform|validate", // 動作類型
  "condition": "expression",         // 執行條件(可選)
  "message": "User-facing message",  // 給用戶的提示
  "auto_attempt": 3,                 // 自動重試次數(可選)
  "transform": "transformation",     // 轉換規則(如果 action=transform)
  "on_fail": "action_on_failure"    // 失敗時的行動
}

步驟 3:驗證 Hook 配置

# 1. 檢查 JSON 語法
jq '.' ~/.claude/settings.json

# 2. 列出所有啟用的 Hook
claude config list-hooks --enabled

# 3. 測試特定 Hook(乾跑)
claude hook test --name rule_name --dry-run

# 4. 查看 Hook 日誌
tail -f ~/.claude/hooks.log

步驟 4:分層部署(由簡到複雜)

  1. 第 1 周:安全防禦
    • PreRequest Hook:阻止敏感檔案讀取
    • PostToolUse Hook:驗證 bash 執行成功
  2. 第 2 周:工作流驗證
    • Stop Hook:JSON 驗證
    • PostToolUse Hook:自動格式化
  3. 第 3 周:錯誤恢復
    • OnError Hook:自動重試
    • PostResponse Hook:清理臨時檔案

📋 12+ 個實戰範例速查表

範例 Hook 類型 動作 效果
保護 .env 檔案 PreRequest Block 永不讀取敏感檔案
防止 git reset –hard PreToolUse Confirm 需要確認才能執行
禁止直接 rm PreToolUse Transform 改為移到回收站
自動格式化 JSON PostToolUse Transform 自動美化輸出
驗證 JSON 有效性 Stop Validate 無效 JSON 拒絕返回
自動備份編輯檔案 PreToolUse Pre-action 編輯前自動備份
日誌敏感操作 PostResponse Log 所有敏感操作記錄
網絡超時自動重試 OnError Retry 最多重試 3 次
清理臨時檔案 PostResponse Cleanup 自動刪除 /tmp
驗證 bash 成功 PostToolUse Validate exit code ≠ 0 時警告
截斷大型輸出 PostToolUse Transform > 10KB 自動截斷
API 故障轉移 OnError Fallback 用備選 API 重試

⚠️ Hook 配置的常見陷阱

陷阱 1:規則太寬鬆,誤傷正常操作

❌ 錯誤:
"pattern": "read"  // 任何包含 "read" 的命令都會觸發

✅ 正確:
"pattern": "read (.*\\.env|\\.key|\\.credentials)"  // 只針對特定檔案

陷阱 2:Hook 順序錯誤導致邏輯失效

❌ 錯誤順序:
1. PostToolUse(驗證)
2. PreToolUse(保護)  ← 太晚了,工具已經執行了

✅ 正確順序:
1. PreToolUse(攔截和保護)
2. PostToolUse(驗證結果)
3. Stop(決定是否修正)

陷阱 3:Transform 規則語法錯誤

❌ 錯誤:
"transform": "cmd.replace('old', 'new')"  // Python 語法,但 Hook 是 shell

✅ 正確:
"transform": "sed 's/old/new/g'"  // Shell 語法
或
"transform": "replace(cmd, old, new)"  // Hook 提供的函數

✅ Hook 部署檢查清單

  • ☐ 配置檔案 JSON 語法正確(jq 驗證通過)
  • ☐ Hook 規則的 pattern 足夠明確(不會誤傷)
  • ☐ PreToolUse 規則在最關鍵的地方(防禦第一)
  • ☐ Stop Hook 驗證邏輯清晰(什麼時候拒絕)
  • ☐ OnError Hook 有適當的重試邏輯
  • ☐ 測試了至少一個完整工作流
  • ☐ 查看日誌確認 Hook 被正確觸發
  • ☐ 團隊成員知道有這些 Hook(溝通重要)

🔗 與其他文章的連結

📚 延伸閱讀

總結:Hook 的 6 個層次

  • 🎯 L1:PreRequest(最上游,全局防禦)
  • 🎯 L2:PreToolUse(工具前,細粒度保護)
  • 🎯 L3:PostToolUse(結果驗證和轉換)
  • 🎯 L4:Stop(決策點,是否修正)
  • 🎯 L5:PostResponse(清理和通知)
  • 🎯 L6:OnError(異常恢復)

掌握這 6 個層次,你就能在任何地方「攔截」執行流程,實現你想要的保護和自動化。

留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *