AIでコード生成すると、速い代わりに「もっともらしい誤り」が混ざります。
経験が浅いほどそれに気づけず、後工程(結合・総合・運用)で露呈して爆発しがち。
この記事では、個人のスキル頼みではなく 「前工程で落ちる仕組み」 を作って、AIの誤りを早期に捕まえる実践策をまとめます。
なぜ後工程で露呈するのか(よくあるパターン)
AIの誤りは、ざっくり次のタイプに偏りがちです。
- 仕様の読み違い(前提条件、例外、境界値)
- 例外・エラー処理の抜け(握りつぶし、戻り値曖昧)
- 状態/並行性(二重実行、競合、冪等性)
- セキュリティ(認可・入力検証・ログにPII)
- 統合ポイントの見落とし(API仕様、DB制約、既存ルール)
これを人間の注意力だけで全部検出するのは無理なので、「ミスがあっても手前で落ちる」仕組みに寄せます。
結論:最短で効くのは「テスト先行 + 自動ゲート」
最も効果が高い組み合わせはこれです。
- 仕様をテストに変換してから実装させる
- 型/Lint/テストをCIでゲートにする
- PRを小さく刻む(変更面積を減らす)
- AIを監査役として別ロールでレビューさせる
順に見ていきます。
1) 仕様を "テストに変換" してから書かせる(最強)
AIにいきなり実装させると、仕様の解釈違いが混ざります。
なので順番を逆にして、先にテスト(受入条件) を作らせます。
受入条件テンプレ(Given/When/Then)
| 項目 | 内容 |
|---|---|
| Given | 前提(データ状態、権限、設定) |
| When | 操作(API呼び出し、画面操作、バッチ起動) |
| Then | 期待結果(戻り値、DB更新、ログ、例外、レスポンス) |
境界値・異常系を必ず含める
-
null/ 空 / 最大長 / 最小値 / 最大値 - 0件 / 1件 / 最大件数
- 権限なし、期限切れ、二重実行
- 外部API失敗、タイムアウト
コツ:「最初にテスト一覧をPRに含める」だけでも、後工程の爆発はかなり減ります。
2) "型・Lint・フォーマット" をゲートにする(人の目を使わない防波堤)
経験が浅くても検出できるように、静的解析と規約で落とします。
TypeScript例
| ツール | 役割 |
|---|---|
tsc(strict系) |
型チェック |
| ESLint | Lint |
| Prettier | フォーマット |
| Vitest / Jest | 単体テスト |
最低限この4つを CI必須 にします。
Java例
| ツール | 役割 |
|---|---|
| SpotBugs / ErrorProne | 静的解析 |
| Checkstyle | コード規約 |
| Nullアノテーション | Null安全 |
| JUnit | 単体テスト |
AIのミスは「型の不整合」「null」「未使用」「握りつぶし」などで引っかかる率が高いです。
警告ゼロ以外マージ不可 にするのが効きます。
3) "小さく刻む" ルール(AIの誤りが混ざる面積を減らす)
後工程で露呈する大きな理由はこれです:
- 変更が大きくなる
- レビューが流し見になる
- テスト範囲が曖昧になる
運用ルール例
- 1PR = 1つの振る舞い
- 差分が一定行数を超えたら分割
- 生成物は スケルトン → ロジック → 最適化 の順に分ける
PRが小さいだけで、AIの誤りは格段に見つけやすくなります。
4) AIに "自己検証チェックリスト" を出させてから提出させる
AIの出力に必ず セルフ監査 を付けさせます。
ここで重要なのは、「根拠(コード箇所)」まで書かせる こと。
監査チェックリスト(コピペ用)
- 想定外入力(null/空/最大長/文字コード/順序入替)は?
- エラー/例外時の挙動(戻り値、例外、ログ)は?
- リトライ/二重実行時に安全?(冪等性)
- 並行実行で壊れない?(競合、ロック、トランザクション)
- 性能ボトルネック候補は?
- ログにPII/機密が出ない?
- 認可/入力検証/インジェクション対策は?
「指摘がある箇所だけ重点的に人が見る」運用にすると、経験差を埋められます。
5) "AI×AI相互監査" でレビューを二重化する(役割分離がポイント)
同じAIに「作ってレビューして」をやらせると甘くなりがち。
役割を分ける のがコツです。
| ロール | 責務 |
|---|---|
| 生成AI | 実装(最短で動く形を作る) |
| 監査AI | 仕様とのズレ、境界値、例外、競合、セキュリティを指摘 |
レビュー用の指示は 「辛口」に固定 すると安定します。
6) "死に方を良くする" =露呈を早める(後工程爆発の縮小)
完全に防げなくても、静かに壊さない が大事です。
- 前提が崩れたら早期に落ちる(入力検証・バリデーション)
- エラー時のログを「原因が分かる形」で出す(ただしPIIは避ける)
- フィーチャーフラグで段階リリース(影響範囲を局所化)
7) 今日から入れられる「最低セット」
全部は無理でも、まずはこれだけで効果が出やすいです。
- 受入条件→テスト を先に作らせる
- CIで 型チェック+Lint+単体テスト を必須化
- 1PR=1振る舞い の小分け運用
- AI監査役レビュー を毎回通す
おまけ:AIに投げるプロンプト(生成役 / 監査役)
そのまま使えるように置いておきます。
生成役(実装前にテスト→実装)
あなたは実装担当です。次の順に出してください。
1) 受入条件(Given/When/Then)を箇条書き
2) 境界値・異常系のテストケース一覧(入力と期待値)
3) そのテストが通る最小実装(差分が大きい場合は分割案も)
監査役(辛口レビュー)
あなたは監査担当です。以下の観点で欠陥を列挙してください。
- 仕様の解釈違い、境界値、異常系
- 例外/エラー処理の抜け、握りつぶし
- 冪等性/二重実行/並行性
- セキュリティ(認可、入力検証、ログのPII)
- 既存仕様/既存コードとの整合性
指摘は「根拠(該当箇所)」と「修正案」まで書いてください。
まとめ
AIコーディングのスピードに負けないためには、
「人の経験で気づく」から「仕組みで手前に倒す」 へ寄せるのが現実解です。
- テスト先行(仕様→テスト→実装)
- 静的解析・CIゲート
- PR小分け
- AI監査役の導入
- 失敗を早く・小さく