2025年8月3日日曜日

Claude Code Hook 機構 詳解

 

1. Hookの基本

概要

Hookとは、Claude Codeのライフサイクル中の特定イベント(例:PreToolUse)において実行される、ユーザー定義のシェルコマンドです。

これにより、LLMによる“選択的な処理”ではなく、確実に処理される“決定論的な制御”が可能になります。

ユースケース例

  • Claudeが入力待ちになる際に、カスタム通知を送る

  • ファイル編集後に自動でprettierやgofmtを実行

  • すべてのシェルコマンドをログに記録

  • Claudeの出力がチームのコーディング規約に反する場合、自動でフィードバック

  • 本番環境や機密ディレクトリの書き込み操作を防止

Promptではなく、Hookに制約を記述することで、毎回確実に動作する“アプリケーションレベルのルール”が構築できます。

注意点

Hookは、確認なしにあなたのユーザー権限でシェルを実行します。セキュリティを十分考慮してください。


2. Hookの設定方法(クイックスタート)

以下は、Claudeが実行するすべてのシェルコマンドをログに記録する例です。

前提

  • jqコマンドが必要です(JSON処理のため)。

手順

  1. /hooksコマンドを実行 → PreToolUseイベントを選択

  2. Matcherを追加 → Bashと入力

  3. Hookを追加:

jq -r '"\(.tool_input.command) - \(.tool_input.description // \"No description\")"' >> ~/.claude/bash-command-log.txt
  1. 保存場所:User settingsを選択(全プロジェクトに適用)

  2. 動作確認:/hooksで登録を確認

登録された設定の例:

"hooks": {
  "PreToolUse": [
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "command": "jq -r '\"\\(.tool_input.command) - \\(.tool_input.description // \"No description\")\"' >> ~/.claude/bash-command-log.txt"
        }
      ]
    }
  ]
}

3. Hookの仕組みと詳細仕様

  • PreToolUse, PostToolUse, Notification, Stop の4種類のイベントに対応

  • 入力はJSON形式でstdinから受け取り、出力もJSONまたはExit Codeで返す

  • フックの構成は matcher + hooks の組み合わせ

例(matcher):

  • Write:Writeツールのみに一致

  • Edit|Write:複数のツールに一致(正規表現)

  • mcp__github__.*:MCP(モデルコンテキストプロトコル)ツールに対応

出力方式:

  • Exit Code:

    • 0:成功、stdoutが表示される

    • 2:ブロック、stderrがClaudeに送られ制御される

  • JSON形式:

{
  "decision": "block",
  "reason": "機密情報の書き込みは禁止されています"
}

4. 応用例:コードガード、CI/CD、自動フォーマット

機密情報スキャン(PreToolUse)

  • マッチャ:Write|Edit|MultiEdit

  • アクション:正規表現やgitleaksライブラリを使ってAPIキー・パスワードを検出

  • フィードバック:ExitCode=2またはJSONでClaudeに警告

本番環境の書き込み防止

  • Gitブランチが main / production の場合にrmやwriteを即時ブロック

依存関係の自動インストール

  • Claudeが npm start などを実行する前に npm install を自動実行

コードレビューと静的解析(PostToolUse)

  • Claudeがコードを書いた直後にLinterやESLintを実行

  • フィードバックを人間的に返す(例:「関数の複雑度が高すぎます」)

ユニットテストの自動生成

  • 関数をClaudeが書いた直後に、その関数に対するテストコードをLLMで生成し即時実行

Gitコミット連携(Stop)

  • Stopイベントで git diff → LLM → Conventional Commitメッセージ自動生成

Jira連携

  • チケットIDをブランチ名やコミットから取得 → 自動でIn Reviewに更新


5. Claude Code Hook活用のまとめ

Claude CodeのHook機構は、単なる補助的ツールではなく、LLMの出力を“ルールベースな自動化システム”へと昇華させる強力な仕組みです。

以下の観点で真価を発揮します:

  • エンジニアリングガバナンス(規約、ルールの徹底)

  • 品質ゲート(静的解析・セキュリティチェック)

  • セキュアコーディング(秘密情報保護、ブランチ制御)

  • ローカル環境統制(依存管理、自動インストール)

  • チームワークとワークフロー(通知、Git/Jira連携)

Hookを正しく設計すれば、Claudeが出力するコードはレビュー不要で即マージ可能な品質に達することも夢ではありません。



Claudeの各Code Hooks

on_input(input: str) -> Union[str, None]

  • 入力時フック

  • 用途: ユーザーからの入力を受け取ったときにトリガーされます。入力を前処理したい場合や、入力に基づいて何かログを取ったり、入力値を変更する用途に使用されます。

on_output(output: str) -> str

  •  出力時フック

  • 用途: Claudeからの出力がユーザーに返される前にトリガーされます。出力の後処理やフィルタリング、ログ記録などに使えます。

on_tool_start(tool_name: str, input: str) -> None

  • ツール開始時フック

  • 用途: Claudeがツール(例: web検索や関数実行)を呼び出す直前に実行されます。開始ログの記録やモニタリングに使用されます。

on_tool_end(tool_name: str, input: str, output: str) -> str

  • ツール終了時フック

  • 用途: Claudeがツールの実行を終えた直後に実行されます。出力の整形や監査ログの記録に使えます。

on_tool_error(tool_name: str, input: str, error: Exception) -> str

  • ツールエラー時フック

  • 用途: Claudeがツール呼び出しで例外を検出した場合に実行されます。エラーログを取ったり、エラー内容に基づいてメッセージをカスタマイズするのに便利です。

on_completion(messages: List[Dict[str, str]]) -> None

  • セッション完了時フック

  • 用途: Claudeが会話を完了したときに呼び出され、会話履歴を取得できます。チャット履歴の保存や外部連携のトリガーに使用されます。

0 件のコメント:

コメントを投稿