Skip to content

🌐 English

Hooks のライフサイクル

IMPORTANT

→ Why: Hallucination 対策(テスト実行 Hook で機械的に検出) → Why: Sycophancy 対策(コンパイラ・テストランナーは追従しない) → Why: Instruction Decay 対策(コンテキストに依存しない強制実行)

Hooks とは

Hooks は Claude Code のライフサイクルイベントにフックして実行されるコンテキスト外の処理。LLM のコンテキストウィンドウを消費しない。

属性
注入タイミングコンテキストに注入されない
コンテキスト消費なし(Prompt/Agent Hook の reasonok: false 時に Claude にフィードバック)
実行場所Claude Code ランタイム(シェル / HTTP / サブ LLM / サブエージェント)
定義場所settings.json 内の hooks キー

なぜ存在するのか

LLM に「毎回 eslint を実行しろ」と指示すると、

  1. コンテキストウィンドウを消費する
  2. Instruction Decay で忘れることがある
  3. Sycophancy で「問題ない」と判断をスキップする可能性がある

Hooks はランタイムレベルで強制実行するため、これらの問題を全て回避する。

ライフサイクルフロー

TIP

3層構造: セッション層(SessionStartSessionEnd)がエージェントループ層を囲み、非同期イベント層がループと並行して発火する。

イベント一覧

セッションライフサイクル

イベント発火タイミング主な用途
SessionStartセッション開始・再開時環境チェック、ログ初期化
SessionEndセッション終了時クリーンアップ処理
UserPromptSubmitユーザー入力送信時入力バリデーション、コンテキスト追加
Stopレスポンス完了時続行判定、品質ゲート
StopFailureAPIエラーによる終了時エラーログ、アラート送信

ツール実行

イベント発火タイミング主な用途
PreToolUseツール実行前危険なコマンドのブロック
PermissionRequest権限ダイアログ表示時権限の自動承認/拒否
PostToolUseツール成功後自動フォーマット、lint 実行
PostToolUseFailureツール失敗後エラーログ、リトライ判定

サブエージェント・タスク

イベント発火タイミング主な用途
SubagentStartサブエージェント生成時エージェントへのコンテキスト注入
SubagentStopサブエージェント完了時結果の検証、続行判定
TaskCreatedタスク作成時命名規則の強制、タスク検証
TaskCompletedタスク完了時完了条件の検証
TeammateIdleチームメイト待機前品質ゲート、リソース検証

設定・環境変更

イベント発火タイミング主な用途
InstructionsLoadedCLAUDE.md / rules 読込時監査ログ、コンプライアンス追跡
ConfigChange設定ファイル変更時セキュリティ監査、ポリシー強制
CwdChanged作業ディレクトリ変更時環境変数管理(direnv 等)
FileChanged監視ファイル変更時ファイル変更トリガーの自動化
Notification通知発生時デスクトップ通知

コンテキスト管理

イベント発火タイミング主な用途
PreCompactコンテキスト圧縮前圧縮前の検証
PostCompactコンテキスト圧縮後圧縮後の検証

ワークツリー・MCP

イベント発火タイミング主な用途
WorktreeCreateワークツリー作成時Git 動作の置き換え
WorktreeRemoveワークツリー削除時クリーンアップ処理
ElicitationMCP 入力リクエスト時ユーザー入力の自動化
ElicitationResultMCP 入力応答時応答データの検証・修正

NOTE

イベントの詳細(JSON 入出力スキーマ、matcher の仕様、非同期 Hook 等)は公式リファレンスを参照: Hooks reference | Hooks guide

Hook の種類

IMPORTANT

4種類すべて同じネスト構造: event → [{ matcher?, hooks: [{ type, ... }] }]matcher フィールドは ツール名に対する文字列正規表現(例: "Edit|Write")で、toolName / pathPattern を持つオブジェクトではない。ツール名は PascalCase(Edit, Write, Bash)。

Command Hook(最も一般的)

シェルコマンドを実行する。Hook 入力は stdin に JSON として届くので、jq でフィールド(file_path 等)を抽出する。exit 0 で許可、exit 2 でブロック(stderr が Claude にフィードバック)。

jsonc
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs -r npx prettier --write --ignore-unknown",
          },
        ],
      },
    ],
  },
}

Prompt Hook(シングルターン LLM 判定)

Hook 入力を Claude モデル(デフォルト Haiku)に送り、yes/no 判定を委ねる。モデルは {"ok": true} で許可、{"ok": false, "reason": "..."} でブロックを返す。Stop イベントでは reason が Claude にフィードバックされ、作業継続のヒントになる。

jsonc
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "すべてのタスクが完了しているか確認してください。未完了なら {\"ok\": false, \"reason\": \"残作業\"} を返してください。",
          },
        ],
      },
    ],
  },
}

HTTP Hook(外部サービス連携)

Hook 入力を JSON として HTTP エンドポイントに POST する。エンドポイントはレスポンスボディに同じ ok/reason JSON を返す。チーム共有の監査サービス等に有用。

jsonc
{
  "hooks": {
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "http",
            "url": "http://localhost:8080/hooks/tool-use",
            "headers": { "Authorization": "Bearer $MY_TOKEN" },
            "allowedEnvVars": ["MY_TOKEN"],
          },
        ],
      },
    ],
  },
}

Agent Hook(マルチターン検証、Experimental)

WARNING

Agent Hook は Experimental(実験的)であり、挙動・設定は変更される可能性がある。本番ワークフローでは Command Hook を優先すること。

ファイル読み取りやコマンド実行が必要な検証に使用。サブエージェントを起動し、最大50ターンのツール使用で条件を確認、{"ok": ..., "reason": ...} を返す。デフォルトタイムアウト60秒。

jsonc
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "agent",
            "prompt": "全てのユニットテストが通るか検証してください。テストスイートを実行し結果を確認してください。$ARGUMENTS",
            "timeout": 120,
          },
        ],
      },
    ],
  },
}

TIP

どれを選ぶか: Command は決定論的なシェルルール(lint、整形、ファイル保護)。Prompt は Hook 入力だけで判断できる場合(Haiku レベルの評価)。Agent はファイル読み取りやコマンド実行を伴う検証(テスト実行等)。HTTP は外部サービスにロジックを委譲する場合。

Exit Code の意味(Command Hook のみ)

Exit Code意味
0操作を許可(そのまま続行。stdout を additionalContext 経由でコンテキストに追加可)
2操作をブロック(stderr の内容を Claude にフィードバック)
その他操作は続行。stderr はログに記録されるが Claude には非表示

Prompt/Agent/HTTP Hook は Exit Code ではなく {"ok": true/false, "reason": "..."} JSON レスポンス形式を使う。

フレームワーク別 実践レシピ

フレームワークレシピ
Angular + NgRx + RxJSexamples/angular-ngrx/
SvelteKit + Svelte 5examples/svelte-kit/

8問題 × Hooks: クイックリファレンス

IMPORTANT

Hooks は構造的問題のすべてに万能ではない。下表は Hooks が強い領域・部分的に効く領域・他層(rules / Agents / セッション管理)の方が効く領域を示す。「ここで Hook を使うべきか?」の判断補助として使う。

構造的問題推奨 Hook イベント具体的なコマンド / タイプ効果強度
Context RotSessionStart (matcher: compact)echo でプロジェクト規約、git log --oneline -5コンパクション後に重要ルールを再注入◯ 部分的 — /compact 自体が主対策
Lost in the Middle(Hooks 単独では効果薄)Hooks はコンテキスト位置を制御しない△ Rules / Agents の方が効果的
Priority SaturationPostToolUse, Stopprettier, eslint, tsc --noEmit機械的ルールを CLAUDE.md から外す◎ 強 — 指示予算を解放
HallucinationPostToolUse, Stoptsc --noEmit, svelte-check, vitest runコンパイラ・型チェッカーは幻覚しない◎ 強 — 主対策
SycophancyStopCommand: eslint --no-warn-ignored
Agent Hook: 「テストが通るか検証」
LLM の追従バイアスはランナーに効かない◎ 強 — 機械的検証は追従しない
Knowledge BoundaryStopsvelte-check(Svelte 5 に混入するレガシー構文を検出)、tsc(型欠落を検出)古い API・構文の混入を検出◯ 部分的 — 境界が検証可能な場合のみ
Prompt SensitivityPreToolUse, StopHallucination と同じ機械的検証プロンプトの表現に出力品質が依存しなくなる◯ 部分的 — 最後の防衛線
Instruction DecayStop, PreToolUseblock-dangerous-commands.sh, tsc --noEmitコンテキスト依存しない強制実行◎ 強 — Hooks は「忘れる」ことができない

TIP

強度欄の読み方:

  • ◎ 強: その問題に対する主たる対策
  • ◯ 部分的: 効くが、他層(rules / Agents / セッション)の方が大きく寄与する
  • △ 弱: ここで Hook を最初に使うべきではない。別の層で対応

全層(rules、Skills、Agents、セッション、plugins)を横断した対策マップは 付録: 構造的問題 × Claude Code 対策マップ 参照。


前へ: settings.json の役割

次へ: なぜLLMに見せないのか

Released under the CC BY 4.0 License.