<p><!--META
{
"title": "LLMの自己修正プロンプト設計と評価",
"primary_category": "AI/機械学習",
"secondary_categories": ["プロンプトエンジニアリング", "LLM開発"],
"tags": ["LLM", "自己修正", "プロンプト", "Gemini", "Chain-of-Thought", "評価"],
"summary": "LLMの自己修正プロンプトの設計、評価、改良プロセスを解説。入出力契約、複数プロンプト案、自動評価、Mermaid図、失敗モードと抑制策を網羅。",
"mermaid": true,
"verify_level": "L0",
"tweet_hint": {"text":"LLMの自己修正プロンプト設計と評価について深掘り。ゼロショットからCoTまで複数のプロンプト案、自動評価の擬似コード、Mermaid図によるプロセス可視化を解説。失敗モードと抑制策も網羅。
#LLM #プロンプトエンジニアリング","hashtags":["#LLM","#プロンプトエンジニアリング"]},
"link_hints": ["https://arxiv.org/abs/2401.00287", "https://arxiv.org/abs/2303.17651", "https://developers.google.com/gemini/docs/prompt-engineering/overview"]
}
-->
本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">LLMの自己修正プロンプト設計と評価</h1>
<p>大規模言語モデル(LLM)は多様なタスクで高い性能を発揮しますが、複雑な推論や厳密な出力フォーマットが求められる場面では、不正確な情報(幻覚)や一貫性の欠如、様式崩れなどの課題を抱えることがあります。LLMの自己修正プロンプトは、モデルが自身の出力を評価し、修正する能力を引き出すことで、これらの課題を克服し、信頼性と堅牢性を向上させる手法です。本記事では、LLMの自己修正プロンプトの設計、評価、改良プロセスについて詳細に解説します。</p>
<h2 class="wp-block-heading">ユースケース定義</h2>
<p>自己修正プロンプトは、特に以下のユースケースで効果を発揮します。</p>
<ul class="wp-block-list">
<li><p><strong>複雑な多段階推論タスク</strong>: 長文要約、複雑なコード生成、多ステップの意思決定支援など、複数の推論ステップを要するタスク。</p></li>
<li><p><strong>事実誤認、一貫性欠如のリスクが高いタスク</strong>: 法律文書の分析、医療情報の生成、データに基づくレポート作成など、正確性と一貫性が極めて重要なタスク。</p></li>
<li><p><strong>特定の出力フォーマット厳守が必要なタスク</strong>: JSON/XML形式のデータ抽出、特定のスキーマに基づくAPIリクエスト生成、Markdown形式のドキュメント生成など。</p></li>
</ul>
<h2 class="wp-block-heading">制約付き仕様化(入出力契約)</h2>
<p>自己修正プロンプトを効果的に適用するためには、LLMとの入出力契約を明確に定義することが不可欠です。</p>
<ul class="wp-block-list">
<li><p><strong>入力</strong>:</p>
<ul>
<li><p><strong>形式</strong>: <code>JSON</code> または <code>text</code> 形式のユーザープロンプトと関連データ。</p></li>
<li><p><strong>内容</strong>: 実行したいタスク、目的、出力形式の要件、参照データを含める。</p></li>
</ul></li>
<li><p><strong>出力</strong>:</p>
<ul>
<li><p><strong>形式</strong>: <code>JSON</code> または <code>text</code> 形式の最終回答。特定のスキーマやフォーマットを厳守。</p></li>
<li><p><strong>内容</strong>: ユーザーの要求に対する正確かつ一貫性のある回答。修正プロセスを経た最終結果。</p></li>
</ul></li>
<li><p><strong>失敗時の挙動</strong>:</p>
<ul>
<li><p>最大 <code>N</code> 回(例: 3回)の修正試行後も要件を満たさない場合、エラーメッセージと、可能であれば部分的な結果を返します。</p></li>
<li><p>エラーメッセージには、どの制約を満たせなかったかを示す情報を含めるべきです。</p></li>
</ul></li>
<li><p><strong>禁止事項</strong>:</p>
<ul>
<li><p><strong>幻覚(Halucination)</strong>: 事実に基づかない情報の生成。</p></li>
<li><p><strong>不適切な内容</strong>: 倫理的に問題のある内容や、ハルシネーション。</p></li>
<li><p><strong>様式崩れ</strong>: 指定された出力フォーマット(例: JSONスキーマ)からの逸脱。</p></li>
<li><p><strong>脱線</strong>: 指示されたタスクスコープからの逸脱。</p></li>
</ul></li>
</ul>
<h2 class="wp-block-heading">プロンプト設計</h2>
<p>自己修正を促すためのプロンプトは、その設計によってモデルのパフォーマンスが大きく変動します。ここでは、代表的な3種類のプロンプト設計を紹介します。</p>
<h3 class="wp-block-heading">1. ゼロショット自己修正</h3>
<p>モデルに初回出力後、追加の指示で自身の出力を批評させ、修正を促す手法です。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">あなたは専門家です。以下のタスクを実行してください。
---
タスク: ユーザーが提供した情報を元に、特定のイベントに関するニュース記事の見出しと要約を生成してください。見出しは20文字以内、要約は100文字以内とし、簡潔かつ魅力的に記述してください。
入力情報:
イベント名: AI技術の進化と未来
日付: 2024年7月25日
場所: 東京ビッグサイト
主要トピック: 最新LLMモデルの発表、倫理的AIの議論、ロボティクスの未来
参加者: 5000人
---
あなたの最初の出力:
[LLMの初回出力]
---
上記の出力について、以下の基準で自己評価し、改善点があれば修正してください。
1. 見出しは20文字以内か?
2. 要約は100文字以内か?
3. 内容は入力情報に基づいているか?(幻覚は無いか?)
4. 簡潔かつ魅力的か?
自己評価と修正案:
</pre>
</div>
<h3 class="wp-block-heading">2. 少数例(Few-shot)自己修正</h3>
<p>正しい自己修正の例を複数提示し、モデルに自己批評と修正のパターンを学ばせる手法です。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">あなたは専門家です。以下のタスクを実行してください。
---
タスク: ユーザーが提供した顧客レビューに基づき、製品のポジティブな点とネガティブな点をJSON形式で抽出してください。
JSONスキーマ:
{
"product_name": "string",
"positive_aspects": ["string"],
"negative_aspects": ["string"]
}
---
例1:
入力レビュー: 「このスピーカーは音質が素晴らしいが、バッテリーの持ちが悪い。」
初回出力:
```json
{
"product_name": "スピーカー",
"positive_aspects": ["音質が良い"],
"negative_aspects": ["バッテリー"]
}
</pre>
</div>
<p>自己評価と修正案:
バッテリーの「持ちが悪い」という具体的な表現を「バッテリーの持ちが悪い」に修正し、より詳細にしました。
修正後の出力:</p>
<div class="codehilite">
<pre data-enlighter-language="generic">{
"product_name": "スピーカー",
"positive_aspects": ["音質が素晴らしい"],
"negative_aspects": ["バッテリーの持ちが悪い"]
}
</pre>
</div><hr/>
<p>例2:
入力レビュー: 「このコーヒーメーカーは使いやすいけど、少し高いね。」
初回出力:</p>
<div class="codehilite">
<pre data-enlighter-language="generic">{
"product_name": "コーヒーメーカー",
"positive_aspects": ["使いやすい"],
"negative_aspects": ["価格が高い"]
}
</pre>
</div>
<p>自己評価と修正案:
特になし。スキーマと内容に問題ありません。
修正後の出力:</p>
<div class="codehilite">
<pre data-enlighter-language="generic">{
"product_name": "コーヒーメーカー",
"positive_aspects": ["使いやすい"],
"negative_aspects": ["価格が高い"]
}
</pre>
</div><hr/>
<p>あなたのタスク:
入力レビュー: 「このマウスは軽くて操作しやすいけど、クリック音が大きすぎる。」
初回出力:</p>
<p>[LLMの初回出力]</p>
<hr/>
<p>上記の出力について、上記の例を参考に自己評価し、改善点があれば修正してください。
自己評価と修正案:</p>
<pre data-enlighter-language="generic">
### 3. Chain-of-Thought(CoT)制約型自己修正
推論プロセスと自己評価ステップを明確に構造化し、詳細なフィードバックを与えることで、モデルが論理的に修正を行うように促します。これは、モデルが自身の思考過程を外部化し、ステップバイステップで検証する「Self-Refine」のようなフレームワークに類似しています \[2]。
```text
あなたはステップバイステップで問題を解決し、自身の解答を厳密に検証する論理的な推論エンジンです。以下のタスクを実行してください。
---
タスク: 与えられた数値を昇順にソートし、結果をカンマ区切りの文字列で出力してください。
---
1. 最初の回答を生成してください。
2. 生成された回答の各要素を分析し、タスクの制約(昇順、カンマ区切り)を満たしているか詳細に検証してください。具体的には、以下の点を確認してください。
a. 数値が本当に昇順になっているか?
b. 出力形式がカンマ区切りの文字列になっているか?
c. 元の数値がすべて含まれているか?(欠落や追加がないか?)
3. 検証結果に基づき、問題があればその理由を説明し、修正案を提示してください。
4. 修正案に基づいて最終的な回答を生成してください。
入力数値: [5, 2, 8, 1, 9, 3]
---
ステップ1: 最初の回答を生成します。
[LLMの初回出力]
ステップ2: 生成された回答を検証します。
a. 昇順チェック: ... (検証結果)
b. 形式チェック: ... (検証結果)
c. 欠落/追加チェック: ... (検証結果)
ステップ3: 検証結果に基づく修正案を提示します。
[LLMの自己評価と修正案]
ステップ4: 最終的な回答を生成します。
</pre>
<h2 class="wp-block-heading">評価</h2>
<p>自己修正プロンプトの効果を測定するためには、体系的な評価プロセスが必要です。</p>
<h3 class="wp-block-heading">評価シナリオ</h3>
<ul class="wp-block-list">
<li><p><strong>正例</strong>: 明確な指示に従い、期待される出力が得られるケース。</p>
<ul>
<li>例: 「日本の首都はどこですか? JSON形式で出力してください。」</li>
</ul></li>
<li><p><strong>難例</strong>: 曖昧な指示、複数の解釈が可能なケース、大量のデータ処理、複雑な推論を要するケース。</p>
<ul>
<li>例: 「このビジネスメールのトーンをもっとプロフェッショナルに修正してください。ただし、顧客への共感は維持してください。」</li>
</ul></li>
<li><p><strong>コーナーケース</strong>: 境界値、無効な入力、予期せぬエッジケース。</p>
<ul>
<li>例: 「空のリストをソートしてください。」「不正なJSONスキーマでデータを抽出してください。」</li>
</ul></li>
</ul>
<h3 class="wp-block-heading">自動評価の擬似コード</h3>
<p>自動評価は、一貫性と効率性を提供し、プロンプトの変更による影響を定量的に把握する上で不可欠です。</p>
<div class="codehilite">
<pre data-enlighter-language="generic"># python
def evaluate_self_correction_output(llm_output: str, expected_output: str, task_type: str) -> dict:
"""
LLMの自己修正後の出力を自動評価する擬似コード。
Args:
llm_output (str): LLMから得られた最終出力。
expected_output (str): 期待される正解出力。
task_type (str): タスクの種類 ('json_extraction', 'text_summary', 'sorting'など)。
Returns:
dict: 評価結果(スコア、詳細)。
前提条件:
- `expected_output` は評価基準を満たす形式で事前に準備されている。
- 評価関数はタスクタイプに応じて適切なバリデーションロジックを持つ。
入出力:
- 入力: LLMの出力文字列、期待される出力文字列、タスクタイプ文字列
- 出力: 評価スコアと詳細を含む辞書
計算量:
- JSONパース: O(L) (Lは出力文字列長)
- 正規表現: O(L)
- 文字列比較: O(L)
メモリ条件:
- 主に文字列と辞書オブジェクトのため、出力長に比例。
"""
score = 0
details = []
# 1. 採点ルーブリックに基づく評価
if task_type == 'json_extraction':
try:
import json
parsed_output = json.loads(llm_output)
parsed_expected = json.loads(expected_output)
# スキーマの検証
if isinstance(parsed_output, dict) and all(k in parsed_output for k in parsed_expected):
score += 30 # スキーマ準拠
details.append("JSONスキーマに準拠しています。")
else:
details.append("JSONスキーマに準拠していません。")
# 内容の正確性(簡易チェック)
if parsed_output == parsed_expected: # 厳密な比較
score += 50
details.append("内容が期待値と完全に一致します。")
else:
# 詳細な比較ロジックを追加可能
details.append("内容が期待値と一部異なります。")
except json.JSONDecodeError:
details.append("JSON形式が無効です。")
elif task_type == 'text_summary':
# 2. 正規表現とキーワードに基づく評価
if len(llm_output) <= 100: # 文字数制限チェック
score += 20
details.append("文字数制限を満たしています。")
else:
details.append(f"文字数制限を超過しています ({len(llm_output)}文字)。")
if any(keyword in llm_output for keyword in ["AI", "LLM", "未来"]): # キーワード含有チェック
score += 30
details.append("主要キーワードが含まれています。")
else:
details.append("主要キーワードが不足しています。")
# 3. 関数評価(例: 外部APIで事実確認を行うなど)
# 例えば、外部のNLPサービスを使って要約の質を評価する
# from external_nlp_service import evaluate_summary_quality
# quality_score = evaluate_summary_quality(llm_output, expected_output)
# score += quality_score * 0.5 # 50点満点
# 簡易的な内容一致度
if expected_output in llm_output: # 非常に簡易的な確認
score += 50
details.append("期待される要点が要約に含まれています。")
else:
details.append("期待される要点が不足しています。")
elif task_type == 'sorting':
try:
llm_list = list(map(int, llm_output.split(',')))
expected_list = list(map(int, expected_output.split(',')))
if llm_list == expected_list:
score += 100
details.append("ソート結果が期待値と完全に一致します。")
else:
details.append("ソート結果が期待値と異なります。")
if not all(llm_list[i] <= llm_list[i+1] for i in range(len(llm_list)-1)):
details.append("結果が昇順ではありません。")
except ValueError:
details.append("出力が数値のカンマ区切り形式ではありません。")
# その他の共通評価項目
if "幻覚" not in llm_output and "不適切" not in llm_output: # 簡易的なネガティブチェック
score += 10 # 禁止事項に抵触しないことのボーナス
details.append("禁止事項に抵触していません。")
return {"total_score": min(score, 100), "details": details}
# 使用例
# output_json = '{"product_name": "スピーカー", "positive_aspects": ["音質が素晴らしい"], "negative_aspects": ["バッテリーの持ちが悪い"]}'
# expected_json = '{"product_name": "スピーカー", "positive_aspects": ["音質が素晴らしい"], "negative_aspects": ["バッテリーの持ちが悪い"]}'
# print(evaluate_self_correction_output(output_json, expected_json, 'json_extraction'))
# output_summary = 'AI技術の進化と未来に関する発表。最新LLMモデル、倫理的AI、ロボティクスが焦点。'
# expected_summary = 'AIの進化と未来に焦点を当てたイベント。最新LLM、倫理的AI、ロボティクスの未来が議論された。'
# print(evaluate_self_correction_output(output_summary, expected_summary, 'text_summary'))
# output_sorted = '1,2,3,5,8,9'
# expected_sorted = '1,2,3,5,8,9'
# print(evaluate_self_correction_output(output_sorted, expected_sorted, 'sorting'))
</pre>
</div>
<h2 class="wp-block-heading">プロンプト→モデル→評価→改良のループ</h2>
<p>自己修正プロンプトの設計と評価は、継続的なフィードバックループを通じて行われます。</p>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
subgraph プロンプト開発ループ
Prompt["プロンプト生成"] --> LLM["LLM実行"]
LLM --> Output["初回出力"]
Output --> Feedback["自己修正フィードバック生成"]
Feedback --> RefinedPrompt["修正プロンプト"]
RefinedPrompt --> RefinedLLM["LLM再実行"]
RefinedLLM --> FinalOutput["最終出力"]
end
FinalOutput --> Evaluator["評価モジュール"]
Evaluator --> Analysis["誤り分析"]
Analysis --> Improvement["プロンプト改良"]
Improvement --> Prompt
</pre></div>
<h2 class="wp-block-heading">誤り分析と抑制手法</h2>
<p>失敗モードを理解し、適切な抑制手法を講じることで、自己修正プロンプトのロバスト性を高めます。</p>
<ul class="wp-block-list">
<li><p><strong>幻覚(Halucination)</strong>:</p>
<ul>
<li><p><strong>分析</strong>: モデルが事実に基づかない情報を生成する。</p></li>
<li><p><strong>抑制手法</strong>:</p>
<ul>
<li><p><strong>System指示</strong>: 事実に基づいた情報のみを生成するよう厳しく指示する。</p></li>
<li><p><strong>検証ステップ</strong>: 外部ツール(検索API、データベース)で生成内容を検証するステップをプロンプトに組み込む。</p></li>
<li><p><strong>リトライ戦略</strong>: 検証で事実誤認が検出された場合、情報源を再確認し、再生成を促す。</p></li>
</ul></li>
</ul></li>
<li><p><strong>様式崩れ(Format Deviation)</strong>:</p>
<ul>
<li><p><strong>分析</strong>: 指定されたJSONやMarkdownなどの出力フォーマットから逸脱する。</p></li>
<li><p><strong>抑制手法</strong>:</p>
<ul>
<li><p><strong>System指示</strong>: フォーマットの厳守を強調し、具体的なスキーマや例を提示する。</p></li>
<li><p><strong>検証ステップ</strong>: 出力後に正規表現やJSONスキーマバリデーターで自動検証を行う。</p></li>
<li><p><strong>リトライ戦略</strong>: バリデーションエラーが発生した場合、エラー内容を具体的に伝え、フォーマットを修正して再生成させる。</p></li>
</ul></li>
</ul></li>
<li><p><strong>脱線(Topic Drift)</strong>:</p>
<ul>
<li><p><strong>分析</strong>: 指示されたタスクスコープ外の情報を生成する、あるいは本来の目的から逸脱する。</p></li>
<li><p><strong>抑制手法</strong>:</p>
<ul>
<li><p><strong>System指示</strong>: タスクの目的と範囲を明確に定義し、不要な情報の生成を禁止する。</p></li>
<li><p><strong>検証ステップ</strong>: 生成内容がタスクの主要キーワードや目的に合致するかをチェックする。</p></li>
<li><p><strong>プロンプト改良</strong>: 具体的な禁止事項(例: 「個人的な意見を含めない」)を明記する。</p></li>
</ul></li>
</ul></li>
<li><p><strong>禁止事項違反(Policy Violation)</strong>:</p>
<ul>
<li><p><strong>分析</strong>: 不適切、有害、倫理的に問題のあるコンテンツを生成する。</p></li>
<li><p><strong>抑制手法</strong>:</p>
<ul>
<li><p><strong>System指示</strong>: 安全性ポリシーや倫理ガイドラインを冒頭で明示し、違反しないよう指示する。</p></li>
<li><p><strong>検証ステップ</strong>: 外部の安全性フィルタリングAPIやキーワードフィルタリングを適用する。</p></li>
<li><p><strong>リトライ戦略</strong>: 違反が検出された場合、内容を修正または生成を中止し、安全な代替案を提示する。</p></li>
</ul></li>
</ul></li>
</ul>
<h2 class="wp-block-heading">改良</h2>
<p>誤り分析の結果に基づき、プロンプト、モデル、または評価プロセスを改良します。</p>
<ul class="wp-block-list">
<li><p><strong>プロンプト改良</strong>:</p>
<ul>
<li><p><strong>指示の具体性向上</strong>: 曖昧な表現を避け、より明確で具体的な指示に修正します。</p></li>
<li><p><strong>制約の強化</strong>: 出力フォーマットや内容に関する制約をさらに厳密にします。</p></li>
<li><p><strong>Few-shot例の追加・修正</strong>: より多様なケースや、自己修正の具体的な手順を示す高品質な例を追加します。</p></li>
</ul></li>
<li><p><strong>モデル選択</strong>:</p>
<ul>
<li>特定のタスクにより適したLLMモデル(例: コード生成に特化したモデル)の検討。</li>
</ul></li>
<li><p><strong>チューニング</strong>:</p>
<ul>
<li>ドメイン固有のデータや自己修正の成功例を用いたファインチューニング。</li>
</ul></li>
</ul>
<h2 class="wp-block-heading">再評価</h2>
<p>改良されたプロンプトやモデルを用いて、再度評価シナリオを実行します。初期の評価結果と比較し、改善度合いを定量的に測定します。特に、難例やコーナーケースにおけるエラー率の低下、特定のメトリクス(例: JSONのパース成功率、要約のROUGEスコア)の向上を指標とします。この反復プロセスにより、自己修正プロンプトの性能は継続的に向上します。</p>
<h2 class="wp-block-heading">まとめ</h2>
<p>LLMの自己修正プロンプトは、モデルの信頼性と出力品質を向上させるための強力な手法です。ゼロショット、Few-shot、Chain-of-Thought制約型といった多様なプロンプト設計を通じて、モデルが自身の出力を批評し、修正する能力を最大限に引き出すことができます。入出力契約の明確化、体系的な評価、そして継続的な誤り分析と改良のループを回すことで、より堅牢で実用的なLLMアプリケーションを構築することが可能となります。2024年1月1日に発表された「Self-Correction in Large Language Models: A Survey」[1] でも様々な自己修正技術が包括的に紹介されており、この分野の重要性が増していることが示唆されています。</p>
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
LLMの自己修正プロンプト設計と評価
大規模言語モデル(LLM)は多様なタスクで高い性能を発揮しますが、複雑な推論や厳密な出力フォーマットが求められる場面では、不正確な情報(幻覚)や一貫性の欠如、様式崩れなどの課題を抱えることがあります。LLMの自己修正プロンプトは、モデルが自身の出力を評価し、修正する能力を引き出すことで、これらの課題を克服し、信頼性と堅牢性を向上させる手法です。本記事では、LLMの自己修正プロンプトの設計、評価、改良プロセスについて詳細に解説します。
ユースケース定義
自己修正プロンプトは、特に以下のユースケースで効果を発揮します。
複雑な多段階推論タスク: 長文要約、複雑なコード生成、多ステップの意思決定支援など、複数の推論ステップを要するタスク。
事実誤認、一貫性欠如のリスクが高いタスク: 法律文書の分析、医療情報の生成、データに基づくレポート作成など、正確性と一貫性が極めて重要なタスク。
特定の出力フォーマット厳守が必要なタスク: JSON/XML形式のデータ抽出、特定のスキーマに基づくAPIリクエスト生成、Markdown形式のドキュメント生成など。
制約付き仕様化(入出力契約)
自己修正プロンプトを効果的に適用するためには、LLMとの入出力契約を明確に定義することが不可欠です。
入力:
出力:
失敗時の挙動:
禁止事項:
幻覚(Halucination): 事実に基づかない情報の生成。
不適切な内容: 倫理的に問題のある内容や、ハルシネーション。
様式崩れ: 指定された出力フォーマット(例: JSONスキーマ)からの逸脱。
脱線: 指示されたタスクスコープからの逸脱。
プロンプト設計
自己修正を促すためのプロンプトは、その設計によってモデルのパフォーマンスが大きく変動します。ここでは、代表的な3種類のプロンプト設計を紹介します。
1. ゼロショット自己修正
モデルに初回出力後、追加の指示で自身の出力を批評させ、修正を促す手法です。
あなたは専門家です。以下のタスクを実行してください。
---
タスク: ユーザーが提供した情報を元に、特定のイベントに関するニュース記事の見出しと要約を生成してください。見出しは20文字以内、要約は100文字以内とし、簡潔かつ魅力的に記述してください。
入力情報:
イベント名: AI技術の進化と未来
日付: 2024年7月25日
場所: 東京ビッグサイト
主要トピック: 最新LLMモデルの発表、倫理的AIの議論、ロボティクスの未来
参加者: 5000人
---
あなたの最初の出力:
[LLMの初回出力]
---
上記の出力について、以下の基準で自己評価し、改善点があれば修正してください。
1. 見出しは20文字以内か?
2. 要約は100文字以内か?
3. 内容は入力情報に基づいているか?(幻覚は無いか?)
4. 簡潔かつ魅力的か?
自己評価と修正案:
2. 少数例(Few-shot)自己修正
正しい自己修正の例を複数提示し、モデルに自己批評と修正のパターンを学ばせる手法です。
あなたは専門家です。以下のタスクを実行してください。
---
タスク: ユーザーが提供した顧客レビューに基づき、製品のポジティブな点とネガティブな点をJSON形式で抽出してください。
JSONスキーマ:
{
"product_name": "string",
"positive_aspects": ["string"],
"negative_aspects": ["string"]
}
---
例1:
入力レビュー: 「このスピーカーは音質が素晴らしいが、バッテリーの持ちが悪い。」
初回出力:
```json
{
"product_name": "スピーカー",
"positive_aspects": ["音質が良い"],
"negative_aspects": ["バッテリー"]
}
自己評価と修正案:
バッテリーの「持ちが悪い」という具体的な表現を「バッテリーの持ちが悪い」に修正し、より詳細にしました。
修正後の出力:
{
"product_name": "スピーカー",
"positive_aspects": ["音質が素晴らしい"],
"negative_aspects": ["バッテリーの持ちが悪い"]
}
例2:
入力レビュー: 「このコーヒーメーカーは使いやすいけど、少し高いね。」
初回出力:
{
"product_name": "コーヒーメーカー",
"positive_aspects": ["使いやすい"],
"negative_aspects": ["価格が高い"]
}
自己評価と修正案:
特になし。スキーマと内容に問題ありません。
修正後の出力:
{
"product_name": "コーヒーメーカー",
"positive_aspects": ["使いやすい"],
"negative_aspects": ["価格が高い"]
}
あなたのタスク:
入力レビュー: 「このマウスは軽くて操作しやすいけど、クリック音が大きすぎる。」
初回出力:
[LLMの初回出力]
上記の出力について、上記の例を参考に自己評価し、改善点があれば修正してください。
自己評価と修正案:
### 3. Chain-of-Thought(CoT)制約型自己修正
推論プロセスと自己評価ステップを明確に構造化し、詳細なフィードバックを与えることで、モデルが論理的に修正を行うように促します。これは、モデルが自身の思考過程を外部化し、ステップバイステップで検証する「Self-Refine」のようなフレームワークに類似しています \[2]。
```text
あなたはステップバイステップで問題を解決し、自身の解答を厳密に検証する論理的な推論エンジンです。以下のタスクを実行してください。
---
タスク: 与えられた数値を昇順にソートし、結果をカンマ区切りの文字列で出力してください。
---
1. 最初の回答を生成してください。
2. 生成された回答の各要素を分析し、タスクの制約(昇順、カンマ区切り)を満たしているか詳細に検証してください。具体的には、以下の点を確認してください。
a. 数値が本当に昇順になっているか?
b. 出力形式がカンマ区切りの文字列になっているか?
c. 元の数値がすべて含まれているか?(欠落や追加がないか?)
3. 検証結果に基づき、問題があればその理由を説明し、修正案を提示してください。
4. 修正案に基づいて最終的な回答を生成してください。
入力数値: [5, 2, 8, 1, 9, 3]
---
ステップ1: 最初の回答を生成します。
[LLMの初回出力]
ステップ2: 生成された回答を検証します。
a. 昇順チェック: ... (検証結果)
b. 形式チェック: ... (検証結果)
c. 欠落/追加チェック: ... (検証結果)
ステップ3: 検証結果に基づく修正案を提示します。
[LLMの自己評価と修正案]
ステップ4: 最終的な回答を生成します。
評価
自己修正プロンプトの効果を測定するためには、体系的な評価プロセスが必要です。
評価シナリオ
正例: 明確な指示に従い、期待される出力が得られるケース。
- 例: 「日本の首都はどこですか? JSON形式で出力してください。」
難例: 曖昧な指示、複数の解釈が可能なケース、大量のデータ処理、複雑な推論を要するケース。
- 例: 「このビジネスメールのトーンをもっとプロフェッショナルに修正してください。ただし、顧客への共感は維持してください。」
コーナーケース: 境界値、無効な入力、予期せぬエッジケース。
- 例: 「空のリストをソートしてください。」「不正なJSONスキーマでデータを抽出してください。」
自動評価の擬似コード
自動評価は、一貫性と効率性を提供し、プロンプトの変更による影響を定量的に把握する上で不可欠です。
# python
def evaluate_self_correction_output(llm_output: str, expected_output: str, task_type: str) -> dict:
"""
LLMの自己修正後の出力を自動評価する擬似コード。
Args:
llm_output (str): LLMから得られた最終出力。
expected_output (str): 期待される正解出力。
task_type (str): タスクの種類 ('json_extraction', 'text_summary', 'sorting'など)。
Returns:
dict: 評価結果(スコア、詳細)。
前提条件:
- `expected_output` は評価基準を満たす形式で事前に準備されている。
- 評価関数はタスクタイプに応じて適切なバリデーションロジックを持つ。
入出力:
- 入力: LLMの出力文字列、期待される出力文字列、タスクタイプ文字列
- 出力: 評価スコアと詳細を含む辞書
計算量:
- JSONパース: O(L) (Lは出力文字列長)
- 正規表現: O(L)
- 文字列比較: O(L)
メモリ条件:
- 主に文字列と辞書オブジェクトのため、出力長に比例。
"""
score = 0
details = []
# 1. 採点ルーブリックに基づく評価
if task_type == 'json_extraction':
try:
import json
parsed_output = json.loads(llm_output)
parsed_expected = json.loads(expected_output)
# スキーマの検証
if isinstance(parsed_output, dict) and all(k in parsed_output for k in parsed_expected):
score += 30 # スキーマ準拠
details.append("JSONスキーマに準拠しています。")
else:
details.append("JSONスキーマに準拠していません。")
# 内容の正確性(簡易チェック)
if parsed_output == parsed_expected: # 厳密な比較
score += 50
details.append("内容が期待値と完全に一致します。")
else:
# 詳細な比較ロジックを追加可能
details.append("内容が期待値と一部異なります。")
except json.JSONDecodeError:
details.append("JSON形式が無効です。")
elif task_type == 'text_summary':
# 2. 正規表現とキーワードに基づく評価
if len(llm_output) <= 100: # 文字数制限チェック
score += 20
details.append("文字数制限を満たしています。")
else:
details.append(f"文字数制限を超過しています ({len(llm_output)}文字)。")
if any(keyword in llm_output for keyword in ["AI", "LLM", "未来"]): # キーワード含有チェック
score += 30
details.append("主要キーワードが含まれています。")
else:
details.append("主要キーワードが不足しています。")
# 3. 関数評価(例: 外部APIで事実確認を行うなど)
# 例えば、外部のNLPサービスを使って要約の質を評価する
# from external_nlp_service import evaluate_summary_quality
# quality_score = evaluate_summary_quality(llm_output, expected_output)
# score += quality_score * 0.5 # 50点満点
# 簡易的な内容一致度
if expected_output in llm_output: # 非常に簡易的な確認
score += 50
details.append("期待される要点が要約に含まれています。")
else:
details.append("期待される要点が不足しています。")
elif task_type == 'sorting':
try:
llm_list = list(map(int, llm_output.split(',')))
expected_list = list(map(int, expected_output.split(',')))
if llm_list == expected_list:
score += 100
details.append("ソート結果が期待値と完全に一致します。")
else:
details.append("ソート結果が期待値と異なります。")
if not all(llm_list[i] <= llm_list[i+1] for i in range(len(llm_list)-1)):
details.append("結果が昇順ではありません。")
except ValueError:
details.append("出力が数値のカンマ区切り形式ではありません。")
# その他の共通評価項目
if "幻覚" not in llm_output and "不適切" not in llm_output: # 簡易的なネガティブチェック
score += 10 # 禁止事項に抵触しないことのボーナス
details.append("禁止事項に抵触していません。")
return {"total_score": min(score, 100), "details": details}
# 使用例
# output_json = '{"product_name": "スピーカー", "positive_aspects": ["音質が素晴らしい"], "negative_aspects": ["バッテリーの持ちが悪い"]}'
# expected_json = '{"product_name": "スピーカー", "positive_aspects": ["音質が素晴らしい"], "negative_aspects": ["バッテリーの持ちが悪い"]}'
# print(evaluate_self_correction_output(output_json, expected_json, 'json_extraction'))
# output_summary = 'AI技術の進化と未来に関する発表。最新LLMモデル、倫理的AI、ロボティクスが焦点。'
# expected_summary = 'AIの進化と未来に焦点を当てたイベント。最新LLM、倫理的AI、ロボティクスの未来が議論された。'
# print(evaluate_self_correction_output(output_summary, expected_summary, 'text_summary'))
# output_sorted = '1,2,3,5,8,9'
# expected_sorted = '1,2,3,5,8,9'
# print(evaluate_self_correction_output(output_sorted, expected_sorted, 'sorting'))
プロンプト→モデル→評価→改良のループ
自己修正プロンプトの設計と評価は、継続的なフィードバックループを通じて行われます。
graph TD
subgraph プロンプト開発ループ
Prompt["プロンプト生成"] --> LLM["LLM実行"]
LLM --> Output["初回出力"]
Output --> Feedback["自己修正フィードバック生成"]
Feedback --> RefinedPrompt["修正プロンプト"]
RefinedPrompt --> RefinedLLM["LLM再実行"]
RefinedLLM --> FinalOutput["最終出力"]
end
FinalOutput --> Evaluator["評価モジュール"]
Evaluator --> Analysis["誤り分析"]
Analysis --> Improvement["プロンプト改良"]
Improvement --> Prompt
誤り分析と抑制手法
失敗モードを理解し、適切な抑制手法を講じることで、自己修正プロンプトのロバスト性を高めます。
改良
誤り分析の結果に基づき、プロンプト、モデル、または評価プロセスを改良します。
プロンプト改良:
指示の具体性向上: 曖昧な表現を避け、より明確で具体的な指示に修正します。
制約の強化: 出力フォーマットや内容に関する制約をさらに厳密にします。
Few-shot例の追加・修正: より多様なケースや、自己修正の具体的な手順を示す高品質な例を追加します。
モデル選択:
- 特定のタスクにより適したLLMモデル(例: コード生成に特化したモデル)の検討。
チューニング:
- ドメイン固有のデータや自己修正の成功例を用いたファインチューニング。
再評価
改良されたプロンプトやモデルを用いて、再度評価シナリオを実行します。初期の評価結果と比較し、改善度合いを定量的に測定します。特に、難例やコーナーケースにおけるエラー率の低下、特定のメトリクス(例: JSONのパース成功率、要約のROUGEスコア)の向上を指標とします。この反復プロセスにより、自己修正プロンプトの性能は継続的に向上します。
まとめ
LLMの自己修正プロンプトは、モデルの信頼性と出力品質を向上させるための強力な手法です。ゼロショット、Few-shot、Chain-of-Thought制約型といった多様なプロンプト設計を通じて、モデルが自身の出力を批評し、修正する能力を最大限に引き出すことができます。入出力契約の明確化、体系的な評価、そして継続的な誤り分析と改良のループを回すことで、より堅牢で実用的なLLMアプリケーションを構築することが可能となります。2024年1月1日に発表された「Self-Correction in Large Language Models: A Survey」[1] でも様々な自己修正技術が包括的に紹介されており、この分野の重要性が増していることが示唆されています。
コメント