CoT(思考連鎖)を用いた複雑なソースコードのバグ修正・リファクタリング支援

Tech

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

CoT(思考連鎖)を用いた複雑なソースコードのバグ修正・リファクタリング支援

【ユースケース定義と課題】

  • ユースケース:レガシーコードや複雑なアルゴリズムにおける、エッジケースを考慮したバグ特定と修正コードの生成。

  • 課題:LLMが即座にコードを出力すると、境界条件(NULL値、極値など)の考慮漏れや、既存ロジックの破壊が発生しやすい。

  • 入出力の型

    • 入力:Markdown(コードブロック + バグの症状・要件)

    • 出力:JSON形式(思考プロセス、修正方針、修正コード、テストケースの4要素を内包)

【プロンプト設計のループ】

graph TD
A["設計: 思考プロセスの分離"] --> B["実行: CoTプロンプトの適用"]
B --> C["評価: 精度・構文の自動検証"]
C -->|改善: 逸脱防止ルールの追加| A
  1. 設計:コード生成の前に「現状分析」「原因特定」「修正方針」「影響範囲」を強制的に思考(CoT)させるステップを定義します。

  2. 実行:Few-shotを用いて、思考ステップを踏んでから最終出力を得るプロセスをLLMに学習させます。

  3. 評価:生成されたコードが構文的に正しく、かつ指定したJSONフォーマットを遵守しているかを検証し、エラーがあればプロンプトにフィードバックします。

【プロンプトの実装案】

# 指示

あなたは優秀なシニアソフトウェアエンジニアです。
提供されたソースコードのバグを修正し、指定されたJSONフォーマットで出力してください。
回答を出力する前に、必ず「思考プロセス(Chain-of-Thought)」を実行し、バグの原因、修正方針、影響範囲をステップ・バイ・ステップで分析してください。

# 出力フォーマット

必ず以下のJSONフォーマットのみで出力してください(マークダウンのコードブロックで囲んでください)。

{
  "thought_process": {
    "analysis": "コードの現状の挙動と問題点に対する詳細な分析",
    "root_cause": "バグの根本原因の特定",
    "edge_cases": ["考慮すべきエッジケース1", "考慮すべきエッジケース2"]
  },
  "fix_strategy": "修正方針の説明",
  "fixed_code": "修正後のソースコード全体",
  "test_cases": [
    {
      "input": "テスト入力",
      "expected_output": "期待される出力"
    }
  ]
}

# 例示(Few-Shot)

## 入力コード(Python)

def divide_list(values, divisor):
    return [v / divisor for v in values]

## 入力バグ報告

divisorが0の場合にZeroDivisionErrorが発生する。空のリストが渡された場合は空のリストを返したい。

## 出力

{
  "thought_process": {
    "analysis": "与えられた関数はリストの各要素をdivisorで割る。divisorが0のとき、ゼロ除算エラーが発生する。",
    "root_cause": "divisorが0である場合の例外処理およびバリデーションが不足している。",
    "edge_cases": ["divisorが0の場合", "valuesが空リストの場合", "valuesに数値以外の型が含まれる場合"]
  },
  "fix_strategy": "divisorが0の場合はValueErrorを発生させるか、事前にバリデーションを行う。今回は安全のためにdivisorが0の場合はカスタム例外またはValueErrorを投げ、空リストの場合はそのまま空リストを返す仕様とする。",
  "fixed_code": "def divide_list(values, divisor):\n    if not values:\n        return []\n    if divisor == 0:\n        raise ValueError('Divisor cannot be zero')\n    return [v / divisor for v in values]",
  "test_cases": [
    {"input": "values=[], divisor=2", "expected_output": "[]"},
    {"input": "values=[10, 20], divisor=0", "expected_output": "ValueError"}
  ]
}

# 修正対象のコード

{{INSERT_CODE_HERE}}

# バグ報告・要件

{{INSERT_BUG_REPORT_HERE}}

【評価指標と誤り分析】

最新のLLM(Gemini 1.5 ProやGPT-4oなど)であっても、以下のような失敗パターンが生じることがあります。

  • 失敗パターン1(様式崩れ):JSONのパースエラー(エスケープ文字の不備、不要なテキストの混入)。

  • 失敗パターン2(思考の浅さ)thought_process の中身が形骸化し、十分な分析を行わずにコード生成へ進んでしまう。

これらを防ぐための、LLM-as-a-Judge用の評価基準を以下に定義します。

評価項目 評価基準 (5点満点) 失敗時の対策
フォーマット遵守率 完全なJSONとしてパース可能であり、スキーマが一致しているか (5: 完全一致, 1: パース不可) スキーマ定義をTypeScriptの型定義等で厳密に指定する。
CoTの深さ 原因分析、エッジケースの洗い出しが具体的に行われているか (5: 網羅的, 1: 空欄または形骸化) システムプロンプトで「各ステップに最低2行以上の記述を求める」制約を課す。
コードの正確性 提示された修正コードがコンパイル/実行可能で、バグが解消されているか (5: 解消済, 1: 未解消) コード生成用とコード検証用(テスト実行環境)でエージェントを分離する。

【改良後の最適プロンプト】

上記の分析結果と、Gemini 1.5 Pro等の「指示追従能力」を最大化するために構造化した、システム指示付きの最適プロンプトです。

# システムロール

あなたは堅牢なソフトウェア開発を専門とする、厳格なコード監査AIエージェントです。

# タスク

入力されたコードのバグを修正してください。ただし、直感的な修正に飛びついてはいけません。必ず以下のステップに従って「深く思考」した結果を、指定のJSON構造で出力してください。

# 思考プロセス(CoT)の実行ルール


1. **静的解析**: コードを1行ずつ読み、不適切な処理や脆弱性がないか調査する。

2. **データフローの追跡**: 異常値、境界値、NULL/None、型不一致が入力された際の挙動を追跡する。

3. **影響範囲特定**: 修正を行うことで、既存の他の処理に悪影響を及ぼさないか検証する。

# 出力フォーマット(厳守)

JSON以外のテキスト(挨拶、前置き、Markdown以外の説明など)は一切出力しないでください。以下のスキーマに従ったJSONブロックのみを出力してください。

```json
{
  "thought_chain": {
    "static_analysis": "コードの静的解析結果",
    "vulnerabilities": ["検出されたバグ・脆弱性のリスト"],
    "boundary_conditions": ["検証した境界条件(空、極大値、NULL等)"]
  },
  "resolution": {
    "strategy": "影響範囲を最小限に抑えるための具体的な修正方針",
    "code": "修正後の完全なコード(インデントや改行を正しくエスケープした文字列)"
  }
}

修正対象

  • 対象言語: {{LANGUAGE}}

  • ソースコード: {{SOURCE_CODE}}

  • 発生している問題: {{ISSUE_DESCRIPTION}} “`

【まとめ】

実務でこのプロンプトを運用するための3つの鉄則:

  1. 思考と出力を分離する:バグ修正のような複雑なタスクでは、ワンショットでコードを出力させるのではなく、必ず「思考(分析)」のステップをプロンプト内で明示的に踏ませる。

  2. JSONパースエラーはスキーマ制約で防ぐ:最新のLLM(GeminiのStructured Outputs等)を利用可能な場合は、APIレベルでスキーマを強制し、テキストとしての崩れを未然に防ぐ。

  3. エッジケースの定義をサボらせない:プロンプト内に「空値、極値、型例外」などの具体的な検証ワードを含めることで、LLMの思考の解像度を強制的に引き上げる。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました