RAGの検索ステップを設計するとき、「ベクトル検索だけで十分」と思いがちだが、固有名詞や製品コードなどキーワード一致が重要なクエリでは取りこぼしが起きる。
一方で、キーワード検索だけでは言い換えに弱い。ハイブリッド検索とリランキングは、このギャップを埋める定番の2段構えだ。
この記事では、初心者向けに仕組み・使いどころ・設計の勘所を整理する。
結論:検索は「広く取る」→「精度で並べ替える」の2段階
| 観点 | 内容 |
|---|---|
| ハイブリッド検索 | ベクトル検索(意味)とキーワード検索(語の一致)を組み合わせて候補を集める |
| リランキング | 第1段階で集めた候補を、より精密なモデルで再スコアリングして順位を付け直す |
| なぜ必要か | ベクトル単体は固有名詞・略語・数値に弱く、キーワード単体は言い換えに弱い |
| 典型パイプライン | ハイブリッドで top 50〜100 取得 → リランカーで top 5 に絞る → LLMへ |
| 覚え方 | 「釣り網を広げてから、目利きで選別する」 |
ポイント:ハイブリッド検索とリランキングは別物だ。前者は候補の取りこぼしを減らす、後者は順位の精度を上げる。多くの本番RAGでは両方を組み合わせる。
ベクトル検索だけでは何が起きるか
ベクトル検索は「意味の近さ」で文書を探す。自然文の質問に強い一方、次のような弱点がある。
| クエリの種類 | ベクトル検索の弱点 | 具体例 |
|---|---|---|
| 固有名詞・製品名 | 埋め込み空間で「似た意味」に引っ張られる | 「ERR_CONNECTION_REFUSED」のエラーコード検索 |
| 略語・型番 | 学習データに少ない語はベクトルが不安定 | 「pgvector の HNSW パラメータ」 |
| 完全一致が必要な語 | 意味は近いが語が違う文書が上位に来る | 社内で定義した用語IDの検索 |
| 数値・日付 | 埋め込みでは数値の大小関係が保持されにくい | 「2024年4月以降の変更履歴」 |
逆に、キーワード検索(BM25 などの全文検索)は語の一致に強いが、「退勤手順」と「業務終了時のチェックリスト」のような言い換えには弱い。
この2つの弱点を補い合わせるのがハイブリッド検索だ。
ハイブリッド検索とは
ハイブリッド検索(hybrid search)は、複数の検索方式のスコアを組み合わせて、最終的な候補リストを作る手法の総称だ。
典型的には次の2つを併用する。
[ベクトル検索] クエリ埋め込み → コサイン類似度で Top-N
↓ スコアを融合
[キーワード検索] BM25 / 全文検索で Top-N
↓
[融合スコア] 重み付き合算 or RRF で統合ランキング
↓
統合 Top-K 候補
キーワード検索側:BM25
BM25(Best Matching 25)は、全文検索で最も広く使われるランキング関数のひとつだ。単語の出現頻度と文書長を考慮し、「クエリの語がどれだけマッチするか」でスコアを付ける。
| 特徴 | 説明 |
|---|---|
| 強み | 固有名詞・エラーコード・型番など語の一致が重要な検索 |
| 弱み | 同義語・言い換えには対応できない |
| 実装 | Elasticsearch、OpenSearch、PostgreSQL の tsvector、多くのベクトルDBのハイブリッド機能 |
スコアの融合方法
2つの検索結果のスコアはスケールが異なる(コサイン類似度は0〜1、BM25は0〜∞に近い)。そのまま足し算できないため、次のような融合手法が使われる。
| 手法 | 概要 | 向いている場面 |
|---|---|---|
| 重み付き線形結合 |
final = α × vector_score + (1-α) × bm25_score(正規化後) |
αをチューニングできる環境 |
| RRF(Reciprocal Rank Fusion) | 順位の逆数を足し合わせる。スコアのスケールに依存しない | デフォルトの無難な選択肢 |
| 最大スコア採用 | どちらか高い方を採用 | シンプルなPoC |
RRFの計算式(概念):
RRF_score(d) = Σ 1 / (k + rank_i(d))
rank_i(d) は検索方式 i における文書 d の順位、k は定数(多くの実装で 60)。Weaviate、Elasticsearch、Pinecone などが RRF または同等の融合をサポートしている。
重み α の目安
| データの性質 | vector 重み | keyword 重み | 理由 |
|---|---|---|---|
| FAQ・手順書(自然文中心) | 0.7〜0.8 | 0.2〜0.3 | 言い換えクエリが多い |
| APIリファレンス・エラーコード集 | 0.3〜0.5 | 0.5〜0.7 | 固有名詞・コードの一致が重要 |
| 汎用ナレッジベース | 0.5 | 0.5 | まずは均等から始めて評価で調整 |
最初から最適値を当てる必要はない。テストクエリ20件程度で Recall@K を測り、α を動かして比較するのが現実的だ。
リランキングとは
リランキング(reranking)は、第1段階の検索で得た候補リストを、より精密なモデルで並べ替え直す処理だ。
[第1段階:高速・粗い検索]
ハイブリッド検索で Top-50〜100 を取得(速度優先)
[第2段階:精密・遅いリランキング]
クロスエンコーダ等で (クエリ, 文書) ペアを再スコアリング
→ Top-5〜10 に絞る
[第3段階:生成]
上位チャンクを LLM のコンテキストに渡す
なぜ2段階にするのか
| 段階 | モデル | 速度 | 精度 |
|---|---|---|---|
| 第1段階(検索) | 埋め込みモデル(バイエンコーダ) | 高速(全件に対してANN) | 粗い |
| 第2段階(リランク) | クロスエンコーダ | 遅い(候補ペアのみ) | 高精度 |
埋め込みモデル(バイエンコーダ)はクエリと文書を別々にベクトル化するため高速だが、両者の相互作用を直接見られない。クロスエンコーダはクエリと文書を同時に入力し、関連度を直接予測するため精度が高いが、全件に適用すると遅すぎる。
だから「まず広く候補を取り、上位候補だけ精密に並べ替える」という設計になる。
クロスエンコーダのイメージ
[バイエンコーダ(第1段階)]
query → embed(query) ─┐
├─ cosine similarity → スコア
doc → embed(doc) ─┘
※ query と doc は独立に処理
[クロスエンコーダ(第2段階)]
[query ; doc] → Transformer → relevance score
※ query と doc を同時に見て関連度を予測
代表的なオープンソースのリランキングモデル:
| モデル | 提供元 | 特徴 |
|---|---|---|
BAAI/bge-reranker-v2-m3 |
BAAI | 多言語対応、RAGで広く使われる |
cross-encoder/ms-marco-MiniLM-L-6-v2 |
Sentence Transformers | 英語向け、軽量 |
| Cohere Rerank API | Cohere | マネージドAPI、多言語 |
リランキングの効果(公開ベンチマークの傾向)
BEIR などの情報検索ベンチマークでは、ベクトル検索にリランキングを追加すると nDCG@10 が 5〜15ポイント程度改善するケースが報告されている(データセット・モデルにより変動)。絶対値ではなく「第1段階だけより順位精度が上がる傾向」として理解すればよい。
ハイブリッド検索 + リランキングの全体パイプライン
実務でよく見る構成を図示する。
[インデックス構築]
ドキュメント
→ チャンク分割
→ 埋め込みベクトル化 → ベクトルDBへ
→ 全文インデックス(BM25)→ 検索エンジンへ
※ 同一チャンクIDで両方を紐付ける
[検索(オンライン)]
ユーザーの質問
├─ ベクトル検索 Top-50
└─ BM25 検索 Top-50
↓ RRF で融合 → 統合 Top-50
↓ クロスエンコーダでリランク → Top-5
↓ LLM コンテキストへ
| パラメータ | 初心者向けの初期値 | 調整の目安 |
|---|---|---|
| 第1段階の取得数 | 50〜100 | リコール不足なら増やす(レイテンシとのトレードオフ) |
| リランク後の採用数 | 3〜5 | LLMのコンテキスト長とコストで決める |
| ハイブリッドの α | 0.5(均等) | 評価セットで Recall@10 を見ながら調整 |
| リランクの閾値 | スコア 0.5 以上(モデル依存) | 全件下回る場合は「関連情報なし」と返す |
実装例:Python(概念コード)
以下は sentence-transformers の CrossEncoder を使った最小例だ。本番ではベクトルDBのハイブリッドAPIを使う方が一般的。
from sentence_transformers import CrossEncoder
# 第1段階で得た候補(ハイブリッド検索の結果を想定)
query = "PostgreSQL でベクトル検索のインデックスを作る方法"
candidates = [
"pgvector では HNSW インデックスを CREATE INDEX で作成できる。",
"MySQL の全文検索インデックスの設定手順について説明する。",
"HNSW は近似最近傍探索のアルゴリズムで、pgvector がサポートしている。",
"Redis のキャッシュ戦略について解説する。",
]
# 第2段階:クロスエンコーダでリランキング
model = CrossEncoder("BAAI/bge-reranker-v2-m3")
pairs = [(query, doc) for doc in candidates]
scores = model.predict(pairs)
# スコア順に並べ替え
ranked = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True)
for doc, score in ranked[:3]:
print(f"{score:.3f} {doc}")
出力イメージ:
0.892 pgvector では HNSW インデックスを CREATE INDEX で作成できる。
0.756 HNSW は近似最近傍探索のアルゴリズムで、pgvector がサポートしている。
0.124 MySQL の全文検索インデックスの設定手順について説明する。
「MySQL」はキーワード的には「インデックス」でマッチするが、リランカーはクエリの意図(PostgreSQL + ベクトル)を考慮して正しい文書を上位に置く。
主要ツールのハイブリッド・リランク対応
| ツール | ハイブリッド検索 | リランキング |
|---|---|---|
| Weaviate | BM25 + ベクトルの RRF 融合(組み込み) |
reranker モジュール(Cohere等) |
| Elasticsearch |
dense_vector + BM25 の RRF |
Learning to Rank、外部リランカー連携 |
| Pinecone | スパース+デンスベクトルのハイブリッド | 外部リランカーと組み合わせ |
| Qdrant | 名前付きベクトル + 全文検索(v1.10+) | 外部リランカーと組み合わせ |
| LangChain |
EnsembleRetriever で複数 Retriever 融合 |
CrossEncoderReranker 等 |
自前実装する場合は、候補IDの重複排除(ベクトルとBM25で同じチャンクが両方ヒット)を忘れずに行う。
実装チェックリスト
- 第1段階と第2段階で同じチャンクIDをキーに候補を管理しているか
- ハイブリッドの融合方式(RRF or 重み付き合算)と α を設定ファイルに明記しているか
- 第1段階の取得数(50〜100)とリランク後の採用数(3〜5)をレイテンシ目標から逆算しているか
- リランカーのスコアに閾値を設け、全件下回る場合は「関連情報なし」フローにするか
- テストクエリ20件で、ベクトル単体 vs ハイブリッド vs ハイブリッド+リランクのRecall@K を比較しているか
- リランカーモデルのレイテンシ(候補50件で何msか)を計測し、SLA内に収まるか確認しているか
失敗パターン
パターン1:ハイブリッドにしたが融合パラメータを固定したまま
データの性質(FAQ vs APIリファレンス)で最適な α が変わるのに、0.5 固定のまま運用する。
→ 対策:四半期ごとに評価セットで α を再チューニングする。データ追加時も再評価。
パターン2:リランクの候補数が少なすぎて正解が第1段階で落ちる
top_10 しか取らず、正解チャンクが11位以下にいる。
→ 対策:第1段階は top_50 以上。リランクは「絞る」処理であり「広げる」処理ではない。
パターン3:リランカーを全件に適用してレイテンシ爆発
10万件のインデックス全件にクロスエンコーダをかける。
→ 対策:必ず第1段階で候補を絞ってからリランク。全件リランクは現実的でない。
パターン4:BM25とベクトルで別チャンク分割
全文インデックスとベクトルDBでチャンク境界がずれ、融合時に同一文書の断片が別IDになる。
→ 対策:チャンク分割は1箇所で行い、同じIDで両方のインデックスに登録する。
まとめ
- ハイブリッド検索はベクトル(意味)とキーワード(語の一致)を組み合わせ、取りこぼしを減らす。
- リランキングは第1段階の候補を精密モデルで並べ替え、LLMに渡すチャンクの質を上げる。
- 典型構成は「ハイブリッドで top 50 → リランクで top 5 → LLM」。
- RRF はスコア融合の無難なデフォルト。α はデータに応じて評価で調整する。
ベクトル検索の基礎(コサイン類似度・ANN)を理解したうえで、この2段構えを足すと、RAGの検索品質は一段階上がる。
参考リンク
- Weaviate — Hybrid search
- Elasticsearch — Reciprocal rank fusion
- Pinecone — Hybrid search
- Cohere — Rerank
- Sentence Transformers — Cross-Encoders
- BAAI/bge-reranker-v2-m3 — Hugging Face
- BEIR Benchmark
この記事を書いた人✏️@YushiYamamoto
ITPRODX.com代表 / AIアーキテクト
Next.js / TypeScript / n8nを活用した自律型アーキテクチャ設計を専門としています。
日々の自動化の検証結果や、ビジネス側の視点(ROI等)に関するより深い考察は、以下の公式サイトおよびnoteで発信しています。
