RAG の精度を上げる設計:チャンク分割・検索・リランキング・評価
外れる原因を「検索」と「回答」に分けて、順に直す
RAG が外れるとき、原因は検索にあるのか、回答にあるのかを分けて考えると、直す場所が見えてきます。この記事では、チャンク分割、ハイブリッド検索、リランキング、文脈の付け足し、プロンプトでの渡し方、評価までを、公式ドキュメントと一次資料に沿って整理します。
RAG が外れるときの典型パターン
RAG(検索拡張生成)は、質問に関係する文書を検索で取り出し、それをモデルに渡して答えさせる仕組みです。作るのは簡単ですが、それらしい答えが返るのに肝心なところが外れる状態から抜けるのは大変です。外れ方には次の型があります。
| 症状 | 多い原因 | 見る場所 |
|---|---|---|
| 資料にあるはずの答えが出ない | 必要な断片が検索結果に入っていない | 分割、検索方法 |
| 型番や固有名詞の質問だけ外れる | 意味検索だけで、字面の一致を見ていない | ハイブリッド検索 |
| 関連はあるが、答えの核心を含む断片が下位にいる | 順位づけが粗い | リランキング |
| 断片は正しいのに答えが間違う | 渡し方、指示、断片の文脈不足 | プロンプト、文脈の付け足し |
| 出典を示せない、確かめられない | 断片に出典情報が付いていない | 出典の持たせ方 |
大事なのは、「答えが悪い」という一つの症状を、検索の問題と回答の問題に分けて考えることです。検索で必要な断片を取れていなければ、モデルを変えても直りません。逆に、取れているのに間違うなら、直すのは検索ではありません。この記事は、この切り分けを軸に、設計判断を順に見ていきます。
全体の流れ
典型的な RAG は、準備と質問時の二つの段階に分かれます。
- 準備:文書を断片(チャンク)に分け、それぞれを数値のベクトルにして索引に保存する。
- 質問時:質問から候補の断片を検索し、必要なら順位を付け直し、上位だけをプロンプトに入れて回答させる。
つまり、直せる場所は「分け方」「索引の作り方」「検索のかけ方」「順位の付け直し」「渡し方」の五つです。一度に全部いじらず、評価で悪い場所を特定してから手を入れるのが近道です。
チャンク分割:まず分け方を決める
チャンク分割は、精度への影響が大きいのに、最初の既定値のまま放置されがちな部分です。小さすぎると文脈が欠け、大きすぎると一つの断片に別の話題が混ざって検索に引っかかりにくくなります。
参考になる数字をいくつか挙げます。
- Anthropic の Contextual Retrieval の記事は、RAG の断片を「通常は数百トークン以下」としています。費用の試算では、800 トークンの断片、8,000 トークンの文書を仮定しています。
- OpenAI のファイル検索(ベクトルストア)の既定値は、断片の最大サイズが 800 トークン、断片同士の重なりが 400 トークンです。サイズは 100〜4096 の範囲で指定でき、重なりは最大サイズの半分以下にする必要があります。
これらは出発点であって、正解ではありません。判断基準は文書の種類で変わります。
- 見出しのある文書(マニュアル、規程、Wiki)は、固定の文字数で機械的に切るより、見出しや段落の境界で切るほうが、意味のまとまりを保てます。
- 表、コード、FAQ は、1 行や 1 問を単位にすると、質問との対応が取りやすくなります。
- 断片には、文書名、見出し、更新日などのメタデータを付けます。絞り込みや出典表示に使えます。
- 重なり(オーバーラップ)は、境界で文が切れる被害を和らげますが、増やすほど索引は大きくなります。
埋め込みと検索:意味と字面を両方使う
断片は埋め込みでベクトルにして検索します。意味検索は、言い回しが違っても近い内容を拾えるのが強みです。一方で、製品コード、固有名詞、日付、専門用語のような「字面が一致してほしい」質問は、キーワード検索のほうが得意です。Microsoft の Azure AI Search のドキュメントも、製品コード、専門用語、日付、人名などはキーワード検索のほうがよく機能する場面があると説明しています。
そこで使うのがハイブリッド検索です。キーワード検索(BM25 など)とベクトル検索を並行して走らせ、結果を一つに統合します。統合には、順位だけを使う Reciprocal Rank Fusion(RRF)がよく使われます。Azure AI Search は、全文検索とベクトル検索を並行実行して RRF で統合すると説明し、OpenAI のファイル検索も、RRF における埋め込みとテキストの重みを調整できます。Qdrant のドキュメントは、重みを調整するなら評価用のデータで決め、なければ既定値のまま使うよう勧めています。
埋め込みを使うときの注意点も二つあります。
- 質問と文書で、埋め込みの指定を使い分けるモデルがあります。Google の Gemini の埋め込みでは、
gemini-embedding-001はRETRIEVAL_QUERY(質問側)とRETRIEVAL_DOCUMENT(文書側)というタスクタイプを組み合わせます。gemini-embedding-2はタスクタイプではなく、テキストに付ける接頭辞で指定します。モデルごとの作法に従わないと、精度が落ちます。 - ベクトルの次元数を減らすと保存量は減りますが、精度は下がりえます。Google のドキュメントは、既定の 3072 次元に対して、768 や 1536 を推奨値として挙げています。
リランキング:多めに取って、絞り直す
リランキングは、検索で取った候補を、質問との関連度でもう一度並べ替える段階です。最初の検索は大量の断片から速く候補を出すのが役目なので、精度は粗めです。そこで、候補を「質問と断片のペア」として読み比べるモデルに通し、順位を付け直します。
Cohere の Rerank API は、質問と文書の一覧を渡すと、関連度の高い順に並べ替え、それぞれに relevance_score を付けて返します。BEIR という検索評価のベンチマーク論文(2021 年)では、再ランキングや遅延相互作用のモデルが平均して最も良い結果を出した一方で、計算コストが高いと報告されています。BM25 は多くの課題で堅実な基準になる、とも述べられています。
目安は「多めに取って、少なく渡す」です。Anthropic の記事では、リランキングの構成で上位 150 件を取り、並べ替えたうえで上位 20 件をモデルに渡しています。同記事は、渡す断片を 20 件にした場合が、10 件や 5 件より良かったとも報告しています。最適値は自分のデータで評価して決めてください。
文脈の付け足し:断片に「どの文書の話か」を書き込む
断片に分けると、「その決定は 2025 年の第 2 四半期の話」「この会社とは A 社のこと」といった周りの情報が失われます。Anthropic の Contextual Retrieval は、この問題に対して、断片ごとに短い説明文を付けてから埋め込み・索引化する方法です。説明文は、文書全体と断片をモデル(記事では Claude 3 Haiku)に渡して作らせます。長さは通常 50〜100 トークンで、断片の先頭に付けます。
Anthropic が示した結果は次のとおりです。指標は、上位 20 件の中に正解の断片が入らなかった割合(失敗率)です。
| 構成 | 失敗率 | 減少 |
|---|---|---|
| 通常の埋め込み(基準) | 5.7% | - |
| 文脈付きの埋め込み | 3.7% | 35% |
| 文脈付きの埋め込み + 文脈付き BM25 | 2.9% | 49% |
| 上記 + リランキング | 1.9% | 67% |
出典:Anthropic「Introducing Contextual Retrieval」。この数字は同社が行った実験での結果で、あなたのデータで同じ効果が出るとは限りません。
費用面では、同記事はプロンプトキャッシュを使うと、文脈付き断片の生成は 100 万文書トークンあたり 1.02 ドルの一度きりの費用になる、と試算しています(800 トークンの断片、8,000 トークンの文書という仮定)。
もう一つ、同記事の指摘が実用的です。知識ベースが 20 万トークン(約 500 ページ)より小さいなら、RAG を作らずに全文をプロンプトに入れる選択肢があります。小さな資料なら、まずこちらを検討すると設計が簡単になります。
プロンプトでの渡し方と出典の示し方
検索で必要な断片が取れても、渡し方が悪いと答えが外れます。
- 件数は絞ります。多ければ良いわけではなく、関係の薄い断片はノイズになります。
- 順序に気をつけます。「Lost in the Middle」の論文は、関連情報が入力の先頭か末尾にあるときに性能が高く、中ほどにあると下がる傾向があると報告しています。長い入力では、重要な断片を先頭か末尾に置く工夫が考えられます。効果はモデルで違うため、確認が必要です。
- 「渡した資料に書かれていないことは、わからないと答える」と指示します。これはハルシネーションを減らすための基本です。ただし指示だけでは完全に防げないので、評価で確かめます。
出典を示す機能は、モデルの API にもあります。Anthropic の Claude API には search_result というコンテンツブロックがあり、検索結果を出典情報(source、title)付きで渡すと、Claude が自分の文書を、Web 検索の結果と同じように引用して答えられます。Messages API では、ツールの結果の中や、ユーザーのメッセージの中に入れられます。この機能を使わない場合でも、断片に ID を振って「根拠にした ID を答えに添える」よう指示し、アプリ側で原文にリンクする方法で、出典を示せます。
評価:検索と回答を分けて測る
直す前に、測れるようにします。ここが一番省略されやすく、一番効果が大きい部分です。
評価は二つに分けます。
| 測るもの | 見ること | 例 |
|---|---|---|
| 検索 | 正解の断片が上位 N 件に入っているか | 上位 20 件に入る割合(Anthropic の失敗率はこの裏返し) |
| 回答 | 渡した断片に基づいて、正しく答えているか | 正確さ、根拠に忠実か、質問に答えているか |
RAG の評価手法を整理した論文に、RAGAS(Es ら、2023 年)があります。この論文は、RAG の評価に複数の観点が必要だと述べ、検索が関連性の高い断片を取れているか、モデルがその断片を忠実に使っているか、生成された回答の質はどうか、という観点を、正解データなしで測る手法を提案しています。
進め方の例です。
- 実際の質問を 30〜50 件集め、それぞれに「正解の断片」と「期待する答え」を付ける。数は目安で、まず小さく始めてよい。
- 検索だけを測る。分け方、ハイブリッド、リランキングを変えるたびに、正解の断片が上位に入る割合を比べる。
- 回答を測る。人が見る、またはモデルに採点させる。採点させる場合は、人の判断とずれていないかを時々確かめる。
- 変更を一つずつ入れ、数字が上がったものだけ残す。
評価(eval)のセットは、本番で見つかった失敗を足し続けると安全網になります。
よくある失敗と直し方
- 全部を一度に変える:原因がわからなくなります。変更は一つずつ入れます。
- 意味検索だけで運用する:型番や固有名詞が外れます。キーワード検索を足すハイブリッドを試します。
- 件数を増やして解決しようとする:ノイズが増えます。まず検索の精度を上げ、件数は評価で決めます。
- 検索が悪いのにモデルを替える:取れていないなら直りません。先に検索の評価を見ます。
- 更新を考えない:索引が古いままだと古い内容で答えます。更新日をメタデータに持ち、再索引の手順を決めます。
まとめの要点
- 症状を「検索の問題」と「回答の問題」に分けて、検索の評価を先に作る。
- 分け方は意味のまとまりを基本にし、既定値(数百〜800 トークン程度)は出発点として扱う。
- 意味検索とキーワード検索を併用し、統合は RRF を基本にする。
- 多めに取ってリランキングで絞る。Anthropic の実験では、文脈付与、BM25、リランキングの組み合わせで失敗率が 5.7% から 1.9% に下がった。ただしこれは同社の条件での結果。
- 資料が 20 万トークン程度より小さいなら、RAG なしで全文を渡す手もある。
- 渡す件数、順序、出典の付け方を決め、わからないときは「わからない」と答えさせる。
- 変更は一つずつ入れ、評価の数字で残すか決める。
出典
- Introducing Contextual RetrievalAnthropic
- Search results(search_result コンテンツブロック)Anthropic
- Retrieval(ファイル検索・チャンク設定・ランキング)OpenAI
- Embeddings(タスクタイプ・次元数)Google
- Hybrid search overview - Azure AI SearchMicrosoft
- Hybrid Queries(RRF・多段検索)Qdrant
- Rerank OverviewCohere
- Lost in the Middle: How Language Models Use Long ContextsarXiv(Liu ら)
- Ragas: Automated Evaluation of Retrieval Augmented GenerationarXiv(Es ら)
- BEIR: A Heterogenous Benchmark for Zero-shot Evaluation of Information Retrieval ModelsarXiv(Thakur ら)
この記事で扱った企業
- Anthropicアンソロピック