はじめに
この記事では、RAG(Retrieval-Augmented Generation)システムにおいて、LLMがトピックを提案する際に発生する幻覚(hallucination)を低減するためのシンプルかつ効果的なパターン「Check-before-Suggest」を紹介します。つまり、ユーザーに表示する前にLLMの提案をベクトル検索で裏取り(grounding)するという手法です。
対象読者:RAGシステムを構築するエンジニア、サポート用チャットボットを設計するチーム、サービスの信頼性を維持したい運用チーム。
1. 問題
LLMはしばしば「創作」的に応答を生成します。その結果、もっともらしいトピックを提案しても、ナレッジベースに対応する根拠(ドキュメント)が存在しないことがあります。典型的なシナリオ:
- ユーザーがトピックの提案を求める(例:「関連するトピックを3つ提案して」)
- LLMが3つのトピックを提示するが、RAGのデータベースに該当ドキュメントがない
- ユーザーが提案をクリックすると、システムが「申し訳ありません、その情報は持っていません」と返答する
この結果、ユーザー体験が損なわれ、サービスへの信頼が低下します。したがって「ドキュメントで裏取りできないトピックは表示しない」ことを、ユーザー向け提案の必須ガードとすべきです。
2. 解決策(Solution / Reverse Validation)
アイデアは単純です。LLMが候補トピック(candidate topics)を生成した後、それぞれについてベクトル検索で裏取り(Reverse Validation)を行い、検索結果が閾値を満たす候補のみを表示します。
処理フロー(要約):
ドキュメントで裏取りできないトピックは表示しないでください。これはオプションではなく、信頼を守るための必須ガードです。
3. コード例(Python / async)
フローの具体例:LLMが候補を生成し、各候補に対して並列で検索を行い、ドキュメントのスコアが閾値を超える候補のみを採用します。
# async 疑似コード
async def check_before_suggest(question: str, intent: str, embedding_service, llm, threshold=0.75):
if intent != "AMBIGUOUS":
return await normal_handling(question)
# 1) LLM が候補トピックを生成
candidates_text = await llm.generate(prompt=f"Suggest 3 likely topics related to: {question}")
candidates = parse_list(candidates_text) # ['A', 'B', 'C']
# 2) Reverse validation:各候補に対してベクトル検索を並列実行
suggested = []
tasks = [embedding_service.search_all(query=c, top_k=3) for c in candidates]
results = await asyncio.gather(*tasks)
for c, docs in zip(candidates, results):
if docs and docs[0].score >= threshold:
# メタデータからタイトル/ラベルを採る
suggested.append(docs[0].metadata.get("title") or c)
# 3) 結果返却
if suggested:
return f"次のどれについて質問しますか:{', '.join(suggested)}?"
else:
return "該当するドキュメントが見つかりませんでした。検索範囲を広げますか、条件を詳しく教えてください。"
注意点:
-
threshold(例: 0.75)は埋め込みモデルやベクトルDBに応じて調整が必要です。 -
search_allはscoreとmetadataを返すようにし、ソースの検証が可能であること。 - バリデーション結果(topic → hit/miss)はキャッシュしてレイテンシとコストを削減する。
4. 実例
ユーザー: "deep retrieval に関するトピックを3つ教えて"
- LLM の生成: ["Augmented Retrieval", "SparseRerank Methods", "Quantum Retrieval"]
- ベクトル検索は最初の2つにドキュメントを返し、"Quantum Retrieval" には該当がない
- システムは "Augmented Retrieval, SparseRerank Methods" を提案として表示する
5. 適用すべき場面
- ユーザー向けの提案機能を持つRAGシステム
- サポートボットやドキュメントアシスタントなど、信頼性が重要な場面
- 幻覚(hallucination)がユーザー体験に悪影響を与える場合
適用不要な場面:創作やクリエイティブ用途で、grounding を要求しない場合。
6. 運用上の注意
- バリデーションはレイテンシを増やすため、キャッシュや並列実行で最適化する。
- 候補がドロップされる割合をダッシュボードで監視し、プロンプトや閾値を調整する。
- 出典(source, date, author)などメタデータが明確なドキュメントを優先する。
7. 拡張 / 代替案
- 生成→検索の代わりに、ユーザークエリで直接検索して上位タイトルを取得し、LLMに要約/整形させる方法。
- ソース信頼度をスコアリングに組み込み、提案のランキングに反映する。
結論
Check-before-Suggestは、RAGシステムの信頼を保つための小さなが重要なガードです。提案表示前に必ず裏取り(grounding)を行うことで、ユーザーの不満を減らし、サービス全体の信頼性を高められます。