混合检索与重排序:让 RAG 召回更精准

混合检索与重排序:让 RAG 召回更精准
cuizhenjie混合检索与重排序:让 RAG 召回更精准
向量检索很强,但它有一个致命短板:精确关键词搜不到。
用户问”订单号 2026012345 的物流状态”,向量检索返回的是一堆物流规则,而不是这条具体订单的结果。
混合检索解决了这个问题。
纯向量检索的三大短板
问题一:精确关键词丢失
用户问”订单号 2026012345 的物流状态”,向量检索可能返回一堆物流规则,但丢失了精确的订单号。
问题二:专有名词和缩写
“RMA 流程”(退货授权)是专有缩写,向量检索可能无法精确匹配。
问题三:数字和编号
“2026 年春节”中的”2026”被理解成语义,丢失精确匹配。
混合检索架构
1 | 用户提问 → [向量检索 + 关键词检索] → RRF 融合 → 最终排序 |
向量检索 vs 关键词检索
| 维度 | 向量检索 | 关键词检索 |
|---|---|---|
| 擅长场景 | 语义理解、同义词 | 精确关键词 |
| 典型 query | “买了一周的东西还能退吗” | “订单号 2026012345” |
| 短板 | 精确关键词不敏感 | 无法理解语义 |
两者互补,缺一不可。
BM25 算法
核心思想
统计词频(TF)和逆文档频率(IDF),计算关键词重要性:
- 词频(TF):出现越多越相关,但有上限(避免长文档占优)
- 逆文档频率(IDF):越稀有的词越有区分度
- 长度归一化:长短文档公平竞争
BM25 是关键词检索的事实标准,效果好且计算高效。
RRF(倒数排名融合)
核心公式
$$RRF(d) = \sum_{i=1}^{n} \frac{1}{k + rank_i(d)}$$
其中 k=60(通常固定),rank_i(d) 是第 i 路检索中文档 d 的排名。
为什么有效
- 不依赖分数本身,只看排名(避免两路分数不可比的问题)
- 在两路检索中排名都靠前的结果分数更高
- 对异常高分不敏感(不会因为某一路分数特别高而被主导)
示例
1 | 向量检索 Top 5: [文档A, 文档B, 文档C, 文档D, 文档E] |
两阶段检索策略
粗检索:向量 + BM25 → Top 20~50
快速从百万文档中召回候选集,速度优先。
精排序:Reranker → Top 5
对候选集进行精细排序,精度优先。
Reranking:重排序
Bi-Encoder vs Cross-Encoder
| 类型 | 特点 | 适用场景 |
|---|---|---|
| Bi-Encoder | query 和 chunk 分别独立编码,速度快 | 初检阶段 |
| Cross-Encoder | 拼接后一起编码,精度高,能建模交互关系 | 重排序阶段 |
1 | Bi-Encoder: |
主流 Reranker 模型
| 模型 | 中文效果 | 适用场景 |
|---|---|---|
| BGE-reranker-v2-m3 | 稳定 | 预算敏感 |
| Qwen3-Reranker-8B | 优秀 | 复杂意图排序 |
| Cohere rerank-v4.0 | 一般 | 国际化场景 |
中文推荐:BGE-reranker-v2-m3(性价比)或 Qwen3-Reranker-8B(复杂场景)
完整检索流程
1 | 用户问题 → 向量化 → 混合检索(向量+BM25)→ RRF融合 |
每一步都有明确的工程价值:混合检索扩大召回面,RRF 融合平衡两路,Reranker 做最终精细排序。
实战:Python 实现混合检索 + Reranker
1 | from pymilvus import MilvusClient |
RAG 系列总结
7 篇文章,覆盖 RAG 全链路:
| 环节 | 关键技术 |
|---|---|
| 文档解析 | Apache Tika |
| 数据分块 | 递归分块、语义分块 |
| 向量化 | BGE-M3、Qwen3-Embedding |
| 向量存储 | Milvus、HNSW 索引 |
| 混合检索 | BM25 + 向量 + RRF |
| 重排序 | BGE-reranker、Cross-Encoder |
| 元数据 | 引用生成、权限控制 |
相关阅读:








