Claude Codeのhookは便利だが、何も考えずに設定すると全ツール呼び出しで毎回実行される。1回のセッションでツールは数百回呼ばれる。hookが重いほどレスポンスが悪くなる。
この記事では、matcherとifフィールドを使ってhookの実行回数を90%以上削減する方法を紹介する。
問題:hookが遅い
以下の設定を見てほしい:
{
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/destructive-guard.sh"
}
]
}
]
}
}
matcherがないので、全てのツール呼び出しでdestructive-guard.shが実行される。
-
Readでファイルを読むとき → 実行(不要) -
Grepで検索するとき → 実行(不要) -
Bashでlsするとき → 実行(不要) -
Bashでrm -rf /するとき → 実行(これだけ必要)
1セッションでツールが300回呼ばれたとして、destructive-guardが必要なのはBash呼び出しの中のさらに一部だけだ。残り290回以上は無駄な実行になる。
解決策1:matcherでツール名を絞る
matcherフィールドを追加すると、特定のツールが呼ばれたときだけhookが実行される:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/destructive-guard.sh"
}
]
}
]
}
}
matcher: "Bash"を追加しただけで、Read、Grep、Edit、Writeなどの呼び出しでは完全にスキップされる。
matcherの値
matcherにはツール名を指定する。Claude Codeの主要なツール名:
| matcher値 | 対象 |
|---|---|
Bash |
シェルコマンド実行 |
Edit |
ファイル編集 |
Write |
ファイル書き込み |
Read |
ファイル読み取り |
Grep |
テキスト検索 |
Glob |
ファイル検索 |
Skill |
スキル呼び出し |
用途別の典型的なmatcher設定:
// 破壊的コマンドの防止 → Bash
{ "matcher": "Bash" }
// ファイル変更の監視 → Edit, Write
{ "matcher": "Edit" }
{ "matcher": "Write" }
// 読み取り専用操作の自動承認 → Read, Grep, Glob
{ "matcher": "Read" }
解決策2:ifフィールドでコマンド内容を絞る
matcherだけではBashツールの全呼び出しで実行される。lsでもechoでもcatでも実行される。
ifフィールドを使うと、ツール入力の内容が正規表現にマッチしたときだけ実行される:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/destructive-guard.sh",
"if": "rm|git reset|git clean"
}
]
}
]
}
}
この設定の動作:
- ツール呼び出しが来る
-
matcher: "Bash"→ Bashツールでなければスキップ -
if: "rm|git reset|git clean"→ コマンド内容にrm、git reset、git cleanのどれも含まなければスキップ -
両方にマッチしたときだけ
destructive-guard.shが実行される
ifフィールドは正規表現
ifフィールドの値は正規表現として評価される。パイプ|はOR条件になる。
// rm または git reset または git clean にマッチ
"if": "rm|git reset|git clean"
// npm publish にマッチ
"if": "npm publish"
// sudo で始まるコマンドにマッチ
"if": "^sudo"
// .env ファイルへの操作にマッチ
"if": "\\.env"
実行回数の比較
1セッション300回のツール呼び出しを想定:
| 設定 | 実行回数 | 削減率 |
|---|---|---|
| matcherなし、ifなし | 300回 | — |
matcher: "Bash" のみ |
約80回 | 73% |
matcher: "Bash" + if: "rm|git reset|git clean"
|
約5回 | 98% |
hookの実行自体は軽量でも、300回×複数hookでは積み重なる。特にシェルスクリプトを呼ぶhookは、プロセス起動のオーバーヘッドがある。
実践例:用途別の設定
1. 破壊的コマンド防止
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "bash ~/.claude/hooks/destructive-guard.sh",
"if": "rm\\s+-rf|git\\s+reset\\s+--hard|git\\s+clean|git\\s+push.*--force|chmod\\s+777"
}]
}
2. 秘密情報のコミット防止
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "bash ~/.claude/hooks/secret-guard.sh",
"if": "git\\s+add.*\\.env|git\\s+add.*credentials|git\\s+add\\s+-A|git\\s+add\\s+\\."
}]
}
3. npm publishの誤実行防止
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "bash ~/.claude/hooks/npm-publish-guard.sh",
"if": "npm\\s+publish"
}]
}
4. 構文チェック(Edit時のみ)
{
"matcher": "Edit",
"hooks": [{
"type": "command",
"command": "bash ~/.claude/hooks/syntax-check.sh"
}]
}
Editは常にファイル変更なので、ifなしで全実行が適切。
settings.json完全例
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/destructive-guard.sh",
"if": "rm\\s+-rf|git\\s+reset\\s+--hard|git\\s+clean|git\\s+push.*--force|chmod\\s+777"
},
{
"type": "command",
"command": "bash ~/.claude/hooks/secret-guard.sh",
"if": "git\\s+add.*\\.env|git\\s+add.*credentials|git\\s+add\\s+-A"
},
{
"type": "command",
"command": "bash ~/.claude/hooks/npm-publish-guard.sh",
"if": "npm\\s+publish"
}
]
},
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/syntax-check.sh"
}
]
},
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/syntax-check.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/context-monitor.sh"
}
]
}
]
}
}
まとめ
| やること | 効果 |
|---|---|
matcherを必ず設定する |
関係ないツールでの実行を完全に排除 |
ifで内容をさらに絞る |
関係ないコマンドでの実行を排除 |
| 両方を組み合わせる | 実行回数を90%以上削減 |
hookを追加するときは、必ず「このhookはどのツールの、どんな内容のときに必要か?」を考える。matcherとifで絞り込むだけで、hookの数を増やしてもセッションが遅くならない。
730件以上のexample hookがワンコマンドでインストールできる。matcherとifは全てのhookに適切に設定済み:
npx cc-safe-setup
📘 hookの設計思想から運用まで体系的にまとめた本: Claude Code 実戦ガイド(¥800)
第2章「Safety Guards」を無料で読む
hookの設計は「同じ失敗を二度と起こさない」 ための仕組み。 しかし、 hookでは検出できない別の系統の事故がある。 道具が「成功した」 と主張した時に、 実態は何も変わっていなかった、 という主張と実態の乖離の系統。
この系統の事例130件を整理した事例集を2026年5月22日に発売する。
📕 Claude Code Claim-Verify Handbook (5/22発売、 $19) | 主張と実態の乖離の130件の事例 (本文15件 + 付録D 115件) と、 利用者の側の14件の防御の手順、 5件の自動の検出の道具。 試し読みのGist で章1と章4の節1の本文を無料で読める。
同じ事故防止本は Kindle 版(Amazon・¥800)でも読めます。Kindle Unlimited なら追加料金なしで全文読めるので、まず無料で中身を確かめたい方はそちらが早いです。
Claude Code は毎月のように仕様が変わり、費用の膨らみ方も事故の新種も毎月出ます。「先月から何が変わったか・今すぐ直すべき設定や貼るべき hook はどれか」を毎月15日ごろ短く受け取りたい人には、Claude Code 事故まとめ(無料・月次)もあります(本は腰を据えて読む手引き、便りは毎月の鮮度で走らせる運用の線、という住み分けです)。