私のRAGアプリがなぜハルシネーションを起こしたのか、そしてそれをどう修正したか

かつて、同僚に私のRAGサポートボットをデモした時のことです。

ボットは、返金ポリシーは30日間であると彼女に答えました。

実際のポリシーは14日間です。

ボットは「わからない」とは言いませんでした。完全に自信満々に、でっち上げた回答をしたのです。

RAGはハルシネーションを止めるためのものですが、私の設定では、単にハルシネーションの発生場所を移動させただけでした。

私は以下の5つのステップに従って、これを修正しました。

  1. チャンキング戦略を修正する

以前は文字数でドキュメントを分割していました。これは間違いでした。

1つのチャンクに、配送と返品といった異なるトピックが混在してしまうことがよくありました。その結果、モデルはこれらを混ぜ合わせて誤った回答を生成してしまったのです。

修正策:セマンティック・チャンキング(semantic chunking)に切り替えました。現在は、見出しや段落ごとにテキストを分割しています。

  1. 類似度スコアだけを信じるのをやめる

私のリトリーバーは、コサイン類似度に基づいて上位3つのチャンクを取得していました。

「似ている」ことと「関連している」ことは同じではありません。チャンクが質問に似ているように見えても、回答が含まれていないことがあるからです。

修正策:cross-encoderを用いたリランキング(reranking)のステップを追加しました。これにより、システムに実際のデータがない場合にそれを検知できるようになりました。

  1. モデルに「失敗する許可」を与える

以前のプロンプトは、「コンテキストを使用して質問に答えてください」と言うだけでした。

コンテキストに回答が不足している場合、モデルはその空白を推測で埋めてしまっていました。

修正策:直接的な指示を追加しました。「もし回答がコンテキスト内にない場合は、わからないと答えてください」という指示です。これだけで、ほとんどのハルシネーションを防ぐことができました。

  1. リトリーバルの閾値を設定する

リトリーバルが失敗した際、モデルが一般知識を使ってしまうことがありました。プロンプトでうまくいくことを期待していましたが、「期待」は戦略ではありません。

修正策:スコアのカットオフ(しきい値)を追加しました。リトリーバルスコアが低すぎる場合、システムはフォールバック用のレスポンスを返します。「コンテキストがない=回答しない」ということです。

  1. 「成功」ではなく「失敗」をテストする

以前は簡単な質問しかテストしていませんでした。曖昧なクエリや情報の欠落については無視していました。

修正策:トラップ質問(trap questions)の評価セットを作成しました。これらは「回答が存在しないケース」です。これらのテストを定期的に実行することで、システムがどこで壊れるのかを正確に把握できるようになります。

RAGはハルシネーションを排除するものではありません。ハルシネーションを制御可能にするものです。

私のボットは、今でもすべての詳細を知っているわけではありません。しかし、今は確信が持てないときにそれを認めます。そのおかげで、実用的なものになりました。

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

オプションの学習コミュニティ: https://t.me/GyaanSetuAi