LLMを使ったRAG開発の処方箋【チートシート】
実装するだけならノーコードでも可能なRAG構成ですが、社内問い合わせBotなどの運用に耐えられるレベルを開発するのは結構難しかったりします。
RAGの性能を上げる手法はいくつか存在しますが、メリットだけでなくデメリットもあるなど、とにかく全てを適応するのではなく、状況に応じて適切に選択する必要があります。
そのため、今回はRAG開発の処方箋と題して、チートシートのようなものを作ってみました。
RAGの動作を以下の四段階に分けて、それぞれの改善方法を記載しています。
質問の内容を解釈する
チャットを通じてユーザーの質問を理解する検索クエリを作成する
チャットの内容から検索クエリを作成する検索する
検索クエリを用いてDBを検索、コンテキストを作成する回答する
を用いて回答を生成する
問題が上記四段階のどこにあるかを解析し、適切な手法を選んでください。
1. 質問の内容を解釈する
ドキュメントのカテゴリ分け
ドキュメントをカテゴリ分類し、ユーザーに選択させてから問い合わせを始めてもらう。
窓口を選んでから問い合わせしてもらうイメージ。
LLMが質問の意味を理解し、目的のチャンクを検索しやすくなる。
どんな症状に効くのか
質問に考慮しておくべき前提が存在する。(「ログイン方法を教えて」という質問に対して、「社内ポータルの」という前提が存在するなど)
ドキュメントが多すぎて、目的のチャンクが検索で引っかからない
副作用
ユーザーにカテゴリ選択を強いないといけなくなる
独自ワードに関する辞書の作成
一般的でない単語に関する辞書を用意し、ユーザーとの会話に出現した単語の解説をコンテキストに追加する。
独自の単語でもLLMが理解できるようになる。
どんな症状に効くのか
ユーザーとの会話に一般的でない単語が多数存在する(社内独自の単語など)
副作用
コンテキストサイズが大きくなり回答精度が落ちる
Function Callingによる動的な検索
返答のたびに検索を行うのではなく、LLMに判断させて必要に応じて検索させるようにする。
以下のようなことがLLMの判断でできるようになる。
会話全体の文脈を理解した検索
質問の内容が曖昧であれば聞き返して検索
検索済みの情報で回答ができるなら検索をせずに回答
どんな症状に効くのか
ユーザーからの質問が曖昧で、何を聞きたいか具体的でない
毎回検索を行っているせいでレスポンスが悪い
副作用
プロンプトの調整難易度増
2. 検索クエリを作成する
RAG Fusion
一つの検索タスクに対して、クエリを多数生成させて、検索結果を統合する。
後述するリランキングとの組み合わせがほぼ必須。
目的のチャンクが検索で引っかかりやすくなる。
どんな症状に効くのか
目的のチャンクが検索で引っかからない。
検索クエリとチャンクの文章の乖離が大きい。
副作用
検索による計算コスト増
リランキングと組み合わせないと、コンテキストサイズが大きくなり、回答精度が落ちる
検索機能にタグ・カテゴリを追加
Function Callingなどを利用し、LLMにタグやカテゴリも選択させながら検索させる。
ドキュメント全体のメタデータを考慮した検索ができるようになる。
どんな症状に効くのか
チャンク単位で見た時に回答になりそうな情報が大量に存在し、どのチャンクが正しい情報かわからない
(社内システムが乱立しており、ログインに関する情報が何個も存在しているなど)
副作用
クエリの作成にかかる時間増
ドキュメントを追加する時の手間が増える。
HyDE
コンテキストを使用せずに仮回答を生成し、仮回答をクエリとしてベクトル検索を行う。
より回答に近い文章を検索できるようになる。
どんな症状に効くのか
目的のチャンクが検索で引っかからない。
検索クエリとチャンクの文章の乖離が大きい。
副作用
プロンプトの調整が難しく、逆に検索精度が落ちる場合がある。
3. 検索する
チャンクサイズの縮小
チャンクサイズを500文字→300文字にするなど。
チャンクサイズが小さくなると、チャンクに対する一つ一つの単語や文章の重みが大きくなり、目的のチャンクが引っかかりやすくなる。
どんな症状に効くのか
目的のチャンクが検索で引っかからない
文章に対してチャンクサイズが大きすぎる(細かい単語などに検索が引っかからない)
副作用
長文の文脈を考慮した検索ができなくなる
チャンクサイズの拡大
チャンクサイズを300文字→500文字にするなど
チャンクサイズが大きくなると、全体の文脈を考慮した検索ができるようになる。
どんな症状に効くのか
目的のチャンクが検索で引っかからない
文章に対してチャンクサイズが小さすぎる(文脈を意識した検索が行われない)
副作用
単語によってマッチしなくなる
コンテキストサイズが大きくなり回答精度が落ちる
ハイブリッド検索
Vector検索、キーワード検索などを組み合わせる。
リランキングと一緒に使うことが望ましい。
どんな症状に効くのか
目的のチャンクが検索で引っかからない
単語でマッチさせたいユースケースと、文脈でマッチさせたいユースケースが混在している(検索の観点が状況によって異なる)
副作用
検索による計算コスト増
リランクと組み合わせないと、コンテキストサイズが大きくなり、回答精度が落ちる
ドキュメントメタデータへのタグ付け
ドキュメントにタグを追加し、メタデータを充実させる。
タグ付けは人力か、LLMによって自動で行う。
LLMがチャンクの内容を理解しやすくなる。
どんな症状に効くのか
チャンク単位で見た時に回答になりそうな情報が大量に存在し、どのチャンクが正しい情報かわからない(社内システムが乱立しており、ログインに関する情報が何個も存在しているなど)
副作用
ドキュメント追加する時の手間が増える
コンテキストサイズが大きくなり回答精度が落ちる
リランキング
検索結果をより高度に再度ランク付けする。
ハイブリッド検索や、RAG Fusionと組み合わせると効果的。
リランキング結果の上位だけを利用することで、コンテキストサイズの削減ができる。
どんな症状に効くのか
検索結果の下位に目的のチャンクが存在しており、それを含めようとするとコンテキストサイズが大きくなってしまう。
ハイブリッド検索やRAG Fusionを使っており、検索順位が明確でない。
副作用
検索による計算コスト増
スクロール機能
コンテキストの中から必要な情報が見つからなかった場合、追加でコンテキストを取得する。
必要な情報があるかどうかはLLMが判定する。
例えば検索結果を三件取得したが、必要な情報がなかったため、次の三件を取得する。
精度を落とさずにより多くの情報を使って回答できるようになる。
どんな症状に効くのか
検索結果の下位に目的のチャンクが存在しており、それを含めようとするとコンテキストサイズが大きくなってしまう。
副作用
検索にかかる時間増
4. 検索結果を元に回答する
チャンク拡張
検索結果チャンクの上下複数チャンクも利用してコンテキストを作成する。
長い文脈を考慮して回答できるようになる。
どんな症状に効くのか
コンテキストが中途半端に途切れてしまい、長文を考慮した回答ができない。
表などが途中で途切れてしまい、ヘッダーなどの情報が欠落している。
副作用
コンテキストサイズが大きくなり回答精度が落ちる
コンテキストのフォーマットを調整
コンテキストのフォーマットを変更し、コンテキストの区切り、メタデータなどを明確化する。
別々のドキュメントであることや、メタデータを明確に理解して回答できるようになる。
どんな症状に効くのか
複数のドキュメントの内容を混ぜて間違った回答をしてしまう。
メタデータ(参照元URLやページ数など)がうまく出力できない。
副作用
特になし
チャンク分割ロジックの調整
チャンク分割に以下のようなロジックを追加し、中途半端な箇所でチャンク分割されないようにする。
表は途中で分割しない
必ず。(句点)や.(ピリオド)の箇所で分割する
セクションの区切りで必ず分割する
チャンクが意味のあるまとまった文章になり、LLMが内容を理解しやすくなる。
どんな症状に効くのか
コンテキストが中途半端に途切れてしまい、長文を考慮した回答ができない。
表などが途中で途切れてしまい、ヘッダーなどの情報が欠落している。
副作用
コンテキストサイズが大きくなり回答精度が落ちる
メタデータの充実
ページ数やドキュメントのURL、タグ、カテゴリ、ドキュメントの要約などの情報をメタデータとして付与する。
参照元の情報を充実させることができる。
ドキュメント全体の内容を考慮した回答ができるようになる。
どんな症状に効くのか
チャンク単位で見た時に回答になりそうな情報が大量に存在し、どのチャンクが正しい情報かわからない(社内システムが乱立しており、ログインに関する情報が何個も存在しているなど)
ユーザーが参照元のドキュメントを確認できない。
正確な回答に前提となる情報が必要。
副作用
コンテキストサイズが大きくなり回答精度が落ちる
まとめ
リクエストが多ければ(&時間があれば)各手法に関しての細かい解説などもしようと思います。
リクエストはコメント欄かXにお願いたします。