AIコーディングを使っていると、初期の実装スピードに驚かされる一方で、たった一つのエラーが何度頼んでも消えずドハマりすることがあります。「このエラーを直して」と指示すると一見それっぽいパッチが届く。でも実行すると同じエラーが出る。もう一度頼むと別の場所に条件分岐が足され、原因が見えないままコードだけが膨らんでいく……。

私もAIへエラー修正を任せる中で、一つの運用ルールに行き着きました。
「最初の1回はAIへ任せてもいい。でも同じエラーが2回続いたら、人間も原因仮説を考えて介入すべきだ」ということです。

これはAIを諦めて自分で全部書く話ではありません。同じ指示を繰り返して奇跡的に直るのを祈るのをやめ、AIが見えていない証拠を人間が足す役割分担の話です。

AIが同じエラーを繰り返すのは、入力される証拠が変わらないから

なぜAIは同じエラーを何度も繰り返してしまうのでしょうか?
理由はシンプルで、渡されている情報(証拠)が最初から変わっていないからです。

AIはエラーメッセージ、関連コード、規約、テスト結果から原因を推測します。しかし人間が「まだ直っていません」とだけ返していると、AIが原因探索に使える材料は増えません。その結果、同じ前提のまま似た修正案を別の書き方で出し続けることになります。

さらに注意が必要なのは、AIが行った変更パッチ自体が次の不具合を引き起こす点です。
失敗テストを直す代わりに条件を緩めたり、例外を握りつぶしたり、存在しないAPIやパッケージ(ハルシネーション)を追加したり……。コード量が増えているため一見進んだように感じますが、求める合格条件からは遠ざかっています。

GitHubのAI開発ガイドでも、生成コードに対してコンパイル、テスト、静的解析を行い、プロジェクトの意図に合っているか確認するよう推奨されています。特に失敗テストがスキップされていないか、不要な依存関係が入っていないかは必須の確認項目です。
重要なのは「AIが修正を出したか」ではなく、「外部から観測できる合格条件を満たしたか」です。

1回目はAIへ任せ、2回目から人間が原因仮説を足す

私がデバッグで設けている境界線はとても単純です。

1回目のエラーでは、AIにエラー全文を読ませ、関連コードを調べさせ、修正とテスト実行まで一気に任せます。思い当たるバグや副作用を自ら洗い出させた方が、人間が細かく指示するよりコストが低いからです。

しかし、まったく同じ症状が2回目に出たら自動再試行を止めます。
ここで「別の方法で直して」と頼むのではなく、人間が実行結果を見て原因候補を一つ立てます。

たとえば、

  • ロジックではなくビルドキャッシュが残っている
  • ローカルと本番で設定ファイルの値がズレている
  • テストが実際の失敗経路を通っていない
  • 修正対象とは別のテンプレートが表示されている

といった仮説です。
「2回」に科学的な正解があるわけではありません。私にとって同じ失敗が続いた瞬間は、「モデルの推論をもう一度回す問題」から「人間の観測方法を変える問題」へ切り替えるスイッチです。無制限に試行錯誤させて時間を溶かさないため、あらかじめ境界を決めておくことに価値があります。

AIへ渡す「原因仮説パケット」5項目

2回目の失敗からAIへ指示を出すときは、長い会話履歴をそのまま渡すのではなく、次の5項目を短く整理して渡します。

  1. 期待する結果:どの操作の後、何が表示・保存・返却されれば成功か。
  2. 実際の結果:エラー全文、HTTPステータス、画面差分など観測した事実。
  3. 最小の再現手順:初期状態から失敗までを3〜5手順にする。
  4. 人間の原因仮説:一番怪しいと思う境界を一つ示し、理由を書く。
  5. 合格条件と禁止事項:通すテスト、維持する仕様、触れてはいけないファイルやデータを定義する。

たとえば単に「ログイン後に一覧が空になる」と伝えるだけでは情報不足です。
代わりに「APIは200で3件返すが画面では0件。通信結果は正しいため、レスポンスのキー名と表示側の変換処理がズレていると考えている。データ形式は変更せず、変換処理を確認して既存テストと再現手順を通してほしい」と渡します。

ここまで絞り込めば、AIが探すべき範囲が一気に明確になります。
仮説は正解でなくて構いません。外れていればAIはコードやログを根拠に反証できます。何も仮説がない丸投げ状態を避け、どの境界を調べ、何が分かれば次へ進めるかを明確にすることが重要です。

AIの修正と検証を同じ仕事にしない

AIへ「直して、問題ないことも確認して」と一括で頼むと、作った本人が自分の修正を過剰に肯定する形になりがちです。そのため私は、「修正を作る工程」と「合格を判定する工程」を分けています。

修正後はまずコード差分(diff)を読みます。次に既存テスト、再現テスト、静的解析を実行します。
その上でAIへ「この修正が失敗テストを消しただけになっていないか」「未確認の前提はないか」「元の仕様を壊す経路はないか」とレビューさせます。同じモデルでも作成時の会話から切り離し、差分と合格条件だけ渡すことで客観的に評価しやすくなります。

NISTのDevSecOpsガイドラインでも、AI生成物は人間が監視・検証し、正確性を検証可能な工程で担保すべきとされています。ここでの監視は全コードを手で書き直すことではありません。テスト、ログ、差分という証拠を残し、誰が見ても成功か失敗か判断できる状態を作ることです。

AIで速くなるかは、修正時間ではなく完了時間で測る

AI開発の速度は、「コードが出た瞬間」ではなく「要求を満たして安全に完了した時点」で測る必要があります。

Googleが96人のエンジニアを対象に行った実験では、特定の環境と課題でAI支援により約21%の時間短縮が推定されました。一方、METRが2025年に開発者を対象に行った実験では、当時の条件で19%の遅延が観測されています(METR自身もこの初期結果を最新モデルへそのまま一般化できないと注意しています)。

この差から「AIは速い」「AIは遅い」のどちらかを選ぶのは早計です。課題の難易度、リポジトリへの熟練度、ツール、測定方法、品質基準で結果は変わります。だからこそ現場では、生成速度ではなく「最初の指示からテスト通過までの時間」「再試行回数」「巻き戻した差分量」を記録すべきです。どれだけ出力が速くても、同じエラーで3回足踏みしているなら開発は速くありません。

AIデバッグを止めて巻き戻す条件

原因仮説を渡しても続行しない方がよい場面があります。私は次のどれかが起きたら、追加パッチをやめて直前の正常状態(Gitコミット等)へ巻き戻します。

  • 同じ症状が3回続き、新しい観測事実が増えていない。
  • 変更範囲が当初の原因候補から無秩序に広がり続けている。
  • テストを削除・緩和しないと成功扱いにできない。
  • 認証、権限、個人情報、決済、データ削除など重要機能へ影響する。
  • 新しい依存関係を追加しないと直せないが、必要性と安全性を説明できない。

巻き戻しは失敗ではありません。壊れ方を観測し原因候補を減らした成果を残したまま、変更だけを捨てる前向きな操作です。小さなチェックポイントを作っておけば、AIが積み上げたパッチを守るため複雑なパッチを重ねる泥沼化を防げます。

人間の仕事はコードを書くことより、観測を変えること

AIが同じエラーを繰り返したとき、人間が取り戻すべきなのはキーボードの打鍵速度ではなく、「問題を見る視点(観測領域)」です。

画面しか見ていなければ通信ログを見る。コードしか見ていなければ実データを見る。本番だけ壊れるなら設定差を見る。AIが同じ前提の中を回っているなら、人間が境界の外から新しい証拠を持ち込みます。

私が2回目から原因仮説を足すのは、人間の方が常に正しいからではありません。AIは広く速く探索でき、人間は実際に触れた結果や事業上の制約を知っている。両方をつなぐ方が、一方へ丸投げするより早く失敗から抜け出せるからです。

次に同じエラーが2回続いたら、もう一度「直して」と送る前に、期待、実際、再現、仮説、合格条件の5行を書く試みをしてみてください。AIを使い続けるために人間が適切に介入する。その切り替えこそが、AIコーディングで最も価値のあるデバッグ技術だと感じています。