什么是 RAG 混合检索?如何实现向量检索和关键词检索结合?
- 标签:RAG、混合检索
🏛 业务架构师
RAG 混合检索(向量+关键词)的实现:
为什么要混合:向量检索管"语义"("咋退货"≈"退换货流程"),关键词(BM25)管"精确信号"(订单号、型号、专有名词、"RB-2031 型号"这种字面匹配向量反而抓不住)——两路互补,单路都有盲区。
实现架构四步:
- 双路索引:文档切分后——向量路:Embedding 向量化入向量库;关键词路:分词(中文 IK/jieba)后建 BM25 索引(Elasticsearch,或 Milvus 2.5+ 的内置全文检索,pgvector+pgvector 的 tsvector 也可轻量实现);
- 并行召回:同一 query 同时走向量 Top-K1 与 BM25 Top-K2(并行执行控延迟);
- 结果融合:RRF(倒数排名融合)——
score = Σ 1/(60+rank_i),按各路排名而非原始分数融合,规避两路分数量纲不可比的问题(简单、无需调参、效果稳健,生产首选);也可用加权融合(需调参); - 精排收口:融合后的候选(50~100 条)过 Rerank 模型,取 Top 3~5 进生成。
LangChain 实现:EnsembleRetriever(retrievers=[vector_retriever, bm25_retriever], weights=[0.5, 0.5]) 十几行搞定。
业务建议:混合检索是 RAG 生产化的"必做项"而非优化项——成本低(ES 或向量库自带能力)、收益确定(尤其企业知识库充满编码与行话)。进阶:对 query 做意图分类动态调两路权重(带单号的路走关键词、描述性问走路向量),但初期固定权重+RRF 已够用,别过度设计。
🏗 系统架构师
RAG 混合检索 = 向量语义检索 + BM25 关键词检索并行,结果融合(RRF)。实现方案:
架构与流程:
query ──┬── 向量路:Embedding → ANN 索引(HNSW)→ Top-K₁
└── 关键词路:分词 → BM25(倒排索引)→ Top-K₂
↓
融合层:RRF(倒数排名融合)→ 去重 →(Rerank)→ Top-K为什么两者互补:
- 向量:语义泛化("退货"≈"售后流程")、跨语言、容忍表述差异;盲区:专有名词、型号、错误码、精确数字(Embedding 把这些"语义平均"掉了);
- BM25:精确词匹配("ERR_CONNECTION_RESET" 原样命中)、稀有词高区分度(IDF);盲区:同义改写、跨语言、错别字。
融合实现:
- RRF(默认推荐):
score = Σ 1/(60 + rank_i)——只用排名不用分数,对两路分数量纲天然免疫(免调参);加权版需要分数归一化,谨慎使用; - 存储:ES/OpenSearch 8.x 一套引擎双能力(kNN + BM25)最省运维;或 Milvus(稀疏向量支持)+ 独立倒排;LangChain 的
EnsembleRetriever封装了融合。
工程要点:
- 两路并行 fan-out(不是串行),单路超时降级另一路(P99 保护);
- 权重按 query 特征动态调整(含型号/错误码 → 提关键词权重;自然语言长句 → 提向量权重);
- 融合后接 Rerank 统一精排(两路分数不可比,精排收敛量纲);
- 收益验证:recall@K 对比单路通常 +10~20 个点——上线前后用金标集量化,防"为了架构而架构"。
💻 全栈开发专家
混合检索(Hybrid Search)= 向量语义检索 + BM25 关键词检索并行,结果融合。
为什么结合:两者是互补的强弱项——
- 向量检索:语义泛化好(「退货」匹配「售后退换」),但专有名词/型号/缩写精度差(WSS-4500 被「语义平滑」掉);
- BM25:精确词匹配、低延迟、可解释,但不认识同义改写。
- 融合后:长尾精确 query 和口语语义 query 都有兜底。
实现方案(三种主流):
1. Elasticsearch 8+(推荐,一套栈搞定):
json
GET /docs/_search
{ "retriever": { "rrf": { "retrievers": [
{ "standard": { "query": { "match": { "content": "WSS-4500 故障" } } } },
{ "knn": { "field": "embedding", "query_vector": [0.1,...],
"k": 20, "num_candidates": 200 } }
], "rank_constant": 10, "window_size": 50 } } }2. 向量库自带混合:Milvus(多向量场+RRF/WeightedRanker)、Qdrant(sparse vectors)、Weaviate(BM25 内置)。
3. 应用层自融合(LangChain):
python
from langchain.retrievers import EnsembleRetriever
hybrid = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.4, 0.6]) # 底层自动 RRF融合策略选择:RRF(只看排名,免调参,默认首选)> 归一化加权(可按 query 类型动态调权,需要归一化)。
工程要点:BM25 路要配中文分词器(IK)+ 同义词词典维护;两路检索并行发出(别串行);加 rerank 后效果再上一档(混合管召回,rerank 管排序)。我们上线混合检索后,含型号/编号的 query 命中率提升最明显。