跳至主要內容
精選 Hooks Automation Tutorial

Claude Code Hooks:打造自動化開發工作流程

Claude Code Hooks 新手入門教學。從零開始學習 Hooks,附 10 個以上實用範例、常見錯誤排除與最佳實踐指南。

2026年1月19日 12 分鐘閱讀 作者:Claude World

想讓 Claude Code 自動執行 lint、測試和安全檢查嗎?Hooks 就是你需要的功能。本教學帶你從零開始,掌握 Hooks 的概念與實際應用。


什麼是 Hooks?

簡單來說,Hooks 是攔截 Claude 行動的機制

你下指令 → [Hook 攔截] → Claude 執行 → [Hook 檢查] → 完成

你可以在以下幾個時間點注入自訂邏輯:

時機Hook 名稱用途
工具執行PreToolUse阻擋危險操作、加入提醒
工具執行PostToolUse自動 lint、執行測試
任務完成時Stop確保測試通過後才結束
Session 啟動時SessionStart載入環境、顯示資訊

5 分鐘快速入門

步驟 1:建立設定檔

在你的專案目錄中建立 .claude/settings.json

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'File written!'",
            "onFailure": "ignore"
          }
        ]
      }
    ]
  }
}

步驟 2:測試 Hook

啟動 Claude Code:

claude

請 Claude 建立任意檔案:

你:建立一個 hello.txt 檔案,內容是 "Hello World"

你會看到 Claude 建立檔案後輸出 File written!

恭喜!你的第一個 Hook 已經在運作了。


核心概念

Hook 結構

每個 Hook 設定由三個部分組成:

{
  "hooks": {
    "EventName": [
      {
        "matcher": "要攔截的工具",
        "hooks": [
          {
            "type": "command 或 prompt",
            "command": "要執行的指令",
            "onFailure": "失敗處理方式"
          }
        ]
      }
    ]
  }
}

Matchers

Matcher說明
"Write"只攔截 Write 工具
"Edit"只攔截 Edit 工具
"Bash"只攔截 Bash 工具
"Read"只攔截 Read 工具
"*"攔截所有工具
"Write|Edit"攔截 Write 或 Edit

Hook 類型

1. Command Hook(執行指令)

{
  "type": "command",
  "command": "npm run lint",
  "onFailure": "warn"
}

2. Prompt Hook(使用 AI 判斷)

{
  "type": "prompt",
  "prompt": "檢查這個指令是否安全。如果包含 rm -rf,回傳 'block'。否則回傳 'approve'。"
}

onFailure 選項

選項行為
"block"指令失敗時阻擋操作
"warn"顯示警告但繼續執行
"ignore"忽略失敗

10 個實用範例

1. 自動格式化(寫入後 Lint)

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATHS\"",
            "onFailure": "warn"
          }
        ]
      }
    ]
  }
}

2. 自動執行測試

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm test -- --passWithNoTests",
            "onFailure": "warn"
          }
        ]
      }
    ]
  }
}

3. 阻擋危險指令

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "檢查指令是否包含危險操作(rm -rf、DROP TABLE、git push --force)。如果是,回傳 'block'。否則回傳 'approve'。"
          }
        ]
      }
    ]
  }
}

4. 防止讀取機密檔案

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "如果檔案路徑包含 .env、secret、credential、password,回傳 'block'。否則回傳 'approve'。"
          }
        ]
      }
    ]
  }
}

5. 檢查 API 金鑰洩漏

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "掃描內容中是否有 API 金鑰(sk_、api_key、token)。如果找到,回傳 'block' 並說明原因。否則回傳 'approve'。"
          }
        ]
      }
    ]
  }
}

6. 強制測試通過才能結束

{
  "hooks": {
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "npm test",
            "onFailure": "block"
          }
        ]
      }
    ]
  }
}

7. 顯示 Session 啟動訊息

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Claude Code 已啟動 - 專案:'$(basename $(pwd))",
            "onFailure": "ignore"
          }
        ]
      }
    ]
  }
}

8. TypeScript 型別檢查

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx tsc --noEmit",
            "onFailure": "warn"
          }
        ]
      }
    ]
  }
}

9. Git Commit 前置檢查

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "如果指令是 git commit 或 git push,確認測試已通過。如果不確定,回傳 'ask' 詢問使用者。否則回傳 'approve'。"
          }
        ]
      }
    ]
  }
}

10. 敏感目錄保護

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "如果檔案在 auth/、payment/、admin/ 目錄中,回傳 'ask' 要求確認。否則回傳 'approve'。"
          }
        ]
      }
    ]
  }
}

常見錯誤排除

錯誤 1:Hook 沒有觸發

症狀:已設定 Hook 但沒有執行

確認清單

  1. JSON 格式是否正確?用 jq . .claude/settings.json 驗證
  2. Matcher 拼寫是否正確?(Write 不是 write
  3. 檔案位置是否正確?(.claude/settings.json
  4. 是否重新啟動了 Claude?

解法

# 驗證 JSON 格式
cat .claude/settings.json | jq .

# 重新啟動 Claude
claude

錯誤 2:Command Hook 執行失敗

症狀Hook command failed with exit code X

常見原因

  • 找不到指令路徑
  • 權限不足
  • 指令本身有錯誤

解法

# 先手動測試指令
npm test

# 確認指令在 PATH 中
which npm

錯誤 3:Prompt Hook 的判斷不如預期

症狀:Hook 做出錯誤判斷或沒有回應

改善方式

不好的 prompt

{
  "prompt": "檢查這是否安全"
}

好的 prompt

{
  "prompt": "檢查指令是否包含 'rm -rf'。如果是,回傳 'block'。否則回傳 'approve'。只回傳這兩個值之一。"
}

錯誤 4:環境變數問題

症狀$CLAUDE_FILE_PATHS 是空的

解法:只有特定 Hook 事件才有對應的變數

變數可用的 Hook
$CLAUDE_FILE_PATHSPostToolUse(Write/Edit 之後)
$CLAUDE_PROJECT_DIR所有 Hook

錯誤 5:無限迴圈

症狀:Hook 觸發 Hook,陷入迴圈

原因:Hook 執行的指令又觸發了另一個 Hook

解法:使用更精確的 matcher,或避免在指令中觸發其他工具


最佳實踐

1. 從簡單開始

不要一次設定太多 Hook。先從一個開始:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'File written!'",
            "onFailure": "ignore"
          }
        ]
      }
    ]
  }
}

2. 適當使用 onFailure

情境建議設定
測試必須通過"onFailure": "block"
Lint 可以有警告"onFailure": "warn"
非關鍵性檢查"onFailure": "ignore"

3. 分層設定

PreToolUse → 防止危險操作(安全性)
PostToolUse → 自動化檢查(品質)
Stop → 確認完成標準(交付)

4. 團隊共用

.claude/settings.json 加入 Git,讓團隊共享相同的 Hooks:

git add .claude/settings.json
git commit -m "Add Claude Code hooks for team standards"

完整設定範例

以下是適合大多數專案的起始設定:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "檢查指令是否包含危險操作(rm -rf、DROP、--force)。如果是,回傳 'block'。否則回傳 'approve'。"
          }
        ]
      },
      {
        "matcher": "Read",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "如果路徑包含 .env 或 secret,回傳 'block'。否則回傳 'approve'。"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint -- --quiet 2>/dev/null || true",
            "onFailure": "ignore"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "npm test -- --passWithNoTests 2>/dev/null",
            "onFailure": "warn"
          }
        ]
      }
    ],
    "SessionStart": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "echo '專案:'$(basename $(pwd))",
            "onFailure": "ignore"
          }
        ]
      }
    ]
  }
}

下一步

學完 Hooks 基礎後,推薦繼續閱讀:

  1. Hooks 完整指南 - 進階設定與更多範例
  2. Hooks 開發手冊 - 腳本開發細節
  3. TDD 工作流程 - 用 Hooks 實現 TDD
  4. 安全最佳實踐 - 安全相關的 Hook 設定

總結

你想要…使用這個 Hook
阻擋危險操作PreToolUse + prompt
自動 lint/測試PostToolUse + command
確保完成前測試通過Stop + command
Session 啟動時執行SessionStart + command

記住:Hooks 把「建議」變成「強制執行」。設定一次,永久生效。


最後更新:2026-01-19