Reranker重排序实战:让RAG检索准确率大幅提升的那记临门一脚

📅 2026/9/21 ✍️ 小文 📖 约 1 分钟

向量检索召回了对的文档却排在后面?加入重排序模型是提升RAG质量性价比最高的一步。本文讲原理、选型、集成与效果评估。

在 RAG 系统里,有个让人抓狂的现象:正确答案明明被检索到了,却排在第五、第八位,模型上下文里塞满了不相关的文档,最终答案质量一塌糊涂。 增加 top-k 只会让噪声更多。这时候你需要的不是更强的向量模型,而是重排序(Reranking)。

一、为什么需要重排序

RAG 检索通常分两阶段,叫”召回 + 精排”:

  • 召回(Recall):用向量相似度从海量文档里快速捞出候选(比如 top-100)。追求”别漏掉对的”。
  • 精排(Rerank):对候选做更精细的相关性打分,重排出真正最相关的 top-5。追求”排对顺序”。

向量检索快,但它用的是双塔结构——问题和文档各自编码成向量再比较,丢失了细粒度的交互信息。而重排序模型是交叉编码器(Cross-Encoder),把问题和文档拼在一起送进模型,能捕捉词级交互,相关性判断准得多,代价是慢——所以只用在少量候选上。

二、效果为什么这么明显

向量检索的排序是”近似”的,重排序是”精算”的。把 top-100 的粗排结果交给重排序,取前 5 喂给生成模型,通常能把答案相关性从 60% 出头拉高到 85% 以上。这是 RAG 优化里性价比最高的一步。

三、主流重排序方案选型

方案特点适用
Cohere Rerank托管、效果稳定、按量计费快速上线、无 GPU
BGE-Reranker开源、中文强、可本地部署私有化、成本敏感
Jina Reranker多语言、长文本多语种场景
自训小模型可控、贴合业务有标注数据

中文场景下,BGE-Reranker 系列是常被推荐的平衡之选,可本地跑,无需外发数据。

四、集成示例

from sentence_transformers import CrossEncoder

reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")

def rag_search(query, candidates, top_n=5):
    # candidates: [(doc_id, text), ...] 来自向量召回
    pairs = [(query, text) for _, text in candidates]
    scores = reranker.predict(pairs)
    ranked = sorted(zip(candidates, scores),
                    key=lambda x: x[1], reverse=True)
    return [doc for (doc, _), _ in ranked[:top_n]]

要点:重排序吃的是”问题-文档对”,输入顺序无所谓,但要控制候选数量——太少了没得选,太多了延迟高。经验值是召回 50100,精排取 38。

五、三个容易忽视的调优点

1. 候选数量要调。 召回 20 有时比召回 100 效果更好,因为噪声候选可能干扰重排序。要在你的数据上测。

2. 重排序不是万能药。 如果召回阶段根本没捞到正确文档(召回率低),重排序无能为力。先保证召回率,再优化精排。

3. 延迟预算。 交叉编码器比向量检索慢一到两个数量级。若对延迟敏感,考虑用更小的重排序模型,或对候选分批处理。

六、如何衡量收益

建立一套评估集(问题 + 标准答案文档),分别测量:

  • 召回率:正确文档是否在前 100;
  • MRR / NDCG:正确文档排序的倒数排名与归一化折损;
  • 端到端答案质量:人工或模型打分。

只上重排序、其余不动,通常就能看到 MRR 的明显跃升。

结语

RAG 质量的提升有优先级:分块 > 召回 > 重排序 > 生成调优。重排序处在”投入小、见效快”的甜点区。如果你已经做好了分块和召回,却仍被”对的答案排太靠后”困扰,加一个 Reranker,往往就是那记决定性的临门一脚。

📤 分享到