プロンプト 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: [最頻出現/統計的に最高の答え]
- 「Answer candidates」 は、モデルを何回か呼び出して得られた複数の結果。
- 「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️⃣ コツ・ベストプラクティス
-
N を調整
N=3は最低限、N=5〜10が一般的。- コストを考慮して、タスクの難易度に応じて設定。
-
出力形式を統一
- 例:数式計算なら「答えのみ」、文章回答なら「結論」など統一。
- 文字列一致しやすくなる。
-
候補の表示
- ユーザーに候補を見せると、信頼感が増す。
- 例:
Answer candidates: 1. ... 2. ... 3. ...
-
重み付け
- 出現頻度だけでなく、モデルの確信度(logits)やスコアを利用して選択するとさらに精度向上。
-
混合手法
- Few‑Shot + CoT + Self‑Consistency を組み合わせると、最も高いパフォーマンスが期待できる。
Task: ...
Example 1:
Input: ...
Thought: ...
Output: ...
Now solve (Self‑Consistency):
Input: ...
Answer candidates:
1. ...
2. ...
3. ...
Final answer: ...
🎯 まとめ
- Self‑Consistency は「同じ質問を複数回実行し、最も頻出する答えを採用」する手法。
- テンプレート:
Task → Example(s) (optional) → Now solve (SC) - 実装ステップ:N 回呼び出し → 出力収集 → 多数決/重み付け → 最終回答。
- メリット:精度・透明性向上、ランダム性の排除。
- デメリット:計算コスト増大、候補が分岐する場合も。
これをベースに、タスクごとに N を調整し、Few‑Shot や CoT と組み合わせることで、LLM の回答品質を最大限に引き上げられます! 🚀