なぜ私のRAGアプリはハルシネーションを繰り返したのか、そしてどのように修正したか

数ヶ月前、私は自作のRAGサポートボットのデモを行いました。 それは同僚に対し、返金ポリシーは30日間であると答えました。 実際のポリシーは14日間です。 ボットは躊躇しませんでした。「わからない」とも言いませんでした。完全に自信満々に、でっち上げた回答を提示したのです。

RAGはハルシネーションを減らすためのものですが、私の設定では単に発生場所を移動させただけでした。 このシステムをデバッグする過程で、5つの教訓を学びました。

  1. チャンクに固定の文字数を使用するのをやめる 私は、わずかにオーバーラップさせた1000文字のチャンクを使用していました。 これが問題を引き起こしました。一つのチャンクに、配送ルールと返品ルールが混在してしまうことがよくあったのです。 モデルはこれらの異なるセクションを混ぜ合わせ、一つの誤った回答を作成してしまいました。 解決策:セマンティック・チャンキング(semantic chunking)に切り替えました。見出しや段落ごとにデータを分割することで、関連する情報をまとめて保持できるようにしました。

  2. 類似性は関連性を意味しない 私のretrieverは、コサイン類似度に基づいて上位3つのチャンクを取得していました。 チャンクは質問に似ているように見えても、答えを含んでいないことがあります。 モデルは、コンテキスト内のすべてが真実であると仮定してしまいます。 解決策:cross-encoderを使用したリランキング(reranking)のステップを追加しました。また、retrieval scoresのログ出力も開始しました。これにより、システムに適切な回答が欠けているかどうかを判断できるようになりました。

  3. モデルに「失敗してもよい」と伝える 当初のプロンプトは単純なものでした:「コンテキストを使用して質問に答えてください」。 コンテキストが不足している場合の指示がモデルに与えられていませんでした。 モデルはその空白を推測で埋めてしまったのです。 解決策:具体的な指示を追加しました。「もし回答がコンテキスト内にない場合は、わからないと答えてください」。これにより、ハルシネーションは即座に減少しました。

  4. リトリーバルの閾値を強制する リトリーバルが失敗しても、モデルは依然として一般的な知識を使用していました。 プロンプトでうまくいくことを期待していましたが、期待するだけでは戦略とは言えません。 解決策:厳格なスコアの閾値を設定しました。上位のリトリーバル・スコアが低すぎる場合、システムを停止させます。モデルに推測させるのではなく、フォールバック・メッセージを返すようにしました。

  5. 成功だけでなく、失敗についてもテストする ドキュメントがカバーしていることがわかっている簡単な質問しかテストしていませんでした。 曖昧なクエリや情報の欠落を無視していました。 ハルシネーションはその隙間に潜んでいるのです。 解決策:トラップ質問(trap questions)の評価セットを作成しました。これは、正しい答えがシステム内に存在しないケースです。変更を加えるたびに、これらのテストを実行しています。

RAGはハルシネーションを完全に止めるものではありません。それを制御可能にするものです。 私のボットがいまだにすべてを知っているわけではありません。 しかし今では、確信が持てないときには、そう伝えてくれます。 それによって、ツールとして実用的なものになりました。

出典: https://dev.to/pallavi_sharma_10c1a6f1da/why-my-rag-app-kept-hallucinating-and-how-i-fixed-it-3i10