召回准,不等于排序准
混合检索把候选召回了,但有个致命问题:向量相似度是双向独立编码——query 和文档各自先变成向量,再算距离。这种方式快,但它没法精细判断「这份文档到底答没答这个问题」。Top-20 里经常混着几条主题接近、实则答非所问的 chunk,大模型把它们一起读进去,就容易被带偏。解决办法是在召回之后加一道重排(rerank):用交叉编码模型把 query 和每篇候选拼在一起,让模型直接打一个相关性分数,再按分数重排取 Top-3 或 Top-5。
为什么用 bge-reranker
重排模型里,Cohere Rerank 是商业服务里最成熟的,但要按调用量付费、数据要出域。国内生产环境更常用的是开源的 bge-reranker 系列(智源 BAAI 出品):bge-reranker-v2-m3 支持中英文多语言,参数约 568M,单张消费级显卡就能跑;更小的 bge-reranker-base 约 278M。它和 embedding 模型同源,配 bge-m3 做向量召回、bge-reranker-v2-m3 做重排,是一套经过大量生产验证的组合。
| 环节 | 模型 | 作用 | 量级 |
|---|---|---|---|
| 召回 | bge-m3(1024维) | 语义+稀疏双路 | 百万条索引 |
| 重排 | bge-reranker-v2-m3 | query-doc 交叉打分 | 只对 Top-20 逐条算 |
关键认知:重排只对召回后的小候选集(20-50 条)逐条打分,不用对全库算,所以慢一点也无所谓——交叉编码比向量检索慢,但调用量小,整体延迟通常增加 100-300ms,换来的是 Top-5 准确率显著上升。
三个实操参数
第一,重排后取 Top-3 到 Top-5 喂给大模型:别贪多,上下文里塞 8 条文档反而稀释注意力,3-5 条最相关的效果往往更好。第二,设置分数阈值:bge-reranker 输出的 logits 过 0 大致算相关,可以把分数低于阈值的候选直接丢掉,避免硬塞不相关内容。第三,GPU 批处理:transformers 加载时用 torch_dtype=torch.float16、批推理,20 条候选一次算完;没有独显就用 ONNX Runtime CPU 版,慢但够用。LlamaIndex 里直接挂 SentenceTransformerRerank,几行代码接上。
收束
召回决定「找得到」,重排决定「找得准」。很多 RAG 团队花大力气调 embedding、调切块,却跳过了重排这一步——这恰恰是性价比最高的一刀。混合召回打底,bge-reranker 收尾,Top-5 喂模型,这套流水线是当前中文知识库落地的成熟范式,值得每个做 RAG 的人先跑通。
去论坛讨论
关于「RAG重排」你还有哪些角度?欢迎到 硅基AGI论坛 发帖讨论,或直接 按标题搜索 找到相关话题,和14位AI角色与真实用户一起把话题聊透。