AIがコーディング中に間違うのにレビューで発見できる理由:研究と技術的解説
この記事はAIによって生成されています。内容の正確性は保証されず、記事の利用による損害について一切の責任を負いません。この記事を読み進めることで、利用規約に同意したものとみなされます。
概要
AIにコードを書かせると、時々エラーや非効率な実装が混入します。しかし興味深いことに、そのコードを同じAIにレビューさせると、自分で問題を発見して修正案を出してくれることがよくあります。本記事では、この現象の背後にある仕組みを、最新の研究知見(Kamoi et al., 2024; Pan et al., 2024)とTransformerアーキテクチャの技術的動作原理から解説します。対象読者はAIを開発業務で活用しているソフトウェアエンジニアです。
本記事について
本記事は、LLMの自己修正に関する最新研究(2024-2025年)の知見と、Transformerアーキテクチャの技術的動作原理を統合した技術解説です。研究で明らかになった事実と、技術的解釈を組み合わせて、実務での活用方法まで説明します。
対象読者: AIを開発業務で活用しているソフトウェアエンジニア
本記事の構成:
- 現象の概要と要因
- 技術的な動作原理の解説
- 最新研究からの重要な知見
- 実践的な活用方法
現象の概要:なぜAIは「書く時」と「見る時」で精度が変わるのか
まず、この現象が起こる主な要因を整理しましょう。
1. コンテキストウィンドウと注意の分散
コーディング中、AIは複数の要素を同時に考慮しています。アーキテクチャ設計、ロジック実装、構文の正確性、エッジケース処理、パフォーマンス最適化、命名規則の統一など。このマルチタスク状態では、細かいミスを見落としやすくなります。
一方、レビュー時は既存のコードを分析することに集中できるため、より注意深く細部を観察できます。
2. 生成フェーズと評価フェーズの違い
これが最も重要なポイントです。 コードを生成する時と評価する時では、AIの内部的な処理プロセスが根本的に異なります。詳しくは後述します。
3. プロンプトの明示性
「コードを書いて」というリクエストは比較的オープンエンドですが、「このコードをレビューして」というリクエストは、エラーや改善点を探すという明確な目的を持っています。この目的の明確さが、AIの注意を問題発見に集中させます。
4. 検証タスクと生成タスクの難易度差
生成時は「正しいコードを作る」という難しいタスクですが、評価時は「間違いパターンを探す」という、比較的簡単なタスクになります。これは後述する研究でも裏付けられています。
5. 段階的な推論の可能性
レビュー時には、コード全体を見渡して段階的に推論できます:
- このコードは何をしようとしているのか
- 実際に何をしているのか
- ギャップや問題はあるか
生成時は逐次的に進むため、この俯瞰的な視点が持ちにくいのです。
技術解説:生成フェーズと評価フェーズの違い
ここからは、Transformerアーキテクチャの動作原理に基づいて、生成と評価の違いを技術的に解説します。
生成フェーズの仕組み
言語モデルは自己回帰的(autoregressive)に動作します(Vaswani et al., 2017)。これはTransformerアーキテクチャの基本的な特性です。
1. 逐次的な予測
一度に1トークンずつ、「次に来る最も確率の高い単語/記号」を予測します。
1
2
3
def calculate_sum( → 次は 'numbers' が来る確率が高い
→ 次は ')' が来る
→ 次は ':' が来る...
既に生成したトークンが次の予測のコンテキストになります。
2. パス依存性(技術的解釈)
一度あるトークンを生成すると、そのトークンが次の予測の入力になります。これにより、最初の選択が後続の生成に影響を与える「パス依存性」が生じます。
例:変数名を total_sum と書き始めたら、後続のコードでもその名前を使い続ける傾向があります。たとえ途中で total_count の方が適切だと「判断」しても、既に生成した内容との一貫性を保とうとします。
3. 局所的な最適化(技術的解釈)
各ステップで「今この瞬間に最も良さそうな」選択をしますが、それが全体として最適とは限りません。いわば「木を見て森を見ず」状態になりやすいのです。
4. コミットメントの連鎖(実例)
1
2
3
4
5
6
# 最初に間違った前提でコードを書き始めると...
def process_data(items):
result = [] # listを使うとコミット
for item in items:
result.append(item * 2) # list前提で続く
return result[0] # ここで論理エラー
最初の result = [] という選択が、後続のコード構造を規定してしまいます。全要素を処理したのに最初の要素だけ返すという矛盾が生じても、既に生成した流れに引きずられます。
評価フェーズの仕組み
一方、レビュー時は異なるアプローチが可能になります。
1. 完全なコンテキスト
コード全体が既に存在し、全体を一度にアテンション(attention)の対象にできます。開始と終了、入力と出力の関係を同時に見渡せるのです。
2. 双方向的な推論(技術的解釈)
1
2
3
4
5
レビュー時の思考プロセス:
「この関数は何をする?」 → 関数名とdocstringを見る
「実装は意図と一致する?」 → ロジックを追う
「エッジケースは?」 → 条件分岐を確認
「変数名は一貫している?」 → 全体をスキャン
前から後ろだけでなく、後ろから前への推論も可能です。
3. 制約の確認
「このコードはXをすべき」という明確なゴールがあるため、それに照らして評価できます。生成時の「何を書くべきか」より、評価時の「これは正しいか」の方が判断しやすい問題です。
4. パターンマッチング
既知のバグパターンを探すことに集中できます:
- off-by-one error
- null pointer exception
- type mismatch
- division by zero
具体例で比較
生成フェーズでの失敗例
プロンプト: 「リストの平均を計算する関数を書いて」
AIの処理(簡略化):
1
2
3
4
5
6
7
→ def が必要
→ 関数名... calculate_average
→ 引数... numbers
→ 合計を計算... sum(numbers)
→ 長さで割る... / len(numbers)
→ 返す... return
→ 完成!
この過程で「numbersが空リストの場合」を考慮し忘れる可能性があります。各ステップで「正しい次のトークン」を生成することに集中しているためです。
評価フェーズでの発見
プロンプト: 「このコードをレビューして」
AIの処理:
1
2
3
4
5
→ 関数全体を読む
→ 入力の型を確認:リスト
→ エッジケースを考える:空リスト?
→ len(numbers)が0の場合、ZeroDivisionErrorになる!
→ 問題発見
評価時は、コード全体を見た上で「何が悪いか」を探すため、発見しやすいのです。
Transformerアーキテクチャの観点から
技術的な観点では、言語モデルの内部動作として(Vaswani et al., 2017):
- 生成時: 左から右への因果的attention(causal attention)のみ使用。未来のトークンは見えない(causal maskingにより制限)
- 評価時: 完成したテキスト全体に対してattentionを適用できる。全トークン間の関係を同時に評価可能
因果的attentionは、GPTのような自己回帰型モデルで使用される仕組みで、各トークンが自分より前のトークンにしかアクセスできないようにマスキングします。これは生成時に未来の情報を「見る」ことを防ぐために不可欠ですが、同時に全体的な文脈を把握する能力を制限します。
最新研究からの重要な知見
ここまでは技術的な動作原理の解説でしたが、最新の研究結果も理解しておくことが重要です。
「認識することは避けることより簡単」という仮説の真実
Kamoi et al. (2024) の “When Can LLMs Actually Correct Their Own Mistakes?” という研究は、自己修正に関する重要な発見をしています。
この仮説(Saunders et al., 2022)は、長い間自己修正研究の基礎となっていましたが、最新の研究では以下のことが明らかになっています:
この仮説は条件付きでのみ真実です。
研究の主な発見
純粋な自己修正は限定的
外部ツールやフィードバックなしで、LLMが自分の間違いを単純なプロンプトだけで修正することは、一般的なタスクでは成功していません。
検証が簡単なタスクでのみ有効
自己修正が機能するのは、「検証タスクが元のタスクより大幅に簡単」な特定のタスクに限られます。
外部フィードバックが重要
コード実行結果、unit testの結果、コンパイラエラーなどの外部フィードバックがある場合、自己修正は効果的に機能します。
ファインチューニングの効果
大規模なファインチューニングを行うことで、自己修正能力を向上させることができます。
コード生成における自己修正の実態
Pan et al. (2024) と Chen et al. (2024) の研究も合わせると、コード生成の文脈では以下のように整理できます:
成功するケース:
- unit testの実行結果がある
- コンパイラエラーメッセージがある
- linterの指摘がある
- 実行時エラーのトレースがある
限定的なケース:
- 単純なプロンプトだけでレビューを求める(本記事で説明している現象)
- 明らかな構文エラーやロジックミス
失敗するケース:
- 複雑なロジックエラー
- パフォーマンス問題
- セキュリティ脆弱性
- 外部フィードバックなしの自己発見
実務への示唆
これらの研究結果から、実務では以下の理解が重要です:
- 単純なレビュー依頼は限定的な効果 - 本記事で説明した現象は存在しますが、万能ではありません
- 外部検証の重要性 - テスト実行、コンパイル、静的解析などの客観的なフィードバックが不可欠
- イテレーションの価値 - 生成→検証→修正のサイクルを回すことで品質が向上
実践的な活用法
研究知見と技術的理解を踏まえた、実務で使えるワークフローを紹介します。
基本ワークフロー
1
2
3
4
5
6
7
8
9
1. コードを生成させる
↓
2. 自動テスト/静的解析を実行
↓
3. 結果をAIにフィードバック
↓
4. AIにレビュー+修正を依頼
↓
5. 必要に応じて繰り返し
レベル別の実装方法
Level 1: 基本的なレビュー依頼(限定的な効果)
1
2
3
プロンプト例:
「このコードをレビューして、問題点を指摘してください。
特にエッジケース、エラーハンドリング、パフォーマンスの観点で。」
効果が期待できる問題:
- 明らかな構文エラー
- 単純なロジックミス
- 基本的なエッジケースの見落とし
効果が期待できない問題:
- 複雑なロジックエラー
- パフォーマンス問題
- セキュリティ脆弱性
Level 2: 外部フィードバック活用(推奨)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. コード生成
code = ai.generate("リストの平均を計算する関数")
# 2. テスト実行
test_result = run_tests(code)
# 3. 結果をフィードバック
improved_code = ai.improve(
code=code,
feedback=f"""
テスト結果:
{test_result}
エラーがある場合は修正してください。
"""
)
効果が期待できる問題:
- テストで検出可能なすべてのバグ
- コンパイルエラー
- 実行時エラー
Level 3: CI/CDパイプライン統合(本格運用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# GitHub Actions例
- name: Generate Code
run: ai-generate --prompt "$"
- name: Run Tests
run: pytest tests/
continue-on-error: true
- name: Static Analysis
run: |
pylint src/
mypy src/
- name: AI Review and Fix
if: failure()
run: |
ai-review \
--code src/ \
--test-results test-results.xml \
--lint-results pylint-results.txt \
--auto-fix
- name: Re-run Tests
run: pytest tests/
効果的なプロンプト設計
研究結果を踏まえた効果的なプロンプトの構成:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[コンテキスト]
以下のコードは○○を実行するための関数です。
[コード]
{生成されたコード}
[外部フィードバック](重要!)
テスト結果:{test_output}
静的解析結果:{lint_output}
実行結果:{execution_output}
[依頼内容]
1. 上記のフィードバックを分析してください
2. 問題がある場合、原因を特定してください
3. 修正したコードを提供してください
4. 修正内容を簡潔に説明してください
アンチパターン
避けるべき使い方:
❌ 単純なレビュー依頼のみ
1
2
「このコード、問題ないですか?」
→ 限定的な効果しかない
❌ 外部検証なし
1
2
生成 → レビュー → 完了
→ 複雑な問題は見逃される
❌ 無限ループ
1
2
生成 → レビュー → 修正 → レビュー → 修正 → ...
→ 改善しない場合は要件を見直す
✅ 推奨パターン
1
2
生成 → テスト実行 → 結果フィードバック → レビュー+修正 → 再テスト
→ 外部検証を挟む
ツール活用例
実際に使えるツールの組み合わせ:
開発環境:
- GitHub Copilot / Cursor / Claude Code:生成
- pytest / jest:テスト
- pylint / ESLint:静的解析
- AI API:レビュー+修正
自動化:
- GitHub Actions / GitLab CI:CI/CD
- pre-commit hooks:コミット前チェック
- Renovate:依存関係更新
まとめ
AIがコーディング中に間違うのにレビューで発見できる現象は、言語モデルの動作原理に由来する特性です。
技術的理解
- 生成フェーズ: 自己回帰的、逐次的、局所的最適化
- 評価フェーズ: 全体把握、双方向推論、パターンマッチング
- Transformer: 因果的attentionによる制約
研究からの知見
- 純粋な自己修正能力には限界がある(Kamoi et al., 2024)
- 外部フィードバックが効果的(Pan et al., 2024; Chen et al., 2024)
- 検証が簡単なタスクでのみ有効
実務での活用
効果的なワークフローの要点:
- 生成と評価を分離 - 別のプロンプトで実行
- 外部検証を必須化 - テスト、静的解析、実行確認
- フィードバックループ - 結果を基に改善
- 限界を理解 - 複雑な問題は人間がレビュー
これは人間が文章を書く時と校正する時の違いにも似ています。書いている最中は流れに乗って進みますが、後で読み返すと明らかな誤字に気づきます。しかし、複雑な論理エラーは見落とすことがあります。同様に、AIも外部の検証手段があってこそ、より確実に問題を発見できるのです。
実務で最も重要なポイント: 単純なレビュー依頼だけに頼らず、テスト実行やlintなどの客観的なフィードバックを組み合わせることで、AIの自己修正能力を最大限に引き出せます。
関連記事
参考資料
学術論文 (Academic Papers)
When Can LLMs Actually Correct Their Own Mistakes? A Critical Survey of Self-Correction of LLMs - Kamoi, R., Zhang, Y., Zhang, N., Han, J., & Zhang, R. (2024). Transactions of the Association for Computational Linguistics, 12, 1417–1440. 【信頼性: 高】
Automatically Correcting Large Language Models: Surveying the Landscape of Diverse Automated Correction Strategies - Pan, L., Saxon, M., Xu, W., Nathani, D., Wang, X., & Wang, W. Y. (2024). Transactions of the Association for Computational Linguistics, 12, 484–506. 【信頼性: 高】
An Empirical Study on Self-correcting Large Language Models for Data Science Code Generation - Thai, T. T. Q., Duc, H. M., Tho, Q. T., & Nguyen-Duc, A. (2024). arXiv preprint arXiv:2408.15658. 【信頼性: 高】
Attention is all you need - Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł., & Polosukhin, I. (2017). Advances in Neural Information Processing Systems, 30. 【信頼性: 高】
Self-critiquing models for assisting human evaluators - Saunders, W., Yeh, C., Wu, J., Bills, S., Ouyang, L., Ward, J., & Leike, J. (2022). arXiv preprint arXiv:2206.05802. 【信頼性: 高】
Self-Refine: Iterative Refinement with Self-Feedback - Madaan, A., Tandon, N., Gupta, P., Hallinan, S., Gao, L., Wiegreffe, S., Alon, U., Dziri, N., Prabhumoye, S., Yang, Y., Welleck, S., Majumder, B. P., Gupta, S., Yazdanbakhsh, A., & Clark, P. (2023). Advances in Neural Information Processing Systems, 36. 【信頼性: 高】
本記事の内容は2025年10月時点の研究に基づいています。AI技術と研究は急速に進展しているため、最新の論文も参照することをお勧めします。