0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code hookのmatcherとifフィールド——不要な実行を減らして高速化する

0
Last updated at Posted at 2026-05-08

Claude Codeのhookは便利だが、何も考えずに設定すると全ツール呼び出しで毎回実行される。1回のセッションでツールは数百回呼ばれる。hookが重いほどレスポンスが悪くなる。

この記事では、matcherifフィールドを使ってhookの実行回数を90%以上削減する方法を紹介する。

問題:hookが遅い

以下の設定を見てほしい:

{
  "hooks": {
    "PreToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash ~/.claude/hooks/destructive-guard.sh"
          }
        ]
      }
    ]
  }
}

matcherがないので、全てのツール呼び出しdestructive-guard.shが実行される。

  • Readでファイルを読むとき → 実行(不要)
  • Grepで検索するとき → 実行(不要)
  • Bashlsするとき → 実行(不要)
  • Bashrm -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"を追加しただけで、ReadGrepEditWriteなどの呼び出しでは完全にスキップされる。

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"
          }
        ]
      }
    ]
  }
}

この設定の動作:

  1. ツール呼び出しが来る
  2. matcher: "Bash" → Bashツールでなければスキップ
  3. if: "rm|git reset|git clean" → コマンド内容にrmgit resetgit cleanのどれも含まなければスキップ
  4. 両方にマッチしたときだけ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 事故まとめ(無料・月次)もあります(本は腰を据えて読む手引き、便りは毎月の鮮度で走らせる運用の線、という住み分けです)。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?