Advanced RAG ─ チャンキング・リランキング・HyDE で精度を上げる
結論から言うと、エージェントにRAG(検索拡張生成)を組み込んでも「回答がズレる」「関係ない文書が返ってくる」という問題は、チャンキング・リランキング・HyDEの3手法を組み合わせることで大幅に改善できるとされています。レッスン06で基本を学んだ方は、ここで一段深い技術に進みましょう。
チャンキングとは? ─ 文書の切り方が精度を左右する
RAGでは長い文書を小さなかたまり(チャンク)に分割し、各チャンクの埋め込みを作ってから検索します。切り方には主に3種類があります。
- 固定長チャンキング: 文字数・単語数で機械的に切る。実装は簡単ですが文の途中で切れやすい。
- 再帰的チャンキング: 段落→文→単語の順に自然な区切りを優先して分割する。多くのライブラリのデフォルト。
- セマンティックチャンキング: 話題の転換点で分割する意味重視の手法。精度は高いが処理コストがかかる。
チャンクが大きすぎると無関係な情報が混じり、小さすぎると文脈が失われます。試行の出発点は256〜512トークン程度とされることが多いです。
リランキングとは? ─ 2段階で検索精度を高める
ベクトル検索は高速ですが、常に最も関連度の高い順に並ぶとは限りません。そこで**2段階検索(Two-stage Retrieval)**が有効です。
- まずベクトル検索で上位20〜50件を素早く取得する(速いが粗い)
- クロスエンコーダ(質問と文書をペアで精密に評価するモデル)で上位3〜5件に絞り込む(遅いが精確)
最初の取得には双方向エンコーダ(Bi-encoder)、再ランク付けにはクロスエンコーダを使い分けるのが定石です。Cohereの Rerank APIなどクラウドサービスとして提供されているものもあります。
HyDE ─ 仮説文書で質問と文書のギャップを埋める
**HyDE(Hypothetical Document Embeddings)**は、質問をそのまま埋め込むのではなく「LLMに仮説的な回答文書を生成させてから埋め込む」手法です。
- 質問「RAGとは何か?」の埋め込みは、回答を含む文書の埋め込みと意味的に遠い場合がある
- 代わりにLLMが「RAGとは…という手法で、…に使われる」という仮説文書を生成し、それを埋め込んで検索する
- 仮説文書の内容が正確かどうかは問わない──検索のための橋渡しとして機能すれば十分
# HyDE の擬似フロー
question = "RAGとは何か?"
hypothesis = llm.generate(f"次の質問に回答する文書を作れ: {question}")
embedding = embed(hypothesis) # ← 質問の代わりに仮説文書を埋め込む
chunks = vector_db.search(embedding, top_k=5)
コンテキストへの配置も重要 ─ "Lost in the Middle" 問題
Liu ら(2023)の研究「Lost in the Middle」では、関連文書をコンテキストの中間に置くと精度が落ちることが多くのモデルで確認されています。先頭と末尾にある情報は利用されやすく、中間の情報は見落とされやすいとされます。
実装上の示唆:取得したチャンクをコンテキストに挿入するとき、最も重要なものを先頭か末尾に配置するとよい場合があります。
まとめ
RAGサーベイ論文(arXiv:2312.10997)が整理するように、RAGは「Naive RAG → Advanced RAG → Modular RAG」と進化しています。
| 手法 | 何を改善するか |
|---|---|
| チャンキング | 検索単位の質(無関係情報の混入を減らす) |
| リランキング | 検索順位の精度(クロスエンコーダで再評価) |
| HyDE | クエリと文書の意味的な距離を縮める |
| 配置の工夫 | コンテキスト内での見落とし(Lost in the Middle)を防ぐ |
それぞれ独立して適用できるので、「まずリランキングだけ追加してみる」のように段階的に試すのがおすすめです。