09 - Hooks 自動化
← 08-Subagents與平行工作 | 00-Index | 下一篇 → 10-MCP與外部工具
Hook 是什麼、為什麼重要
Hook 是你定義的 shell 指令,Claude Code 在生命週期的特定時點執行它。
🔑 關鍵價值:確定性。 某件事一定會發生,而不是靠 LLM 決定要不要做。
這就是 06-CLAUDE-md與記憶系統 那句話的解方——CLAUDE.md 是上下文(軟),hook 是執行(硬)。
三種 hook:
- 一般 hook:跑 shell 指令
- Prompt-based hook:用 Claude 模型判斷條件(需要判斷而非死規則時)
- Agent-based hook:用一個 agent 評估
設定位置與格式
寫在 settings 檔案(~/.claude/settings.json、.claude/settings.json、.claude/settings.local.json)的 hooks 區塊。也可以綁在 skill 或 subagent 的 frontmatter 裡。
基本結構:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$CLAUDE_FILE_PATHS\""
}
]
}
]
}
}在 session 裡看目前設定:
/hooks
全部 hook 事件
| 事件 | 觸發時機 |
|---|---|
SessionStart | session 開始或 resume 時 |
Setup | --init-only,或 -p 模式下的 --init / --maintenance。給 CI / 腳本的一次性準備 |
UserPromptSubmit | 你送出 prompt 後、Claude 處理前 |
UserPromptExpansion | 你打的指令展開成 prompt、送到 Claude 之前。可以擋下展開 |
PreToolUse | 工具呼叫執行前。可以擋下它 ← 最常用 |
PermissionRequest | 工具呼叫需要權限決定時 |
PermissionDenied | 被 auto mode classifier 拒絕時。回傳 {retry: true} 可讓模型重試 |
PostToolUse | 工具呼叫成功後 |
PostToolUseFailure | 工具呼叫失敗後 |
PostToolBatch | 一整批平行工具呼叫都結束後、下一次模型呼叫前 |
Notification | Claude Code 送通知時 |
MessageDisplay | 助理訊息文字顯示時 |
SubagentStart / SubagentStop | subagent 生成 / 結束 |
TaskCreated / TaskCompleted | 任務建立 / 標記完成 |
Stop | Claude 回覆完畢 |
StopFailure | 因 API 錯誤結束該輪(輸出與 exit code 會被忽略) |
TeammateIdle | agent team 的隊友即將 idle |
InstructionsLoaded | CLAUDE.md 或 .claude/rules/*.md 載入 context 時 ← 除錯神器 |
ConfigChange | session 期間設定檔變更 |
CwdChanged | 工作目錄改變(例如 Claude 執行 cd) |
DirectoryAdded | 中途用 /add-dir 加目錄 |
FileChanged | 被監看的檔案在磁碟上變更(matcher 指定要看哪些檔名) |
WorktreeCreate / WorktreeRemove | worktree 建立 / 移除。會取代預設的 git 行為 |
PreCompact | context 壓縮前 |
Notification 事件的細分(用 matcher 比對):permission_prompt、idle_prompt、auth_success、elicitation_dialog、elicitation_complete、elicitation_response、agent_needs_input、agent_completed。
四個對你有用的實例
1. 擋下對受保護檔案的編輯 ⭐
這是你最該裝的一個。 Obsidian-med-note/CLAUDE.md §6 說「不要動 .quartzsite/」——但那是軟規則。做成 hook 就是硬的:
.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "case \"$CLAUDE_FILE_PATHS\" in *.quartzsite/*) echo 'BLOCKED: .quartzsite/ 是 Quartz 框架設定,除非任務就是調網站否則不可修改' >&2; exit 2;; esac"
}
]
}
]
}
}⚠️ 這是示意寫法。實際部署前自己先測一次(
PreToolUse的擋下語義與輸入格式請對照官方 hooks reference 的 JSON schema,本教學未逐欄複製)。
2. 改完檔案自動更新 modified 日期戳
vault 的 CLAUDE.md §3 ⓪ 說每次改動筆記都要把 frontmatter 的 modified 設成當天。這是典型的「一定要發生」:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "python3 .claude/scripts/stamp_modified.py \"$CLAUDE_FILE_PATHS\"" }
]
}
]
}
}寫一支小腳本把日期蓋上去,就再也不會忘記——而這正是 CLAUDE.md §7 列出的「最常見錯誤」之一。
3. Claude 需要你輸入時發桌面通知
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt|idle_prompt",
"hooks": [
{ "type": "command", "command": "notify-send 'Claude Code' '需要你的輸入'" }
]
}
]
}
}(WSL 上可以改成呼叫 powershell.exe 發 Windows 通知。)
4. 除錯:到底載入了哪些指示
{
"hooks": {
"InstructionsLoaded": [
{ "hooks": [ { "type": "command", "command": "echo \"[$(date +%T)] instructions loaded\" >> ~/.claude/instructions.log" } ] }
]
}
}排查 path-scoped rules 或子目錄延遲載入時很有用。
官方文件裡還有的實例
- 編輯後自動格式化程式碼
- 壓縮後重新注入 context(
PreCompact) - 稽核設定變更
- 目錄或檔案變更時重載環境(搭配 direnv 之類)
- 自動核准特定權限提示
使用時的注意事項
- Hook 是以你的身分執行的 shell 指令。 寫錯 = 真的會壞事。先在安全的地方測。
WorktreeCreate/WorktreeRemove會取代預設 git 行為——除非你確定要自訂,否則不要碰。- Hook 出錯會讓 session 行為異常。設定改壞了用
claude --safe-mode開起來救。 - 完整的事件 schema、JSON 輸入 / 輸出格式、async hook、MCP tool hook 見官方 Hooks reference。本教學只涵蓋觀念與常用事件。
什麼時候用 hook、什麼時候用別的
| 需求 | 用什麼 |
|---|---|
| 「一定要在 X 之前 / 之後發生」 | Hook |
| 「不准碰某個路徑」 | 權限 deny 規則(更簡單)或 PreToolUse hook(更靈活) |
| 「這個專案的慣例是…」 | CLAUDE.md |
| 「這個多步驟流程是這樣跑的」 | Skill |
| 「這類任務交給專門的助手」 | Subagent |
🔗 相關筆記
- 08-Subagents與平行工作 — 上一步
- 10-MCP與外部工具 — 下一步
- 06-CLAUDE-md與記憶系統 — 為什麼 CLAUDE.md 不是硬保證
- 05-權限模式與安全 — 權限規則 vs hook
- 官方 Hooks reference:https://code.claude.com/docs/en/hooks
最後更新:2026-08-04
