本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
Few-shotとZero-shotプロンプティングの設計と評価
大規模言語モデル(LLM)の性能を最大限に引き出すためには、効果的なプロンプト設計が不可欠です。本記事では、特にFew-shotとZero-shotプロンプティングに焦点を当て、その設計原則、評価方法、および一般的な課題と解決策について解説します。
ユースケース定義
本稿では、以下のユースケースを想定します。 ユースケース: ユーザーからの商品レビューテキストを分析し、そのレビューが示す感情(ポジティブ、ネガティブ、中立)を分類し、その感情を裏付ける具体的な理由を抽出する。
制約付き仕様化(入出力契約)
入力契約
形式: プレーンテキスト
内容: 日本語の商品レビューテキスト
制約: 最大500文字
出力契約
形式: JSON形式
スキーマ:
{ "sentiment": "ポジティブ" | "ネガティブ" | "中立", "reasons": ["理由1", "理由2", ...], "confidence": "高" | "中" | "低" }各フィールドの制約:
sentiment: 必須。"ポジティブ","ネガティブ","中立"のいずれか。reasons: 必須。レビュー本文から抽出された、感情の根拠となる具体的な理由のリスト。最小1つ、最大3つ。レビュー内に明確な理由がない場合は空のリスト[]を許容する。confidence: 必須。モデルが自身の分析結果に対して持つ自信度。"高","中","低"のいずれか。
失敗時の挙動
JSON形式の崩壊: モデル出力が有効なJSONとしてパースできない場合、アプリケーション側でエラーを返し、ログに記録する。可能であれば、特定のフォーマットを修正して再試行する。
感情の指定外出力:
sentimentフィールドが契約外の値を出力した場合、最も近い許容値に変換を試みるか、エラーとして処理する。理由の未抽出/過剰抽出:
reasonsが契約外の数である場合(0個または4個以上)、エラーとして処理するか、先頭3つにトリミングする。
禁止事項
レビュー内容にない事実や情報を追加で生成しない(幻覚)。
指定されたJSON形式以外の出力をしない。
モデル自身が「AI」であることや、自身の能力について言及しない。
プロンプト設計
以下に3種類のプロンプト案を提示します。
1. Zero-shotプロンプト
事前の学習例なしにタスクを指示する最も基本的な形式です[1]。モデルの汎化能力に依存します。
あなたは熟練した感情分析アシスタントです。 以下のレビューテキストを分析し、感情(ポジティブ、ネガティブ、中立)とその理由、そして分析の自信度をJSON形式で出力してください。 感情の理由はレビューから直接抽出し、最大3つまでとしてください。 レビュー: この製品は期待以上でした!バッテリーの持ちが良く、操作も非常にスムーズです。デザインも気に入りました。 出力:
2. Few-shotプロンプト
少数の入出力例をプロンプト内に含めることで、モデルにタスクのパターンを学習させ、性能を向上させる手法です[1]。
あなたは熟練した感情分析アシスタントです。
以下の指示に従ってレビューテキストを分析し、感情とその理由、分析の自信度をJSON形式で出力してください。
感情の理由はレビューから直接抽出し、最大3つまでとしてください。
---
レビュー:
この製品は期待以上でした!バッテリーの持ちが良く、操作も非常にスムーズです。デザインも気に入りました。
出力:
{
"sentiment": "ポジティブ",
"reasons": ["バッテリーの持ちが良い", "操作がスムーズ", "デザインが良い"],
"confidence": "高"
}
---
レビュー:
購入しましたが、すぐに故障しました。サポートに連絡しても返事が遅く、非常に不満です。二度と買いません。
出力:
{
"sentiment": "ネガティブ",
"reasons": ["すぐに故障した", "サポートの返事が遅い"],
"confidence": "高"
}
---
レビュー:
音質はまあまあですが、接続が不安定な時があります。値段を考えると悪くはないと思います。
出力:
{
"sentiment": "中立",
"reasons": ["音質はまあまあ", "接続が不安定な時がある", "値段を考えると悪くない"],
"confidence": "中"
}
---
レビュー:
このノートPCは非常に軽くて持ち運びやすいですが、画面が小さくて作業しづらいのが難点です。
出力:
3. Chain-of-Thought (CoT) 制約型プロンプト
思考のステップを明示的にプロンプトに含めることで、モデルに論理的な推論を促し、複雑なタスクの精度を高める手法です[2]。ここでは、思考プロセスも出力させることで、デバッグや透明性を確保します。
あなたは熟練した感情分析アシスタントです。
以下のレビューテキストを分析し、感情(ポジティブ、ネガティブ、中立)とその理由、そして分析の自信度をJSON形式で出力してください。
感情の理由はレビューから直接抽出し、最大3つまでとしてください。
まず、感情分析の思考プロセスを段階的に記述してください。その後、最終的な分析結果をJSON形式で出力してください。
---
レビュー:
このスマホのカメラは素晴らしいですが、バッテリーの消耗が速いのが残念です。
思考プロセス:
1. 感情を示すキーワードやフレーズの特定: 「カメラは素晴らしい」(ポジティブ)、「バッテリーの消耗が速いのが残念」(ネガティブ)。
2. 全体的な感情の判断: ポジティブとネガティブの両方が混在しているため、中立と判断するのが適切。
3. 感情の理由の抽出: レビューから直接「カメラが素晴らしい」と「バッテリーの消耗が速い」を抽出。
4. 分析の自信度の決定: ポジティブとネガティブな要素が明確に記述されており、判断に迷いがないため自信度は高。
5. JSON形式での出力。
出力:
{
"sentiment": "中立",
"reasons": ["カメラが素晴らしい", "バッテリーの消耗が速い"],
"confidence": "高"
}
---
レビュー:
この新しいイヤホンは音質は良いものの、装着感が悪く耳が痛くなります。
思考プロセス:
評価
LLMの評価には、正例、難例、コーナーケースを組み合わせた評価データセットが不可欠です[4]。
評価シナリオ
正例 (Happy Path):
明確なポジティブレビュー: 「最高の製品!使いやすくて感動しました。」
明確なネガティブレビュー: 「期待外れ。すぐに壊れてしまい、がっかりです。」
明確な中立レビュー: 「特に良くも悪くもない。普通です。」
難例 (Edge Cases):
複合感情: 「デザインは素晴らしいですが、性能は期待以下でした。」
皮肉表現: 「まさかこんなに早く壊れるとは、驚きですね(皮肉)。」
情報不足: 「うーん、微妙。」
長いレビュー: 複数の話題が含まれる長文。
コーナーケース (Adversarial Cases):
レビューではない入力: 「今週の特売品!」(広告文)
不適切な内容: 暴力的な表現や個人情報を含むもの。
自動評価の擬似コード
Pythonを用いた自動評価の擬似コードと採点ルーブリックを示します。
import json
import re
def evaluate_llm_output(review_text: str, llm_output: str, golden_standard: dict) -> dict:
score = 0
errors = []
# 1. JSON形式のチェック (10点)
try:
parsed_output = json.loads(llm_output.split('出力:\n')[-1].strip()) # CoT考慮
score += 10
except json.JSONDecodeError:
errors.append("JSON形式が無効です。")
return {"score": score, "errors": errors, "parsed_output": None}
# 2. sentimentフィールドの検証 (30点)
if "sentiment" not in parsed_output:
errors.append("sentimentフィールドがありません。")
elif parsed_output["sentiment"] == golden_standard["sentiment"]:
score += 30
else:
errors.append(f"感情が不一致です。期待値: {golden_standard['sentiment']}, 実際: {parsed_output['sentiment']}")
# 3. reasonsフィールドの検証 (最大30点 + 理由数5点 = 35点)
if "reasons" not in parsed_output or not isinstance(parsed_output["reasons"], list):
errors.append("reasonsフィールドが無効です。")
else:
# 理由の数チェック (5点)
if 1 <= len(parsed_output["reasons"]) <= 3:
score += 5
else:
errors.append(f"理由の数が範囲外です。実際: {len(parsed_output['reasons'])}")
# 各理由がレビューテキストに含まれるか、ゴールデンに含まれるか (各10点)
correct_reasons_count = 0
for reason in parsed_output["reasons"]:
if reason in golden_standard["reasons"] and reason in review_text: # レビューからの直接抽出も確認
correct_reasons_count += 1
else:
errors.append(f"不正な理由またはレビューにない理由: '{reason}'")
score += min(correct_reasons_count * 10, 30) # 最大30点
# 4. confidenceフィールドの検証 (5点)
valid_confidence = ["高", "中", "低"]
if "confidence" not in parsed_output:
errors.append("confidenceフィールドがありません。")
elif parsed_output["confidence"] in valid_confidence:
score += 5
else:
errors.append(f"自信度が不正です。期待値: {valid_confidence}, 実際: {parsed_output['confidence']}")
# 5. 幻覚(レビューにない情報)の簡易チェック (減点)
# これはより高度なNLIモデルや人間による評価が必要だが、簡易的にreasonsがレビューに含まれるかなどで対応
# 上記reasonsチェックで部分的に対応済み。
return {"score": score, "errors": errors, "parsed_output": parsed_output}
# 採点ルーブリック:
# - JSON形式の正確さ: +10点
# - sentimentの正解度: +30点
# - reasonsの数(1-3個): +5点
# - reasonsの各項目が正しく抽出され、かつ元レビュー内に存在するか: 各+10点(最大30点)
# - confidenceの妥当性: +5点
# 合計: 80点 (簡易評価のため)
# CoTの場合、思考プロセスが論理的かどうかの評価も追加可能だが、自動化は困難なため今回は省略
プロンプト評価と改良のループ
プロンプトは一度作成して終わりではなく、継続的な評価と改良が必要です。
graph TD
PROMPT["プロンプト設計"] --> MODEL{"モデル実行"};
MODEL --> OUTPUT["モデル出力"];
OUTPUT --> EVAL["評価ツール"];
EVAL --|合格|--> DEPLOY["完了/デプロイ"];
EVAL --|不合格|--> ERROR["誤り分析"];
ERROR --> PROMPT;
誤り分析と抑制手法
LLMの出力には様々な失敗モードがあり、それぞれに応じた抑制手法を講じる必要があります[5]。
| 失敗モード | 説明 | 抑制手法 |
|---|---|---|
| 幻覚 (Hallucination) | レビューに存在しない理由や情報を生成する。 | プロンプトで「レビューから直接抽出する」ことを強調。評価フェーズで、抽出された理由が元のレビューに含まれるか検証する。 |
| 様式崩れ (Format Deviation) | 指定されたJSON形式以外で出力する。 | プロンプトに明確なJSONスキーマとFew-shot例を含める。出力後のJSONパース検証を行い、無効な場合は再試行戦略を導入する。 |
| 脱線 (Off-topic/Irrelevant) | 感情分析とは無関係な内容や、余計な説明を生成する。 | system指示でモデルの役割を「熟練した感情分析アシスタント」と明確に定義し、タスクの範囲を厳しく指定する。 |
| 禁止事項違反 | モデルが「AIである」と自身に言及するなど。 | system指示で「自身の存在に言及しない」など明確な制約を設ける。後処理でキーワードフィルタリングを行う。 |
| 一貫性の欠如 | 同じ入力に対して異なる出力を生成する。 | モデルのtemperatureパラメータを低く設定し、決定論的な出力を促す。Few-shot例を豊富にする。 |
改良と再評価
誤り分析の結果に基づき、以下の点に注目してプロンプトの改良を行います。
System指示の強化: モデルの役割、制約、出力形式に関する指示をより具体的に、かつ厳しく定義します。
Few-shot例の最適化: 誤りが多いケース(複合感情、皮肉など)に対応するFew-shot例を追加または修正します。
CoT導入の検討: 特に複雑な推論が必要なタスクの場合、CoTプロンプトを導入し、モデルに思考プロセスを明示させることで、精度向上とデバッグの容易化を図ります。
出力後処理の強化: 正規表現や特定の関数を用いて、モデルの出力が契約を遵守しているかを厳密に検証し、必要に応じて修正やリトライを行います。
改良後、拡張された評価データセット(特に以前失敗した難例やコーナーケース)を用いて、再度自動評価と人手評価を実施し、プロンプトの有効性を確認します。
まとめ
Few-shotとZero-shotプロンプティングは、LLMの性能を引き出すための重要な技術です。Zero-shotは簡潔なプロンプトで汎用的なタスクに適し、Few-shotは具体例を通じてモデルの理解を深めます。さらにChain-of-Thoughtは、複雑な推論を必要とするタスクにおいて、モデルに思考プロセスを明示させることで精度を向上させます。
これらのプロンプト設計は、明確な入出力契約の設定から始まり、厳格な自動評価を通じてその効果を測定し、幻覚や様式崩れといった失敗モードを分析することで継続的に改良されるべきです[3]。この「設計→実行→評価→改良」の反復サイクルを通じて、LLMアプリケーションの信頼性と性能を最大限に高めることが可能になります。
[1] Tom B. Brown et al. (OpenAI). “Language Models are Few-Shot Learners”. arXiv, 2020年5月28日. https://arxiv.org/abs/2005.14165 [2] Jason Wei et al. (Google Research). “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models”. arXiv, 2022年1月28日. https://arxiv.org/abs/2201.11903 [3] Google for Developers. “プロンプト設計の紹介”. 最終更新日: 2024年4月11日. https://developers.google.com/machine-learning/practitioner/prompt-design/prompt-design [4] Hugging Face. “Evaluate”. 最終更新日: 2024年7月19日. https://huggingface.co/docs/evaluate/index [5] Nils Swart (AssemblyAI). “Common Failure Modes of Large Language Models”. AssemblyAI Blog, 2023年10月25日. https://www.assemblyai.com/blog/common-failure-modes-of-large-language-models/

