CoTとSelf-ConsistencyによるLLM推論強化のプロンプト設計と評価

Tech

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

CoTとSelf-ConsistencyによるLLM推論強化のプロンプト設計と評価

大規模言語モデル(LLM)の推論能力は、プロンプト設計の工夫によって大きく向上します。本記事では、Chain-of-Thought (CoT) プロンプティングとSelf-Consistencyを組み合わせた推論強化のアプローチについて、プロンプト設計から評価、改良までの一連のプロセスを解説します。

ユースケース定義

LLMが複雑な多段階推論を要するタスク(例:算数問題、論理パズル、コード生成、長文要約、法務文書分析)において、高精度な出力を生成することを目的とします。特に、単一の正解に至るまでの思考プロセスが重要となる場面で、LLMの推論の透明性と信頼性を高めます。

制約付き仕様化(入出力契約)

入力契約

  • フォーマット: プレーンテキスト、JSON形式のデータ。

  • 必須情報: 解決すべき問題の明確な記述。CoTを誘発するための指示(例: “ステップバイステップで考えてください。”)を含める場合がある。

  • 文字数制限: 最大4000トークン。超過時はエラーまたは要約を促す。

  • 禁止事項:

    • 個人情報(PII)や機密情報を含む入力。

    • 違法行為、ハラスメント、ヘイトスピーチ、その他不適切な内容を推奨する入力。

    • 無限ループを引き起こす可能性のある再帰的な指示。

出力契約

  • フォーマット:

    • 最終的な解答は特定の部分(例: 最終解答:)に明示的に記述する。

    • CoTの推論過程は箇条書きまたは段落形式で段階的に記述する。

    • エラー発生時、または解答不能な場合は、特定のJSON構造 { "status": "error", "message": "エラー内容" } または status: indeterminate を返す。

  • 信頼性: 回答の根拠(推論ステップ)を必ず提示する。

  • タイムアウト: 30秒以内に回答できない場合は処理を中断し、エラーを返す。

  • 禁止事項:

    • 入力契約の禁止事項に該当する内容を含む出力。

    • 根拠のない断定的な記述や幻覚(Hallucination)。

    • プロンプトにない新たな問いかけや、タスク範囲外のコメント。

プロンプト設計

LLMの推論能力を引き出すために、CoTとSelf-Consistencyの導入を前提としたプロンプトを設計します。

1. ゼロショットプロンプト

CoTの指示を含まない基本的なプロンプト。モデルのベースライン性能を測定します。

以下の問題を解決してください。

問題: ある箱には赤色のボールが3個、青色のボールが5個入っています。この箱からランダムに2個のボールを取り出すとき、2個とも青色のボールである確率を計算してください。最終解答のみを提示してください。

最終解答:

2. 少数例プロンプト(Few-shot with CoT examples)

CoTの例を複数提示し、モデルに推論の過程を模倣させます。

以下の問題をステップバイステップで解決し、最終解答を提示してください。

例1:
問題: Aさんはリンゴを5個持っており、Bさんはその2倍の数を持っています。Bさんはリンゴをいくつ持っていますか?
思考過程:

1. 問題を理解する。Aさんのリンゴの数は5個。BさんはAさんの2倍。

2. Bさんのリンゴの数を計算する。5個 × 2 = 10個。
最終解答: 10個

例2:
問題: Cさんは午前中に5km、午後に3km歩きました。Cさんは合計何km歩きましたか?
思考過程:

1. 問題を理解する。午前中に5km、午後に3km。

2. 合計距離を計算する。5km + 3km = 8km。
最終解答: 8km

問題: ある箱には赤色のボールが3個、青色のボールが5個入っています。この箱からランダムに2個のボールを取り出すとき、2個とも青色のボールである確率を計算してください。

思考過程:

3. Chain-of-Thought制約型プロンプト

モデルに思考過程の明示を強く促すプロンプト。Self-Consistencyと組み合わせることで、多様な推論経路を生成し、多数決で最も確からしい最終解答を選出します。

あなたは高度な推論能力を持つAIアシスタントです。以下の問題について、厳密にステップバイステップで思考プロセスを詳述し、その後に最終解答を導き出してください。思考の各段階を明確に区切ってください。

問題: ある箱には赤色のボールが3個、青色のボールが5個入っています。この箱からランダムに2個のボールを取り出すとき、2個とも青色のボールである確率を計算してください。

思考過程:
1.
2.
...
最終解答:

Self-Consistencyの適用方法: このCoT制約型プロンプトをLLMに対して複数回(例: N=5〜10回)実行し、それぞれ異なる思考過程と最終解答を得ます。その後、得られたN個の最終解答の中から多数決(または最も頻繁に出現する解答)を選択して、最終的な解答とします。これにより、単一の思考パスの誤りに起因するエラーを軽減し、推論の堅牢性を高めます[2]。

評価

プロンプトの有効性を評価するため、複数のシナリオと自動評価手法を定義します。

評価シナリオ

  1. 正例(Happy Path): 標準的な算数問題や論理パズルで、明確な解答が存在するもの。

    • 例: 「XがYの2倍で、ZがXより5少ない場合、Zはいくつか?」
  2. 難例(Edge Cases/Complexities): 複数の条件分岐や確率計算、あいまいな表現を含む問題。

    • 例: 「3つの扉があり、1つに賞品があります。扉を選んだ後、司会者が残りの扉のうち1つを開けて、賞品がないことを示します。あなたは最初に選んだ扉を変えるべきですか?変える場合と変えない場合の確率を計算しなさい。」(モンティ・ホール問題)
  3. コーナーケース(Ambiguous Inputs): 情報が不足している、矛盾している、あるいは複数の解釈が可能な問題。

    • 例: 「ある場所から東に10km進み、北に5km進みました。最終的な場所はどこですか?」 (開始地点が不明確)

自動評価(擬似コード)

Pythonによる自動評価の擬似コードを以下に示します。

import re
from collections import Counter

def evaluate_llm_output(problem: str, expected_answer: str, llm_outputs: list[str]) -> dict:
    """
    LLMの出力を自動評価する。Self-Consistencyを考慮し、多数決で最終解答を判定。

    Args:
        problem (str): 評価対象の問題文。
        expected_answer (str): 期待される正解。
        llm_outputs (list[str]): LLMから得られた複数の出力文字列(CoTを含む)。

    Returns:
        dict: 評価結果 (正誤、信頼度、解析済み解答)
    """
    extracted_answers = []

    for output in llm_outputs:

        # 最終解答を抽出するための正規表現(例: "最終解答: " の後に続く文字列)

        match = re.search(r"最終解答:\s*(.*)", output)
        if match:
            answer_str = match.group(1).strip()

            # 数値の場合は、数値のみを抽出して比較しやすくする

            try:
                extracted_answers.append(float(answer_str))
            except ValueError:
                extracted_answers.append(answer_str.lower()) # 文字列は小文字化して比較
        else:
            extracted_answers.append("NO_ANSWER_FOUND")

    if not extracted_answers:
        return {"correct": False, "confidence": 0.0, "final_answer": "NO_ANSWER_GENERATED"}

    # Self-Consistency: 抽出された解答の多数決を取る

    answer_counts = Counter(extracted_answers)
    most_common_answer, count = answer_counts.most_common(1)[0]

    # 信頼度(多数決の比率)

    confidence = count / len(extracted_answers)

    # 正解判定

    is_correct = False
    if isinstance(most_common_answer, float):

        # 浮動小数点数の比較は許容誤差を設ける

        if isinstance(expected_answer, (int, float)):
            is_correct = abs(most_common_answer - float(expected_answer)) < 1e-6
    else:
        is_correct = (most_common_answer == expected_answer.lower()) # 大文字小文字を区別しない

    return {
        "correct": is_correct,
        "confidence": confidence,
        "final_answer": most_common_answer,
        "all_extracted_answers": extracted_answers
    }

# 使用例 (JST: 2024年7月30日)


# llm_output_1 = "思考過程: ... 最終解答: 10.0"


# llm_output_2 = "思考過程: ... 最終解答: 10"


# llm_output_3 = "思考過程: ... 最終解答: 12.0"


# outputs = [llm_output_1, llm_output_2, llm_output_3]


# result = evaluate_llm_output("2個とも青色のボールである確率", 0.35714285714, outputs)


# print(f"評価結果: {result}")

誤り分析

LLMの推論における主な失敗モードとその抑制手法を以下に示します。

失敗モード

  • 幻覚(Hallucination): 事実に基づかない情報を生成する。特に確率計算で誤った前提や計算式を用いる場合。

  • 様式崩れ(Format Deviation): 定義した出力契約(例: 最終解答:の欠如、思考過程の構造化不良)に従わない。

  • 脱線(Task Diversion): 問題解決とは関係のない情報や個人的な意見を述べ始める。

  • 禁止事項違反: 機密情報や不適切な内容を出力する。

  • 論理の飛躍/誤謬: 推論の途中で論理的なつながりが欠如したり、誤った前提で結論を導き出したりする。

抑制手法

  • System指示の強化: プロンプトの先頭に、LLMの役割、制約、出力フォーマットに関する厳格な指示(例: 「あなたは指定されたフォーマットを厳守するAIアシスタントです。一切の余分な発言は禁止します。」)を記述する。

  • 検証ステップの追加: 推論過程で外部ツール(計算機、API、データベース)を利用して中間結果を検証させるプロンプト(Tool-use prompting)を導入する。

  • リトライ戦略: 出力フォーマットが崩れた場合や、特定のエラーキーワードが含まれる場合に、自動的にプロンプトを再送信する。

  • ガードレール: 出力結果を人間または別のAIで確認し、不適切な内容や形式不備を検出・フィルタリングする。

  • Self-Correction: モデル自身に自身の出力を批判的に見直し、修正させるプロンプトを設計する。

改良

評価と誤り分析の結果に基づき、プロンプトと評価プロセスを反復的に改良します。

  1. プロンプトの具体化: 誤り分析で特定された失敗モード(例: 計算ミス)に対し、その部分のCoT指示をより詳細化する(例: 「確率計算では、分子と分母を明確に示し、約分する前の数値を明記してください。」)。

  2. Few-shot例の追加/修正: モデルが苦手とする問題タイプに対して、高品質なFew-shot CoT例を追加または修正し、推論パターンを学習させる。

  3. 温度パラメータの調整: Self-Consistencyのための複数生成時、temperatureパラメータを0.7〜1.0に設定して多様な思考経路を促し、多数決の選択肢を増やす。本稿執筆時点(2024年7月30日)での研究では、CoTとSelf-Consistencyの組み合わせは、低い温度での単一推論よりも堅牢であることが示されています[1],[2]。

  4. 評価メトリクスの拡張: 曖昧な問題に対する評価において、部分点や説明の質の評価基準を追加する。

再評価

改良したプロンプトと評価プロセスを用いて、再度評価シナリオを実行し、改善度を定量的に測定します。特に、前回失敗した難例やコーナーケースに対する正答率とSelf-Consistencyによる信頼度(多数決の比率)の向上を追跡します。これにより、プロンプトの変更が実際の性能に与える影響を検証します。

まとめ

CoTとSelf-Consistencyは、LLMの複雑な推論タスクにおける性能と信頼性を飛躍的に向上させる強力な手法です。本記事では、その具体的なプロンプト設計、厳密な入出力契約、自動評価、そして反復的な改良プロセスについて解説しました。これらのアプローチを適用することで、LLMをより堅牢で信頼性の高い推論エンジンとして活用することが可能となります。


graph TD
    A["要求定義・評価指標設定"] --> B{"プロンプト設計"};
    B -- ゼロショット / 少数例CoT --> C1["LLM推論"];
    B -- CoT制約型 --> C2["LLM推論 (複数回)"];
    C1 --> D{"Self-Consistency適用"};
    C2 --> D;
    D -- 推論結果 --> E["自動評価"];
    E -- 評価結果 --> F{"誤り分析"};
    F -- 洞察 --> G["プロンプト改良"];
    G --> B;
    E -- 評価メトリクス --> H["再評価"];

参考文献 [1] Wei, J., Tay, Y., Bommasani, R., et al. (2022). Chain-of-Thought Prompting Elicits Reasoning in Large Language Models. arXiv preprint arXiv:2201.11903. Retrieved from https://arxiv.org/abs/2201.11903 (公開日: 2022年1月27日) [2] Wang, X., Wei, J., Schuurmans, D., et al. (2022). Self-Consistency Improves Chain of Thought Reasoning in Large Language Models. arXiv preprint arXiv:2203.11171. Retrieved from https://arxiv.org/abs/2203.11171 (公開日: 2022年3月21日) [3] Google AI Blog. (2022, May 10). Better Language Models with Chain-of-Thought Prompting. Retrieved from https://ai.googleblog.com/2022/05/language-models-chain-of-thought.html (公開日: 2022年5月10日)

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

コメント

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