なぜ「AIに任せたら壊れた」が起きるのか

Claude Code(= ターミナルで動くAIコーディング相棒)にタスクを任せると、驚くほど速くコードが仕上がります。ところが数日運用すると、必ずと言っていいほど遭遇するのが「動かないコードがcommitされていた」問題です。

原因はシンプルで、AIは「書いた」で仕事を終えるから。本来そこに必要なのは、人間のエンジニアが無意識にやっている「保存→フォーマット→型チェック→テスト→問題なければ提出」という一連の検品作業です。

ある個人運営メディアのオーナーは、この検品をHooks(= AIが道具を使った瞬間に自動で発火する検品ゲート) に置き換えました。結果、3ヶ月運用してAI起因の壊れたcommitはゼロ。本記事はその設計を丸ごと共有します。

Hooksとは何か(まず比喩で理解する)

Hooks(フック)を工場に例えるなら、ベルトコンベアの途中に置かれた検品ロボット です。

  • AIが「ファイルを書いた」 → 検品ロボAが自動でフォーマットをかける
  • AIが「ファイルを編集した」 → 検品ロボBが型チェックを走らせる
  • どれか1つでも不合格 → 製品(= 変更)は流れを止められ、棚に戻される

この仕組みは settings.jsonhooks セクションに数行書くだけで有効になります。

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command", "command": ".claude/hooks/quality-gate.sh" }
        ]
      }
    ]
  }
}

読めなくても大丈夫。要点はこうです。「WriteかEditという道具をAIが使った直後に、quality-gate.shという検品スクリプトを必ず走らせてね」 と宣言しているだけです。

発火タイミングは3種類ある

Hooksが発火するイベントは主に3つ。どれも比喩で覚えると早いです。

  • PreToolUse: 道具を使う「前」に割り込む(= 作業前の安全確認)
  • PostToolUse: 道具を使った「直後」に割り込む(= 提出時の検品)
  • UserPromptSubmit: ユーザーが指示を送った瞬間に割り込む(= 受付での本人確認)

本記事が扱うのは真ん中のPostToolUse。ここが品質ゲートとして最も効きます

FIGURE: concept — 6レイヤーの品質ゲート全体像

6レイヤーの品質ゲート全体像

図: 6レイヤーの品質ゲート全体像

今回紹介するのは、PostToolUseに6つの検品レイヤーを直列で並べる設計です。

  1. フォーマット層: Prettier等で整形(= 服装を整える)
  2. Lint層: ESLint等で規約違反を検出(= 就業規則チェック)
  3. 型チェック層: tsc --noEmit(= 書類の辻褄合わせ)
  4. テスト層: 関連ファイルのユニットテストだけ実行(= 動作確認)
  5. 重複検知層: jscpdなどで「似たコードの増殖」を検出(= 在庫のダブり防止)
  6. セルフレビュー層: Claude自身に0-100点で採点させる(= 自己評価面談)

1〜5はシェルで機械的に、6はAIに任せる。この**「機械の検品 + AIの検品」のハイブリッドが効きます**。

失敗時に何が起きるのか(ここが最重要)

Hooksスクリプトが exit 1(= 不合格の合図)を返すと、Claudeはその瞬間にツール実行をキャンセル、または直前の変更をロールバックします。

つまり、

  • フォーマットが通らない → そのEditは無かったことに
  • 型チェックで赤 → そのWriteは棚に戻される
  • テストが落ちた → 変更はリポジトリに残らない

これが「物理的に強制する」の意味です。人間が「あとでレビューしよう」と思って忘れる余地がありません。検品に落ちたものはそもそも倉庫に入らないのです。

#!/usr/bin/env bash
set -e
npx prettier --write "$CLAUDE_FILE_PATHS"
npx eslint "$CLAUDE_FILE_PATHS"
npx tsc --noEmit
npx vitest related "$CLAUDE_FILE_PATHS" --run

読めなくても大丈夫。要点は**「1行でも失敗したら set -e のおかげでスクリプトごと落ちて、Claudeに不合格を通知する」** ことです。

FIGURE: flow — エージェント実行の時系列

エージェント実行の時系列

図: エージェント実行の時系列

実際の1サイクルはこう流れます。

  1. ユーザー「この関数をリファクタして」
  2. Claudeが Edit ツールでファイルを書き換える
  3. PostToolUse hook 発火 → quality-gate.sh 起動
  4. Prettier → ESLint → tsc → vitest が順に走る
  5. 全部パス → Claudeは次の作業へ進む
  6. どれか落ちた → 変更はロールバック、Claudeにエラー内容が渡る
  7. Claudeがエラーを読んで自己修正 → 再度 Edit → 再度検品

このループが人間の介入なしに回るのがミソです。寝てる間にAIが自分で直してくれます。

FIGURE: comparison — 検品なし vs 検品あり

検品なし運用 vs Hooks検品あり運用

図: 検品なし運用 vs Hooks検品あり運用

観点 検品なし運用 検品ありHooks運用
壊れたcommit 週1-2回発生 ほぼゼロ
人間のレビュー時間 変更のたびに必要 例外時のみ
AIの自己修正 人間が指摘して初めて起動 hook失敗で自動起動
夜間・放置運用 不可(怖くて任せられない) 可能
初期設定コスト ゼロ 30分〜1時間

初期コスト1時間で、夜間放置運用という選択肢 が手に入るのは悪くない取引です。

セルフレビュー型hookという裏技

5つの機械検品だけでも十分ですが、さらに踏み込むならClaude自身に採点させる層を足せます。

やり方は単純で、hookスクリプトの中で claude -p "直前の変更を0-100点で評価し、70未満なら理由を出力せよ" のように呼び出し、70未満なら exit 1 を返すだけ。AIがAIを検品する 構図です。

これは「人間のシニアエンジニアによるコードレビュー」を、粗いながらも24時間自動化したものに相当します。

エンジニアじゃない方へのメッセージ

ここまで読んで「コードの話が多くて自分には無理そう」と感じた方へ。

実は、あなたが触るのは settings.json という1ファイルと、数行のシェルスクリプトだけ です。一度セットアップすれば、あとはClaude Codeが勝手に検品を通してくれます。車に例えるなら、あなたがやるのは「シートベルトを装着する」ことだけで、エアバッグの仕組みを理解する必要はありません。

個人事業で情報発信メディアやツールを立ち上げたいけれど「壊れたものを世に出すのが怖い」と足踏みしている方にこそ、この仕組みは効きます。検品ゲートが物理的に守ってくれる ので、あなたは企画とマーケティングに集中できます。

技術的ハードルに怯むのではなく、「検品は機械に任せる」という選択肢があることだけ覚えて帰ってください。

🎁 特典: 設定ファイル一式ダウンロード

本記事で紹介した6レイヤーの検品ゲートを、すぐに動かせる状態でパッケージしました。

zipの中身:

  • settings.json — hooks セクション記入済みテンプレート
  • hooks/format.sh — Prettier自動整形スクリプト
  • hooks/lint.sh — ESLint実行スクリプト
  • hooks/typecheck.sh — tsc --noEmit型チェックスクリプト
  • hooks/test.sh — 関連テストのみ実行するスクリプト
  • hooks/duplicate-check.sh — jscpdによる重複検知スクリプト
  • hooks/rollback-example.sh — 失敗時のgit stashロールバック参考実装
  • README.md — 導入手順と比喩付き解説

解凍して、あなたのプロジェクトのルートに置き、npm コマンドを自分のスタックに書き換えるだけ で動きます。Python派の方はpytest・ruffに置換する例も同梱しています。

👉 ダウンロードはこちら

📚 参考リファレンス