Few-shotとZero-shotプロンプティングの設計と評価

Tech

本記事は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例を豊富にする。

改良と再評価

誤り分析の結果に基づき、以下の点に注目してプロンプトの改良を行います。

  1. System指示の強化: モデルの役割、制約、出力形式に関する指示をより具体的に、かつ厳しく定義します。

  2. Few-shot例の最適化: 誤りが多いケース(複合感情、皮肉など)に対応するFew-shot例を追加または修正します。

  3. CoT導入の検討: 特に複雑な推論が必要なタスクの場合、CoTプロンプトを導入し、モデルに思考プロセスを明示させることで、精度向上とデバッグの容易化を図ります。

  4. 出力後処理の強化: 正規表現や特定の関数を用いて、モデルの出力が契約を遵守しているかを厳密に検証し、必要に応じて修正やリトライを行います。

改良後、拡張された評価データセット(特に以前失敗した難例やコーナーケース)を用いて、再度自動評価と人手評価を実施し、プロンプトの有効性を確認します。

まとめ

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/

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

コメント

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