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