はじめに
Claude Codeを使ったAI駆動開発では、単にコード生成を速くするだけでは不十分です。
AIエージェントがファイルを編集し、コマンドを実行し、複数の修正を並行して進められるようになるほど、開発者側には次のような課題が出てきます。
- 危険なコマンドを実行させない
- 編集後にformatter / linter / testを通す
- プロジェクト固有のルールをAIに守らせる
- 生成結果を人間がレビューしやすい状態に整える
- AIの作業をログとして残し、後から検証できるようにする
ここで重要になるのが Claude Code Hooks です。
Hooksは、Claude Codeのライフサイクル上の特定タイミングで、ユーザー定義の処理を自動実行する仕組みです。たとえば、ツール実行前に危険操作をブロックしたり、ファイル編集後に自動整形したり、応答終了時にテスト確認を促したりできます。
この記事では、Claude Code Hooksを単なる小技としてではなく、AI駆動開発の品質ハーネスを作るための設計要素として整理します。
Hooksを一言でいうと
Claude Code Hooksは、Claude Codeが動く過程に「決定的な制御点」を差し込む仕組みです。
AIに自然言語で指示するだけでは、最終的な挙動はモデルの判断に依存します。もちろんClaude Codeは強力ですが、プロダクト開発では「たぶん守ってくれる」では足りません。
たとえば、次のようなルールはプロンプトだけに任せるべきではありません。
-
mainブランチに直接pushしない -
.envや秘密鍵を読ませない、書かせない -
rm -rfのような破壊的コマンドを実行させない - 生成後に必ず
pnpm lintやpnpm testを実行する -
npmではなくプロジェクト指定のpnpmを使う - Prisma schema変更後は必ず型生成を行う
プロンプトは「お願い」です。Hooksは「ゲート」です。
この違いが重要です。
設計思想1:AIの判断と、システムの強制を分離する
AI駆動開発でまず分けるべきなのは、次の2つです。
- AIに任せる判断
- システムとして強制する制約
AIに任せてよいものは、たとえば以下です。
- 実装方針の提案
- コンポーネント分割案
- API設計案
- テスト観点の洗い出し
- リファクタリング方針
一方で、システムとして強制したいものは以下です。
- 危険コマンドの禁止
- 秘密情報へのアクセス制限
- フォーマット・lint・testの実行
- 特定ディレクトリの編集禁止
- 生成コードの検証手順
この後者を担うのがHooksです。
AIの創造性や推論能力は活かしつつ、守るべき境界はコードで固定する。これがClaude Code Hooksの基本的な設計思想です。
設計思想2:PreToolUseは「実行前の安全ゲート」
Claude Code Hooksで特に重要なのが PreToolUse です。
PreToolUse は、Claude Codeがツールを実行する前に発火します。ここで入力内容を検査し、危険な処理を止めることができます。
典型的な用途は以下です。
- Bashで危険なコマンドをブロックする
-
.envや秘密鍵ファイルへのアクセスを止める -
npm installではなくpnpm installを使わせる - 本番設定ファイルの編集を禁止する
- migrationやDB操作の前に確認を入れる
たとえば、Bash実行前に危険コマンドを止めるHookを作る場合、設定は次のような形になります。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/pre_bash_guard.py"
}
]
}
]
}
}
pre_bash_guard.py 側では、Claude Codeから渡されるJSONを読み取り、コマンド文字列を検査します。
#!/usr/bin/env python3
import json
import sys
payload = json.load(sys.stdin)
command = payload.get("tool_input", {}).get("command", "")
blocked_patterns = [
"rm -rf /",
"rm -rf ~",
"sudo rm",
"git push --force",
"cat .env",
"cat ~/.ssh",
]
for pattern in blocked_patterns:
if pattern in command:
print(f"Blocked dangerous command: {pattern}", file=sys.stderr)
sys.exit(2)
sys.exit(0)
ここで大事なのは、Claudeに「危険なコマンドは実行しないで」とお願いするのではなく、実行直前に機械的に検査することです。
AIは提案できます。Hooksは止められます。
設計思想3:PostToolUseは「後処理と整流化」
PostToolUse は、ツール実行後に発火します。
これは主に、生成された成果物をプロジェクトの標準に揃えるために使います。
典型例は以下です。
- ファイル編集後にformatterを実行する
- TypeScriptファイル変更後に型チェックする
- package.json変更後に依存関係チェックする
- schema変更後にコード生成する
- ログを保存する
たとえば、Edit / Write / MultiEdit の後にformatterを実行する場合です。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "pnpm format"
}
]
}
]
}
}
ただし、実務では毎回全体formatを走らせると重い場合があります。
その場合は、Hookで変更ファイルを読み取り、対象ファイルだけ処理する設計にします。
#!/usr/bin/env python3
import json
import subprocess
import sys
from pathlib import Path
payload = json.load(sys.stdin)
file_path = payload.get("tool_input", {}).get("file_path")
if not file_path:
sys.exit(0)
path = Path(file_path)
if path.suffix in [".ts", ".tsx", ".js", ".jsx"]:
subprocess.run(["pnpm", "prettier", "--write", str(path)], check=False)
sys.exit(0)
PostToolUseは、AIの出力をチームの開発基準に合わせて整えるための「整流器」です。
設計思想4:Stopは「完了判定」ではなく「完了前検査」に使う
Claude Codeが一連の応答を終えるタイミングで使えるのが Stop です。
ここでは、タスク完了前の最終チェックを行う設計が有効です。
たとえば以下のような用途です。
- TODOが残っていないか確認する
- lint / testが未実行なら促す
- 差分が大きすぎる場合にレビューを促す
- 生成されたファイル一覧を記録する
- 重要ファイル変更時に確認メッセージを出す
AI駆動開発では、AIが「完了しました」と言っても、本当に完了しているとは限りません。
人間でもそうです。違いは、人間は言い訳をしますが、AIは爽やかに未完了を完了扱いします。困った文明です。
Stop Hookは、そこで最後に検査を入れるために使います。
Hooksは品質ハーネスである
私はClaude Code Hooksを、単なる自動化機能ではなく 品質ハーネス として捉えています。
品質ハーネスとは、AIが速く書いたコードを、プロダクトとして扱える状態にするための周辺装置です。
具体的には、以下を含みます。
- 実行前の安全ゲート
- 編集後の自動整形
- 型チェック
- lint
- test
- 秘密情報保護
- ログ保存
- 差分レビュー
- 生成物の評価
- 人間への確認導線
AI駆動開発の本質は「AIに全部任せること」ではありません。
むしろ逆です。
AIに任せる領域を広げるほど、周辺に決定的な制御機構が必要になります。
Claude Code Hooksは、その制御機構をプロジェクトごとに実装するためのレイヤーです。
実務で使うHooks設計パターン
1. 危険コマンドブロック
目的:破壊的操作、秘密情報の閲覧、本番環境操作を止める。
対象:PreToolUse + Bash
検査例:
rm -rfsudogit push --force-
.envのcat kubectl deleteterraform destroy
このHookは全プロジェクト共通のユーザー設定に置いてもよいです。
2. プロジェクト規約の強制
目的:プロジェクトごとのツールチェーンを守る。
例:
- npm禁止、pnpm必須
- yarn禁止、bun必須
- migration生成コマンドの統一
- package manager混在の防止
これは .claude/settings.json に入れて、チーム共有する価値があります。
3. 編集後formatter
目的:AIが生成したコードを即座に整える。
対象:PostToolUse + Edit|Write|MultiEdit
例:
- Prettier
- ESLint --fix
- Biome
- gofmt
- rustfmt
4. 型チェック・テストの誘導
目的:AIが「書いただけ」で終わるのを防ぐ。
対象:PostToolUse または Stop
例:
pnpm typecheckpnpm lintpnpm testpnpm test:e2e
重い処理は毎回走らせず、Stop時や特定ファイル変更時に絞るのが現実的です。
5. LLM出力の構造化検査
目的:LLMが生成するJSONや設定ファイルの形式崩れを検知する。
例:
- JSON schema validation
- Zod schema validation
- Pydantic validation
- YAML parse check
AIアプリケーション開発では、ここが特に重要です。
設計時に避けるべきこと
1. すべてをHookで強制しようとする
Hooksは強力ですが、何でもHookに入れると開発体験が悪化します。
たとえば、毎回全テストを走らせると、Claude Codeの試行錯誤速度が落ちます。
基本方針は以下です。
- 軽い処理はPostToolUse
- 重い処理はStop
- 危険操作はPreToolUse
- 判断が必要なものは人間に戻す
2. プロンプトで済むものまでHook化する
Hookは決定的制御に使うべきです。
「こういう設計方針で考えてほしい」程度なら、CLAUDE.mdやプロンプトで十分です。
一方で、守らないと事故るものはHookにします。
3. ローカル個人設定とチーム共有設定を混ぜる
Hooksは設定ファイルの置き場所で意味が変わります。
- 個人の好み:ローカル設定
- チーム全体で強制したいルール:プロジェクト設定
- 全プロジェクト共通の安全策:ユーザー設定
この分離をしないと、チームメンバーの環境差分で地味に壊れます。
人類は環境差分を軽視しがちですが、だいたい環境差分が人類を殴ります。
設計思想を短くまとめる
Claude Code Hooksの設計思想を短くまとめると、次のようになります。
Hooksは、AI駆動開発における安全ゲートと品質ハーネスです。PreToolUseで実行前に止め、PostToolUseで生成物を整え、Stopで完了前検査を行うことで、AIの速度を活かしながらプロダクト品質を担保します。
重要なのは、AIに任せる領域と、システムとして強制する領域を分離することです。
AIには実装方針の提案やコード生成を任せる。一方で、危険コマンドのブロック、秘密情報の保護、formatter / lint / test、構造化出力の検証などはHooksで決定的に制御する。
この分離によって、AIの速度を活かしながら、プロダクト開発に必要な安全性と再現性を確保できます。
まとめ
Claude Code Hooksは、AI駆動開発を「速いけれど不安定な自動生成」から、「制御可能な開発基盤」に近づけるための重要な仕組みです。
ポイントは以下です。
- HooksはClaude Codeのライフサイクルに決定的な制御点を差し込む仕組み
- PreToolUseは危険操作を止める安全ゲート
- PostToolUseは生成物を整える後処理レイヤー
- Stopは完了前の品質確認に使える
- プロンプトでお願いする領域と、Hooksで強制する領域を分ける
- AI駆動開発では、速度よりも「速度を安全に受け止める仕組み」が重要
AIがコードを書く時代に、人間がやるべきことは減るどころか変わります。
手で全部書くのではなく、AIが安全に速く動ける開発レールを敷く。
Claude Code Hooksは、そのレールの一部です。
この記事を書いた人✏️@YushiYamamoto
株式会社プロドウガ CEO / AIアーキテクト
Next.js / TypeScript / n8nを活用した自律型アーキテクチャ設計を専門としています。
日々の自動化の検証結果や、ビジネス側の視点(ROI等)に関するより深い考察は、以下の公式サイトおよびnoteで発信しています。
