Flaps

プロンプト Self‑Consistency(SC)

軽量モデルへ代表的なプロンプト手法を実際のコードで試しモデルの反応を確認します

記事作成日:2025-12-05, 著者: Hi6

このガイドはなぜ必要か?
現代のLLM(大規模言語モデル)は、正しく誘導されて初めて複雑な推論タスクを解決できます。以下に示す手法は、信頼性・説明可能性・高性能システム構築の「標準的ケア」として確立されています。それぞれが、モデルへの指示量や内部で考えるか外部ツールと対話するかという点で異なります。

影響力が大きい6つの手法を深掘り:


Self‑Consistency(SC) とは?

概要 LLM が同じ質問を複数回実行し、最も頻出する答え(または統計的に最も確からしいもの)を採用する手法。


2️⃣ 基本構造(テンプレート)

Task: [タスクの簡潔な説明]

Example 1:
Input: ...
Output: ...

...

Now solve (Self‑Consistency):
Input: [ユーザーが入力する問題]
Answer candidates:
1. [回答1]
2. [回答2]
3. [回答3]
...
Final answer: [最頻出現/統計的に最高の答え]

3️⃣ 実装手順

ステップ方法
1. タスク定義Task: で何を求めるか明示。
2. 例(オプション)Example を入れると、モデルがパターンを学習しやすい。
3. 複数回実行同じ Input に対して、同一プロンプトで N 回 (例: 5〜10) 実行。
4. 結果収集各呼び出しの Output をリスト化。
5. 一致率計算出力が文字列一致するものをカウント。
6. 最終答え決定- 多数決(最頻値)
- 確率的重み付け(出現確率が高いもの)
7. 出力Final answer: に最終結果を返す。

4️⃣ 実際の実装例(Python + Ollama)

import collections, ollama

def self_consistency(user_prompt, n=5):
    outputs = []
    client = ollama.Client(host="http://127.0.0.1:11434")
    for _ in range(n):
        response = client.chat(
            model="qwen3-vl:8b",
            messages=[
                {"role": "system", "content": system_prompt},  # 常に同じタスク
                {"role": "user",   "content": user_prompt}    # 本番入力だけ
            ]
        )
        answer = response["message"]["content"].strip()
        outputs.append(answer)

    most_common, _ = collections.Counter(outputs).most_common(1)[0]
    return most_common, outputs

# 例:数式計算タスク
system_prompt = """
You are a helpful assistant.
Task: 与えられた数式を計算してください。
"""

user_prompt = """
Now solve:
Input: (9 - 2)² / 7
Output:
"""

final_answer, candidates = self_consistency(user_prompt, n=10)
print("Candidates:", candidates)
print("\nFinal answer:", final_answer)

出力結果: Candidates: ['The calculation proceeds as follows:\n\n1. Compute the expression inside the parentheses: \n $ 9 - 2 = 7 $\n\n2. Square the result: \n $ 7^2 = 49 $\n\n3. Divide by 7: \n $ \\frac{49}{7} = 7 $\n\n**Output:** \n7', '(9 - 2)² / 7 \n= 7² / 7 \n= 49 / 7 \n= **7** \n\nOutput: 7', '(9 - 2)² / 7 \n= (7)² / 7 \n= 49 / 7 \n= **7**\n\nOutput: 7', '(9 - 2)² / 7 \n= 7² / 7 \n= 49 / 7 \n= **7** \n\nOutput: 7', '(9 - 2)² / 7 \n= (7)² / 7 \n= 49 / 7 \n= **7**\n\nOutput: 7', '7', '(9 - 2)² / 7 \n= (7)² / 7 \n= 49 / 7 \n= 7 \n\n**Output:** 7', '7', 'The calculation proceeds as follows:\n\n1. Evaluate the expression inside the parentheses: \n $ 9 - 2 = 7 $\n\n2. Square the result: \n $ 7^2 = 49 $\n\n3. Divide by 7: \n $ 49 / 7 = 7 $\n\n**Answer:** \n7', '(9 - 2)² / 7 \n= (7)² / 7 \n= 49 / 7 \n= 7 \n\n**Output:** 7']

Final answer: (9 - 2)² / 7
= 7² / 7
= 49 / 7
= 7

Output: 7


5️⃣ Self‑Consistency のメリット

メリット説明
精度向上ランダム性を打ち消し、誤答率を低減。
透明性「複数の候補」を提示できる → ユーザーが「どれで決めたか」を理解しやすい。
柔軟性既存プロンプト(Few‑Shot・CoT)と組み合わせて使える。

6️⃣ Self‑Consistency のデメリット

デメリット説明
計算コスト増大同じ質問を N 回呼び出すため、API コスト・時間が増加。
一貫性の欠如まれに「多数決」でも誤答が選ばれるケース(例:すべて異なる答え)。
長文回答で問題長い出力は同じ内容でも微妙な違いがあると分岐しやすい。

7️⃣ コツ・ベストプラクティス

  1. N を調整

    • N=3 は最低限、N=5〜10 が一般的。
    • コストを考慮して、タスクの難易度に応じて設定。
  2. 出力形式を統一

    • 例:数式計算なら「答えのみ」、文章回答なら「結論」など統一。
    • 文字列一致しやすくなる。
  3. 候補の表示

    • ユーザーに候補を見せると、信頼感が増す。
    • 例:Answer candidates: 1. ... 2. ... 3. ...
  4. 重み付け

    • 出現頻度だけでなく、モデルの確信度(logits)やスコアを利用して選択するとさらに精度向上。
  5. 混合手法

    • Few‑Shot + CoT + Self‑Consistency を組み合わせると、最も高いパフォーマンスが期待できる。
     Task: ...
     Example 1:
       Input: ...
       Thought: ...
       Output: ...
     Now solve (Self‑Consistency):
       Input: ...
       Answer candidates:
         1. ...
         2. ...
         3. ...
       Final answer: ...

🎯 まとめ

これをベースに、タスクごとに N を調整し、Few‑ShotCoT と組み合わせることで、LLM の回答品質を最大限に引き上げられます! 🚀