AIに丸投げしないコードレビュー・デバッグ壁打ち術
連載:AI時代のSE・プログラマのためのAI壁打ち実践入門
全5回 | 第4回 / 5この連載は、AIを「答えを出す機械」ではなく、「前提を掘り、選択肢を増やし、判断を検証する相棒」として使うための実践シリーズです。
はじめに
AIはコードを書ける。
しかし、AIのコードをそのまま信じると、動かないコードや危険な修正を取り込むことがあります。
「エラーを貼ったら修正コードが出てきたので適用した。しかし別のバグが入った」
「AIのレビューで "問題ありません" と言われたが、実はセキュリティホールがあった」
こんな経験をしたことはありませんか?
前回は設計フェーズでの壁打ちを扱いました。今回は、実装・レビュー・デバッグの場面で、AIを安全に使う壁打ち手順を整理します。
この記事で扱うこと
- AIにデバッグを「丸投げ」すると失敗する理由
- エラー相談・コードレビュー・テスト観点の壁打ちテンプレート
- AIが間違えやすいポイント
- 壁打ちの実例(「API レスポンスが空になるバグ」を題材に)
- AIの回答を検証する手順
結論
先に結論を書きます。
実装中のAI壁打ちは、コード生成よりも以下に使うと安定します。
| 用途 | 効果 |
|---|---|
| 再現条件の整理 | 問題の範囲が明確になる |
| 原因仮説の列挙 | 思いつかなかった原因が見つかる |
| 修正案の比較 | 場当たり的な修正を防げる |
| テスト観点の追加 | 見落としていたケースに気づける |
| レビュー観点の洗い出し | 自分では気づかない視点が増える |
つまり、AIは「修正コードを出してもらう相手」ではなく、「原因と対策の選択肢を増やす相手」として使います。
よくある失敗例
悪い例
このエラーを直してください。
TypeError: 'NoneType' object is not subscriptable
AIは修正コードを返しますが、以下の問題があります。
- 文脈なしで渡しているため、AIは推測で修正する
- 推測が外れると、別のバグを埋め込む
- 根本原因ではなく症状だけを消す修正になりやすい
- テストなしで「修正完了」と判断してしまう
実装中の壁打ちで有効な3つの型
型①:エラー相談型
エラーが出たとき、いきなり修正コードを求めるのではなく、原因仮説を整理させる型です。
以下のエラーについて、いきなり修正コードを出すのではなく、
原因仮説を整理してください。
やりたいこと:
- FastAPIのエンドポイントでタスク一覧をJSON形式で返す
環境:
- Python 3.11 / FastAPI 0.104 / SQLAlchemy 2.0
- OS: Windows 11
期待結果:
- GET /tasks で、タスクのリストがJSON配列で返る
実際結果:
- レスポンスが空の配列 [] になる(DBにはデータがある)
エラーメッセージ:
- エラーは出ていない。ステータスコードは200。
最近変更したこと:
- SQLAlchemy のモデルに新しいカラムを追加した
- マイグレーションは実行済み
出力してほしいもの:
1. 原因仮説を可能性が高い順に並べる
2. 各仮説を確認する方法(破壊的でないコマンド)
3. 修正案
4. 再発防止のテスト観点
型②:コードレビュー依頼型
自分のコードをレビューさせる型です。ポイントは「レビュー観点」と「制約」を明示することです。
以下のコードをレビューしてください。
レビュー観点:
- バグの可能性
- 境界値
- 例外処理
- セキュリティ
- 可読性
- 保守性
- テスト不足
制約:
- 仕様を勝手に変えない
- 大規模リファクタリングではなく、最小修正案を優先する
- 不明点は推測せず質問として出す
コード:
```python
@app.get("/tasks")
def get_tasks(db: Session = Depends(get_db)):
tasks = db.query(Task).all()
return [{"id": t.id, "title": t.title, "status": t.status} for t in tasks]
「仕様を勝手に変えない」「不明点は質問として出す」の2つの制約が重要です。これがないと、AIが仕様を独自解釈して大きな変更を提案してくることがあります。
### 型③:テスト観点生成型
テストケースを考える前に、テスト観点をAIに出させる型です。
```text
以下の仕様に対して、テスト観点を出してください。
仕様:
- GET /tasks はタスクの一覧を返す
- タスクがない場合は空配列を返す
- ステータスでフィルタできる(query parameter: status)
- 認証は不要(個人ツール)
出力形式:
| 観点 | 正常系/異常系 | 入力 | 期待結果 | 優先度 |
以下のカテゴリに分けてください:
- 正常系
- 境界値
- 異常系
- セキュリティ
AIが間違えやすいポイント
AIをレビューやデバッグに使う際、以下のような間違いが起きやすいです。事前に知っておくと対策できます。
| パターン | 例 | 対策 |
|---|---|---|
| 存在しないAPIを使う | 廃止されたメソッドを提案 | 公式ドキュメントで確認する |
| バージョン差を無視する | Python 3.11 で使えない書き方を提案 | 環境情報を必ず渡す |
| 原因を断定しすぎる | 「原因はこれです」と言い切る | 仮説として扱い、自分で検証する |
| 危険な回避策を出す |
except: pass で握りつぶす提案 |
セキュリティ・安全性の観点でレビュー |
| テストなしで完了とする | 「これで動くはずです」で終わる | ローカルで必ず実行確認する |
壁打ちの実例:「APIレスポンスが空になるバグ」
先ほどのエラー相談型を実際に使ってみます。
AIの回答(要約)
🤖 AI(デバッグ相談役):
原因仮説(可能性が高い順):
順位 仮説 確認方法 1 セッションのスコープ不一致 db.query(Task).count()をエンドポイント内で実行して件数を確認2 カラム追加後にマイグレーション反映漏れ alembic currentとalembic headsを比較3 テーブル名のミスマッチ モデルの __tablename__と実テーブル名を確認4 別のDBファイルを見ている 接続文字列のパスをログ出力して確認 修正案:
- 仮説1の場合:
get_dbのセッションスコープを確認。yieldの後にdb.close()があるか確認。- 仮説4の場合:環境変数
DATABASE_URLの値をログに出力して確認。再発防止のテスト観点:
- DBにテストデータを入れた状態で
GET /tasksを呼ぶテストを追加- レスポンスの件数を検証するアサーションを入れる
この壁打ちから得られた気づき
- 「別のDBを見ている」は盲点だった:自分では気づきにくい仮説をAIが出した
- 修正の前に確認コマンドが並んだ:いきなりコードを書き換えるのではなく、まず状態を確認する手順が整理された
- テスト観点が具体化した:漠然と「テストを書く」ではなく、何を検証すべきか明確になった
AIの回答を検証する手順
AIからの回答は、以下の手順で検証してください。
- 公式ドキュメントで確認する: AIが提案したAPIやメソッドが、使用中のバージョンで実際に存在するか確認する。
- ローカルで実行する: 修正コードは、本番環境ではなくローカルの開発環境で先に動かす。
- テストを書く: 修正後に期待通りの動作をするか、テストで確認する。
- 差分を確認する: AIが出した修正と自分の元コードの差分を、1行ずつ確認する。
- 副作用を確認する: 修正が他の機能に影響しないか確認する。
実務投入時の注意点
- AIの修正コードをそのままコミットしない: AIの修正コードは「提案」であり、「動作保証」ではない。必ずローカルで実行し、テストを通してからコミットする。
- 機密コードを渡さない: レビュー依頼にコードを渡す場合、認証トークン・APIキー・顧客データが含まれていないか確認する。必要に応じてダミー値に置き換える。
- AIに「問題ありません」と言われても安心しない: AIは構文的に正しいコードには「問題なし」と答えやすい。ロジックバグ・ビジネスルール違反・セキュリティホールは見逃す場合がある。
チェックリスト
実装中のAI壁打ちを行う前に、以下を確認してみてください。
- 環境情報(OS、言語、ライブラリ、バージョン)を書いたか
- 期待結果と実際結果を書いたか
- 最近変更したことを書いたか
- いきなり修正コードを求めず、原因仮説を出させたか
- AIの修正をローカルで実行確認したか
- テスト観点を確認したか
- 機密情報をコードから除去したか
まとめ
AIにコードを丸投げするのではなく、原因仮説・レビュー観点・テスト観点を増やす相手として使うと、実装中の壁打ちは安定します。
今回の記事で紹介した内容を振り返ります。
- AIにエラーを丸投げすると別のバグが入る — 原因仮説を先に出させる
- 3つの型(エラー相談型・コードレビュー依頼型・テスト観点生成型)で壁打ちが安定する
- AIが間違えやすいパターンを知っておくと対策できる
- AIの回答は必ず検証する — ローカル実行・テスト・公式ドキュメント確認
次回予告
次回は、AIとの壁打ちログをナレッジ化してポートフォリオに変える方法を扱います。
ここまでの4回で扱った壁打ちの結果を、どうやって「流して終わり」ではなく「再利用できる資産」に変えるかを整理します。壁打ちログをMarkdown化し、RAG・MCP・Qiita記事・ポートフォリオに接続する方法を紹介します。
この記事では、AIの回答をそのまま正解として扱うことは推奨しません。
実務利用時は、機密情報を入れないこと、出力を検証すること、必要に応じて人間が判断することを前提にしています。
連載一覧
- AIとの壁打ちは「質問」ではなく「思考プロセス設計」である
- 曖昧なアイデアを要件に変えるAI壁打ちテンプレート
- 実装前にAIと設計レビューするための壁打ち手順
- AIに丸投げしないコードレビュー・デバッグ壁打ち術 ← 今回
- AIとの壁打ちログをナレッジ化してポートフォリオに変える