本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
LLM失敗モード抑制のためのプロンプト設計と評価技術
LLMの失敗モード抑制には、プロンプト設計と評価の体系化が不可欠であり、本記事では具体的な手法について詳述します。
ユースケース定義
企業のプレスリリースから、製品名、発表日、主要な変更点、影響範囲の4項目を正確に抽出し、構造化されたJSON形式で出力するタスクを対象とします。このタスクは情報の正確性と出力フォーマットの厳守が求められます。
制約付き仕様化
本タスクにおける入出力契約、失敗時の挙動、および禁止事項は以下の通りです。
- 入力契約:
- 形式: 自然言語テキスト(企業のプレスリリースまたはそれに準ずる情報公開文)。
- 内容: 製品に関する発表情報が含まれること。
- 出力契約:
- 形式: 厳密なJSON形式。
- スキーマ: 以下のキーとデータ型を持つこと。
product_name: 文字列 (string)release_date:YYYY-MM-DD形式の文字列 (string)key_changes: 箇条書き形式(各項目がハイフンで始まる)の文字列 (string)impact_scope: 以下のいずれかの文字列 (“全顧客”, “一部顧客”, “社内のみ”)
- 例:
{"product_name": "新製品X", "release_date": "2023-10-26", "key_changes": "- 性能向上\n- 新機能追加", "impact_scope": "全顧客"}
- 失敗時の挙動:
- 必要な情報が抽出できなかった場合やJSONパースエラーが発生した場合は、以下のJSON形式でエラー情報を出力します。
{"error_code": "EXTRACTION_FAILURE", "message": "Required information not found or invalid format."}
- 必要な情報が抽出できなかった場合やJSONパースエラーが発生した場合は、以下のJSON形式でエラー情報を出力します。
- 禁止事項:
- 元のプレスリリースにない情報の幻覚(捏造)。
- JSON形式以外の出力、または指定スキーマからの逸脱。
impact_scopeにおいて、定義された3つの選択肢以外の値の生成。- タスクとは無関係な会話や説明の付加。
プロンプト設計
要求される精度と柔軟性に応じて、以下の3種類のプロンプトを検討します。
1. ゼロショットプロンプト
あなたはプレスリリースから情報を抽出するAIアシスタントです。
以下のプレスリリースから、製品名、発表日(YYYY-MM-DD形式)、主要な変更点(箇条書き)、影響範囲("全顧客", "一部顧客", "社内のみ"のいずれか)を抽出し、JSON形式で出力してください。
プレスリリース:
{{PRESS_RELEASE_TEXT}}
2. 少数例プロンプト (Few-shot Prompt)
あなたはプレスリリースから情報を抽出し、JSON形式で出力するAIアシスタントです。
以下に例を示します。
---
入力:
株式会社ABCは、2023年10月15日に「次世代クラウドサービスα」を発表しました。このサービスは既存のクラウドサービスの性能を20%向上させ、セキュリティ機能も強化します。対象は全顧客です。
出力:
{"product_name": "次世代クラウドサービスα", "release_date": "2023-10-15", "key_changes": "- 性能20%向上\n- セキュリティ機能強化", "impact_scope": "全顧客"}
---
入力:
XYZ社は、2024年1月10日に「開発ツールPro」のアップデートをリリースしました。主な変更点は新しいUIデザインとバグ修正です。この変更は一部顧客のみに影響します。
出力:
{"product_name": "開発ツールPro", "release_date": "2024-01-10", "key_changes": "- 新しいUIデザイン\n- バグ修正", "impact_scope": "一部顧客"}
---
上記例を参考に、以下のプレスリリースから情報を抽出し、JSON形式で出力してください。
プレスリリース:
{{PRESS_RELEASE_TEXT}}
3. Chain-of-Thought (CoT) 制約型プロンプト
System:
あなたはプレスリリースから情報を抽出し、JSON形式で出力するAIアシスタントです。
以下の手順を厳守し、出力形式に厳格に従ってください。
1. まず、プレスリリースから「製品名」を正確に特定します。
2. 次に、「発表日」を特定し、必ず「YYYY-MM-DD」形式に変換します。
3. 続けて、「主要な変更点」を特定し、簡潔な箇条書き(各項目をハイフンで始める)として整理します。
4. 最後に、「影響範囲」を特定し、厳密に「全顧客」「一部顧客」「社内のみ」のいずれかを選択します。
5. これらの情報を集約し、指定されたJSONスキーマに沿って出力します。元の情報にない内容を推測したり、余計な説明を追加したりしないでください。
User:
以下のプレスリリースから情報を抽出し、JSON形式で出力してください。
プレスリリース:
{{PRESS_RELEASE_TEXT}}
評価
LLMの出力を評価するためのシナリオと自動評価の擬似コードを示します。
評価シナリオ
- 正例: 明確な製品名、日付、変更点、影響範囲が全て明記された標準的なプレスリリース。
- 難例:
- 発表日がテキスト中に複数箇所にある、または曖昧な表現(例: 「来月発表」)。
- 複数の製品情報が混在している。
- 影響範囲が直接的に書かれておらず、文脈から推測する必要がある。
- 変更点が箇条書きではないテキストで記述されている。
- コーナーケース:
- 入力がプレスリリースではない、無関係なテキスト。
- 情報が完全に欠落しており、抽出不可能なテキスト。
- JSON形式が不正な出力(パースエラー)。
自動評価の擬似コード
Pythonを想定した自動評価関数の擬似コードです。
import json
import re
def evaluate_llm_output(llm_output: str, expected_product_name: str = None) -> dict:
score = 0
feedback = []
# 1. JSONパースチェック (10点)
try:
data = json.loads(llm_output)
score += 10
feedback.append("JSON形式は正しいです。")
except json.JSONDecodeError:
feedback.append("エラー: JSON形式が不正です。")
# 失敗時の挙動チェック
if '"error_code": "EXTRACTION_FAILURE"' in llm_output:
score += 5 # エラー報告が正しい形式なら加点
feedback.append("エラーコードの報告形式は正しいです。")
return {"score": score, "feedback": feedback, "parsed_output": None}
# 2. 必須キーの存在チェック (各5点)
required_keys = ["product_name", "release_date", "key_changes", "impact_scope"]
missing_keys = [key for key in required_keys if key not in data]
if not missing_keys:
score += 20
feedback.append("全ての必須キーが存在します。")
else:
feedback.append(f"エラー: 以下の必須キーが不足しています: {', '.join(missing_keys)}")
# 3. release_dateフォーマットチェック (10点)
release_date_pattern = r"^\d{4}-\d{2}-\d{2}$"
if "release_date" in data and re.match(release_date_pattern, data["release_date"]):
score += 10
feedback.append("release_dateのフォーマットは正しいです。")
else:
feedback.append("エラー: release_dateのフォーマットが不正です。")
# 4. impact_scope値チェック (10点)
valid_impact_scopes = ["全顧客", "一部顧客", "社内のみ"]
if "impact_scope" in data and data["impact_scope"] in valid_impact_scopes:
score += 10
feedback.append("impact_scopeの値は正しいです。")
else:
feedback.append(f"エラー: impact_scopeの値が不正です。許容値: {valid_impact_scopes}")
# 5. key_changes形式チェック (5点, 簡易)
if "key_changes" in data and isinstance(data["key_changes"], str) and data["key_changes"].startswith("-"):
score += 5
feedback.append("key_changesは箇条書き形式のようです。")
elif "key_changes" in data and not isinstance(data["key_changes"], str):
feedback.append("エラー: key_changesは文字列ではありません。")
else:
feedback.append("注意: key_changesが期待される箇条書き形式ではない可能性があります。")
# 6. 正確性チェック(簡易、期待値がある場合) (30点)
if expected_product_name and "product_name" in data and data["product_name"] == expected_product_name:
score += 30
feedback.append("product_nameは期待値と一致します。")
elif expected_product_name:
feedback.append(f"エラー: product_nameが期待値と異なります。期待: '{expected_product_name}', 実際: '{data.get('product_name')}'")
else:
feedback.append("注意: product_nameの正確性チェックはスキップされました(期待値未指定)。")
return {"score": score, "feedback": feedback, "parsed_output": data}
# 採点ルーブリック例:
# 1. JSONパース: 10点 (エラーコード報告で+5点)
# 2. 必須キー: 20点 (各5点)
# 3. release_dateフォーマット: 10点
# 4. impact_scope値: 10点
# 5. key_changes形式: 5点 (簡易)
# 6. product_name正確性: 30点 (期待値との比較)
# 合計: 85点 (+5点で最大90点、さらに他のキーの正確性も加味すれば100点に調整可能)
誤り分析と抑制手法
LLMで発生しうる主要な失敗モードと、その抑制手法を以下に列挙します。
- 幻覚(Halucination):
- 失敗モード: 元のテキストに存在しない情報を生成する。
- 抑制手法:
system指示で「提示された情報のみを使用し、推測や想像を加えないこと」を明記。CoTプロンプトで情報源を特定するステップを設ける。評価段階で抽出情報と原文との整合性検証を導入。
- 様式崩れ(Format Deviation):
- 失敗モード: JSON形式が不正、
release_dateのフォーマットが不一致、impact_scopeが指定外の値になる。 - 抑制手法:
system指示で「出力は厳密にJSON形式であり、各キーのフォーマット(特に日付と選択肢)を厳守すること」を明記。Few-shotプロンプトで正しい形式の例を複数提示。評価段階でJSONパース、正規表現、セット包含チェックを徹底。不正な形式の場合、エラーメッセージを付与してリトライを促す戦略を適用。
- 失敗モード: JSON形式が不正、
- 脱線(Task Off-topic):
- 失敗モード: タスクと無関係な説明や追加のコメントを付加する。
- 抑制手法:
system指示で「タスクに厳密に従い、JSON形式以外の情報は一切含めないこと」を強調。出力検証ステップで余分なテキストを除去または検出。
- 情報抽出漏れ(Information Omission):
- 失敗モード: プレスリリース内の必須情報を抽出できない。
- 抑制手法: CoTプロンプトで各情報の抽出ステップを明確に指示。評価段階で必須キーの存在チェックを厳格に行い、抽出漏れを特定。
改良
誤り分析の結果に基づき、以下のサイクルでプロンプトと評価基準を改良します。
- プロンプト調整: 特定の失敗モードが多く発生した場合、その失敗モードを抑制するための指示を追加・修正します。例えば、幻覚が多い場合は制約を強化し、様式崩れが多い場合はFew-shot例を増やしたり、フォーマット定義をより厳格に記述します。CoTステップの具体性を高めることも有効です。
- 評価基準の精緻化: 評価シナリオに難例やコーナーケースを追加し、自動評価のルーブリックを細分化します。特に正確性の評価において、キーごとの期待値を定義し、より詳細な採点を行うことで、改良の方向性を明確にします。
- データセット拡充: 多様なプレスリリース(正例、難例、コーナーケース)を含む評価データセットを継続的に拡充し、プロンプトのロバスト性を検証します。
再評価
改良されたプロンプトと評価基準を用いて、新たな評価データセットに対して再評価を実施します。これにより、改良の効果を定量的に測定し、さらなる改善点を発見します。このプロセスを繰り返すことで、LLMの出力品質を段階的に向上させます。
まとめ
LLMの失敗モード抑制には、明確な入出力契約の定義、多様なプロンプト設計、厳格な自動評価、そして継続的な誤り分析と改良のループが不可欠です。これらのプロセスを体系的に実行することで、LLMの信頼性と実用性を高めることが可能です。
graph TD
A["要求定義"] --> B{"ユースケース定義"};
B --> C["制約付き仕様化"];
C --> D["プロンプト設計"];
D --> E["プロンプト案生成"];
E --> F["モデル推論"];
F --> G["出力取得"];
G --> H["評価シナリオ準備"];
H --> I["自動評価実行"];
I --> J{"評価結果分析"};
J -->|"成功"| K["デプロイ"]
J -->|"失敗モード特定"| L["誤り分析"]
L --> M["改良計画"];
M --> D;
I -->|"評価データ不足"| H
F -->|"リトライ"| E

