LESSON

回答生成

「分類できた。FAQも見つかった。あとはユーザーに伝わる回答を生成するだけだ。」

田中VPoEが回答品質の基準を示す。

「テンプレートの丸写しではなく、ユーザーの状況に合わせてパーソナライズされた回答を生成する。ただし、嘘や推測は厳禁だ。」

回答生成の戦略

戦略適用場面メリットデメリット
テンプレートFAQ完全一致正確、高速柔軟性なし
RAG(検索+生成)FAQ部分一致正確+自然やや遅い
LLM生成FAQ該当なし柔軟ハルシネーションリスク

RAGベースの回答生成

from langchain_openai import ChatOpenAI

@tool
def generate_response(inquiry: str, category: str, faq_context: str) -> str:
    """問い合わせへの回答ドラフトを生成する"""
    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)

    prompt = f"""
    あなたはNetShop社のカスタマーサポート担当です。
    以下の問い合わせに対する回答ドラフトを生成してください。

    ## ルール
    - 丁寧な敬語で回答する
    - FAQ情報に基づいて正確に回答する
    - FAQ情報にない内容は「確認いたします」と回答する
    - 推測や不確かな情報は含めない
    - 具体的な手順がある場合はステップで示す

    ## 問い合わせカテゴリ
    {category}

    ## 関連FAQ情報
    {faq_context}

    ## お客様の問い合わせ
    {inquiry}

    ## 回答ドラフト
    """

    response = llm.invoke(prompt)
    return response.content

回答の品質チェック

class ResponseQualityChecker:
    """回答の品質を検証"""

    def __init__(self):
        self.checks = [
            self._check_hallucination,
            self._check_politeness,
            self._check_completeness,
            self._check_length,
        ]

    def validate(self, response, inquiry, faq_context):
        """回答の品質を検証"""
        results = []
        for check in self.checks:
            result = check(response, inquiry, faq_context)
            results.append(result)

        passed = all(r['passed'] for r in results)
        return {
            'passed': passed,
            'checks': results,
        }

    def _check_hallucination(self, response, inquiry, faq_context):
        """ハルシネーションの検出"""
        # FAQ情報にない具体的な数値や手順が含まれていないか
        llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
        prompt = f"""
        以下の回答がFAQ情報に基づいているか検証してください。
        FAQ情報にない事実や推測が含まれている場合は「false」と回答。

        FAQ情報: {faq_context}
        回答: {response}

        grounded (true/false):
        """
        result = llm.invoke(prompt)
        is_grounded = 'true' in result.content.lower()
        return {'check': 'hallucination', 'passed': is_grounded}

    def _check_politeness(self, response, inquiry, faq_context):
        """敬語チェック"""
        polite_markers = ['ございます', 'いたします', 'ください', 'お問い合わせ']
        has_polite = any(m in response for m in polite_markers)
        return {'check': 'politeness', 'passed': has_polite}

    def _check_completeness(self, response, inquiry, faq_context):
        """質問に対する回答の網羅性"""
        return {'check': 'completeness', 'passed': len(response) > 50}

    def _check_length(self, response, inquiry, faq_context):
        """回答の長さ"""
        return {'check': 'length', 'passed': 50 <= len(response) <= 1000}

まとめ

項目ポイント
RAG方式FAQ検索結果をコンテキストとしてLLMに渡す
品質チェックハルシネーション/敬語/網羅性/長さを検証
ガードレールFAQ情報にない内容は「確認します」と回答
テンプレート併用FAQ完全一致はテンプレートで高速応答

チェックリスト

  • RAGベースの回答生成を実装できる
  • プロンプトにガードレールを設定できる
  • 回答の品質チェック項目を定義できる
  • ハルシネーション検出の仕組みを理解した

次のステップへ

回答生成を実装した。次はエスカレーション判断を学ぼう。

推定読了時間: 30分