LLM失敗モード抑制:Hallucination対策

Tech

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

LLM失敗モード抑制:Hallucination対策

大規模言語モデル(LLM)の応用において、Hallucination(幻覚)は最も深刻な失敗モードの一つです。Hallucinationとは、LLMが事実に基づかない、あるいは与えられた情報と矛盾する内容をもっともらしく生成する現象を指します。本記事では、LLMのプロンプト設計と評価を専門とするエンジニアの視点から、Hallucinationを抑制するための戦略を包括的に解説します。

1. ユースケース定義

特定のドメイン知識に基づいた情報提供システムを想定します。例えば、企業内で製品仕様に関するFAQ応答システムや、カスタマーサポートにおける情報検索・要約が挙げられます。このシステムでは、ユーザーからの質問に対して、既存の公式ドキュメントやデータベースから取得した情報に基づき、正確かつ簡潔に回答することが求められます。

2. 入出力契約(制約付き仕様化)

LLMの安定した運用のためには、明確な入出力契約を定義し、Hallucinationを含む失敗モードに対する挙動を事前に規定することが不可欠です。

  • 入力:

    • 自然言語による質問文(例: 「XYZ製品のバッテリー持続時間は何時間ですか?」)。

    • オプションとして、参照すべき外部ドキュメントやデータベースからの関連情報(RAGのコンテキスト)。

  • 出力:

    • フォーマット: 事実に基づいた簡潔な回答文。特定の形式(例: JSON)が求められる場合は、その形式を厳守。

    • 出典: 可能であれば、回答の根拠となった情報源(ドキュメント名、URL、参照ページ)を付記。

    • 失敗時の挙動: 関連情報が見つからない、または質問に対する正確な回答を生成できない場合、「情報不足のため回答できません」といった定型文で回答し、架空の情報を生成しない。

  • 禁止事項:

    • Hallucination: 誤った事実、存在しない情報、根拠のない推測の生成。

    • 様式崩れ: JSON形式を要求したにもかかわらず、XMLや不正なJSONを生成するなどのフォーマット逸脱。

    • 脱線: ユーザーの質問意図から逸脱した、無関係な内容の生成。

    • 倫理的逸脱: 差別的、有害、不適切な内容の生成。

3. Hallucinationの主要な失敗モードと抑制手法

Hallucinationはいくつかのタイプに分類でき、それぞれに効果的な抑制手法が存在します。

  • 失敗モード:

    1. 事実の捏造: 外部の客観的事実や参照情報と異なる内容を生成する(例: 「XYZ製品のバッテリー持続時間は20時間です」と誤答する場合、公式情報では10時間)。

    2. 論理の一貫性の欠如: 生成された回答内の推論過程や複数の文の間に矛盾が生じる(例: ある部分で肯定し、別の部分で否定する)。

    3. 文脈からの逸脱: ユーザーの質問やプロンプトで与えられた文脈から外れ、無関係なトピックについて回答する。

  • 抑制手法:

    • System指示による制約: LLMの役割、目的、出力形式、禁止事項を明確に指示する。

    • RAG (Retrieval Augmented Generation): 外部の信頼できる情報源(データベース、ドキュメント)から関連情報を検索し、LLMにコンテキストとして与えることで、LLMがその情報に基づいて回答を生成するように促します。これにより、事実に基づいた回答が強化されます。参照: [Shashi et al., “Navigating the Landscape of Large Language Models (LLMs): A Comprehensive Survey”] (arXiv:2407.03966, 2024年7月5日公開)

    • Chain-of-Thought (CoT): LLMに最終的な回答だけでなく、その回答に至るまでの思考プロセスを段階的に出力させることで、推論の透明性を高め、論理的な一貫性を確保しやすくします。

    • 自己修正 (Self-correction): LLMが自身の生成した回答を批判的に評価し、問題点を発見した場合は修正を試みるメカニズムです。複数回の推論ステップを経て回答の精度を高めます。参照: [M. Eger, “Self-Correction for Generative AI”] (arXiv:2406.14250, 2024年6月21日公開)

    • 検証ステップの組み込み: 生成された回答を別のLLM(またはルールベースのシステム)でファクトチェックしたり、RAGで取得した元情報と照合するステップを導入します。

    • リトライ戦略: 特定の失敗モード(例: 不正なJSON形式)が検出された場合に、プロンプトを調整してLLMに再生成を指示する戦略です。

4. プロンプト設計の基本原則とHallucination対策

Hallucination抑制のためのプロンプト設計では、明確性、具体性、制約、そして外部情報の活用が基本原則となります。以下に3種のプロンプト案を提示します。

プロンプト案1: ゼロショットプロンプト(制約型)

外部情報がない場合や、モデルが内包する知識で回答を試みる際の最低限のHallucination対策です。

あなたは質問応答アシスタントです。ユーザーの質問に対し、以下の制約を厳守して簡潔に回答してください。

1. 提供された情報(プロンプト内、またはシステムに組み込まれた情報)のみに基づいて回答すること。

2. 情報がない場合は「情報不足のため回答できません」と正直に答えること。

3. 架空の情報、推測、意見を生成することは固く禁じます。

4. 回答は簡潔な日本語で100文字以内にまとめること。

質問: [質問内容]

プロンプト案2: 少数例プロンプト(RAG/CoTの示唆)

RAGで取得した具体的な情報を提供し、Few-shot学習で思考プロセス(CoT)の例を示すことで、Hallucinationを抑制しつつ正確性を高めます。

あなたは製品仕様に関する専門家です。以下の「参考情報」と「質問」に基づいて、製品の具体的な情報を正確に教えてください。回答には必ず参考情報内の事実のみを使用し、思考プロセスを段階的に記述してください。情報がない場合は「参考情報に該当する情報はありません」と答えてください。

---
参考情報:

- XYZ製品はバッテリー持続時間が最大10時間です。(ソース: 公式ウェブサイト, 2024年7月1日)

- ABC製品の重量は150gです。(ソース: 製品データシート, 2024年6月15日)

- PQR製品の価格は50,000円です。(ソース: オンラインストア, 2024年7月20日)
---

質問: XYZ製品のバッテリー持続時間は何時間ですか?

思考プロセス:

1.  質問は「XYZ製品のバッテリー持続時間」についてである。

2.  参考情報から「XYZ製品はバッテリー持続時間が最大10時間です。」という記述を見つける。

3.  この情報が質問に直接対応している。
回答: XYZ製品のバッテリー持続時間は最大10時間です。

---

質問: [質問内容]

思考プロセス:

プロンプト案3: Chain-of-Thought制約型プロンプト(検証ステップの組み込み)

Hallucination対策として、回答の生成と検証を明示的にステップ化し、モデルに自己検証を促します。

あなたは与えられた「文書」に基づいて、ユーザーの「質問」に回答するAIです。回答は以下の手順で生成し、各ステップの結果を明確に示してください。

---
文書: [外部ソースからのテキスト(例: RAGで取得した記事全文)]
---

質問: [質問内容]

---
**手順:**

1.  **関連情報抽出**: 「文書」の中から、質問に直接関連する重要なセンテンスをすべて抽出し、箇条書きで列挙してください。

    - [関連センテンス1]

    - [関連センテンス2]

    - ...

2.  **回答生成**: 抽出した情報のみを用いて、質問に対する簡潔かつ正確な回答を生成してください。この際、文書にない情報は絶対に含めないでください。

3.  **根拠確認**: 生成した「回答」が、手順1で「抽出した情報」と完全に一致し、かつ追加の推測や情報を含んでいないかを確認し、以下のいずれかの評価を記述してください。

    - **評価**: 根拠あり(完全に一致)

    - **評価**: 根拠なし(一部矛盾または推測を含む)
    もし「根拠なし」の場合は、手順2の回答を修正するか、「文書に情報不足のため回答できません」と述べてください。

4.  **最終回答**: 手順3で確認・修正された最終的な回答を提示してください。

5. 評価戦略と自動評価

Hallucination抑制のためには、生成された回答が事実に基づいているかを評価する体系的な戦略が必須です。

評価シナリオ

  • 正例: RAGで提供される情報と質問が明確に一致し、回答が容易なケース。

    • 例: 「文書AにはXYZ製品のバッテリー持続時間が10時間と記載されています。XYZ製品のバッテリー持続時間は?」
  • 難例:

    • 曖昧な質問: 複数の解釈が可能な質問。

    • 情報不足: RAGで取得した情報が質問に部分的にしか答えていない、あるいは全く答えていないケース。

    • 推測誘発: LLMが補完したくなるような、わずかに情報が欠けている質問。

  • コーナーケース:

    • 競合情報: RAGで提供される複数の情報源が互いに矛盾しているケース。

    • 禁止事項誘発: 存在しない製品機能や架空のデータを意図的に質問し、Hallucinationを誘発する試み。

自動評価の擬似コード

Hallucinationの自動評価は、主にキーワードマッチング、正規表現、LLMベースの評価などを組み合わせることで実現します。

import re

def evaluate_hallucination(generated_answer: str, expected_facts: dict, forbidden_patterns: list) -> tuple[int, str]:
    """
    LLMのHallucinationを自動評価する擬似コード。
    入力:
        generated_answer (str): LLMが生成した回答。
        expected_facts (dict): 期待される事実やキーワードをキーとして、その重要度や存在確認フラグを持つ辞書。
                               例: {"バッテリー持続時間": {"value": "10時間", "required": True}, ...}
        forbidden_patterns (list): Hallucinationや脱線を示す正規表現パターンのリスト。
    出力:
        tuple[int, str]: スコアとフィードバックメッセージ。
    前提:

        - generated_answer は日本語のテキスト。

        - expected_facts と forbidden_patterns は評価前に定義済み。
    """
    score = 100 # 初期スコア
    feedback_messages = []

    # 1. 期待される事実の確認(事実整合性)

    missing_facts = []
    for fact_key, details in expected_facts.items():
        if details.get("required", False): # 必須の事実の場合
            expected_value = details.get("value", "")
            if expected_value not in generated_answer:
                missing_facts.append(fact_key)

    if missing_facts:
        score -= (30 * len(missing_facts)) # 必須事実の欠落で減点
        feedback_messages.append(f"❌ 事実整合性の欠如: 以下の必須情報が見つかりません: {', '.join(missing_facts)}")
    else:
        feedback_messages.append("✅ 事実整合性: 期待される必須情報がすべて含まれています。")

    # 2. 禁止パターンの検出(Hallucination / 脱線 / 不適切な内容)

    hallucination_detected = False
    for pattern_str in forbidden_patterns:
        if re.search(pattern_str, generated_answer, re.IGNORECASE):
            score -= 50 # 禁止パターン検出で大幅減点
            feedback_messages.append(f"🛑 禁止事項違反: パターン '{pattern_str}' が検出されました (Hallucination/脱線)。")
            hallucination_detected = True
            break # 最初の違反で十分な場合

    if not hallucination_detected:
        feedback_messages.append("✅ 禁止パターンなし: Hallucinationや脱線を示すパターンは検出されませんでした。")

    # 3. 回答不能時の挙動評価 (Hallucination回避)


    # この評価は、期待される回答が「情報不足」であるシナリオでのみ有効


    # 例: expected_factsが空、かつ generated_answer が「情報不足」を含む場合

    if not expected_facts and ("情報不足" in generated_answer or "回答できません" in generated_answer):
        score += 20 # 適切に回答不能を表明した場合に加点
        feedback_messages.append("✅ 回答不能時の挙動: 適切に情報不足を宣言しています。")
    elif expected_facts and ("情報不足" in generated_answer or "回答できません" in generated_answer):

        # 情報があるのに回答不能とされた場合(誤って回答を拒否)

        score -= 10 # 減点
        feedback_messages.append("⚠️ 回答拒否: 情報があるにもかかわらず回答を拒否しました。")

    # スコアは0以下にならないようにする

    final_score = max(0, score)
    return final_score, "\n".join(feedback_messages)

# ルーブリック例:


# - 期待される必須事実の欠落: 1つにつき -30点


# - 禁止パターン検出: -50点 (致命的)


# - 情報不足シナリオでの適切な回答拒否: +20点


# - 情報がある場合の不適切な回答拒否: -10点

6. プロンプト→モデル→評価→改良のループ

Hallucination対策は一度で完了するものではなく、継続的な評価と改良のサイクルが不可欠です。このプロセスをMermaidで可視化します。

graph TD
    A["プロンプト設計"] --> B("LLMモデル")
    B --> C{"出力生成"}
    C --> D["評価シナリオ実行"]
    D --> E{"自動評価"}
    E -- |適合: デプロイへ| F_Pass["結果分析: 適合"]
    E -- |不適合: 改良へ| F_Fail["結果分析: 不適合"]
    F_Pass --> H["デプロイ/本番適用"]
    F_Fail -- |Hallucination検出/パターン特定| G["プロンプト改良/RAG強化/モデル調整"]
    G --> A

7. 誤り分析と改良

評価サイクルでHallucinationが検出された場合、以下のステップで分析と改良を行います。

  • 誤り分析:

    • Hallucinationのタイプ分類: 事実誤認、論理矛盾、文脈逸脱のいずれに該当するかを特定します。参照: [Shashi et al., “Navigating the Landscape of Large Language Models (LLMs): A Comprehensive Survey”] (arXiv:2407.03966, 2024年7月5日公開)

    • プロンプトとの関連: どのプロンプトの指示が曖昧だったか、または不十分だったかを特定します。

    • RAGの問題: 外部知識ベースの情報が古い、不正確、あるいは関連情報が不足していたかを検証します。

    • モデルの限界: モデルが特定のタイプの質問やドメイン知識で幻覚を起こしやすいかを特定します。

  • 改良:

    • System指示の具体化: 「〇〇以外の情報は回答に含めない」「必ず参照元を記載する」など、より厳密な制約を追加します。

    • RAGの強化: 知識ベースの定期的な更新、複数の情報源の統合、埋め込みモデルの改善、検索アルゴリズムの最適化を行います。

    • Chain-of-Thoughtステップの詳細化: 推論の各段階で特定の検証を組み込む、より多くのステップを要求するなど、CoTを強化します。

    • 自己検証ステップの導入: LLMに自身の回答を複数回見直させ、矛盾がないか確認させるステップを追加します。参照: [M. Eger, “Self-Correction for Generative AI”] (arXiv:2406.14250, 2024年6月21日公開)

    • ファインチューニング: 特定のドメインにおけるHallucinationパターンが多い場合、少量ながら高品質なデータでモデルをファインチューニングすることで、ドメイン特化の精度向上を図ります(ただし、コストと専門知識が必要)。

8. まとめ

LLMにおけるHallucination対策は、プロンプト設計、RAG(Retrieval Augmented Generation)の導入、継続的な評価、そして体系的な改良サイクルを組み合わせることで実現されます。明確な入出力契約と自動評価の仕組みを確立し、Hallucinationの発生パターンを分析してプロンプトやシステムを洗練し続けることが、信頼性の高いLLMアプリケーション運用に不可欠です。このアプローチを通じて、LLMの可能性を最大限に引き出しつつ、その失敗モードを効果的に抑制できるでしょう。

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

コメント

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