混合RAG检索实战:Dense+BM25+RRF与重排序完整解析

ReRankEval将稠密检索、BM25、RRF融合与LLM重排序串联,并用三项量化指标严格评测RAG检索质量。
ReRankEval是一套开源的混合RAG检索评测管线,由开发者Saurabh Kamal发布。它将稠密向量检索与BM25关键词检索两路召回通过倒数排名融合(RRF)合并——RRF只依赖排名而非原始分数,从而绕开了两种检索分数量纲不兼容的问题。融合后的候选集再经由LLM驱动的重排序器做精细评分,重排序器采用成对输入的cross-encoder逻辑,与追求速度的双塔检索器在本质上不同。项目用真实金融/支付文档和人工标注的测试问题,以Hit Rate、MRR、NDCG三项标准指标对四种检索方案做横向对比,并配套清晰的工程化分层代码结构,覆盖从文档摄入到答案生成的完整链路,为生产级RAG系统的构建提供了可复现的参考范本。
检索增强生成(RAG)的效果好坏,很大程度上取决于检索环节能否把真正相关的文档送到大模型面前。一位开发者 Saurabh Kamal 近期开源了一套名为 ReRankEval 的混合检索管线,并配套发布了完整代码与视频讲解。这套系统把稠密向量检索、BM25 关键词检索、倒数排名融合(RRF)以及 LLM 重排序串联成一条完整链路,并用真实的金融/支付文档做了严谨的对比评测。
本文基于其公开的 Reddit 分享、GitHub 仓库与 YouTube 教程,梳理这套管线的核心设计思路,以及它对构建生产级 RAG 系统的启示。

为什么要做混合检索
单一检索策略各有短板。稠密向量检索(Dense Search)擅长捕捉语义相似性,能理解“分期付款”和“installment”之间的关联,但在精确匹配专有名词、代码、数字时容易失手。BM25 这类稀疏关键词检索则相反——它对精确词项匹配非常敏感,却无法理解同义改写和上下文语义。
混合检索的逻辑就是让两者互补:稠密检索负责语义召回,BM25 负责关键词召回,再把两路结果融合。作者在项目中明确指出,这不是“假设哪种更好”,而是要在同一测试集上公平比较多种策略,用真实数字说话。
RRF:解决分数无法直接比较的难题
把两路检索结果合并时会遇到一个棘手问题:向量检索返回的是余弦相似度或距离分数,BM25 返回的是基于词频的打分,两者量纲完全不同,原始分数根本没法直接相加或比较。
倒数排名融合(Reciprocal Rank Fusion, RRF)正是为此而生。它不看原始分数,只看文档在各路结果中的排名位置。RRF 的核心公式为:
RRF_score(d) = Σ 1 / (k + rank_i(d))
其中 rank_i(d) 是文档 d 在第 i 路检索结果中的排名,k 是一个平滑常数(常取 60)。排名越靠前,贡献的分数越高;多路都靠前的文档会累加出更高的总分,从而在融合后脱颖而出。这种“只认排名不认分数”的做法,巧妙绕开了异构分数无法归一化的难题。
重排序器与检索器的本质区别
很多人把重排序(Reranking)误当成又一次检索,但作者强调两者有根本差异。
检索器(Retriever)要在成千上万的文档中快速筛出候选集,追求的是速度与召回率,通常用双塔结构(bi-encoder)分别编码查询与文档。而重排序器(Reranker)只处理检索器给出的少量候选(比如 Top-K),它把查询和每个候选文档成对输入,联合判断相关性——这正是 cross-encoder 的思路。
项目中采用了 prompt 驱动的 LLM 重排序器,让大模型直接判断每个候选文档与问题的相关程度并重新排序。虽然计算开销大,但由于只作用于少量候选,整体成本可控,而精度提升往往非常明显。
双塔(bi-encoder)与交叉编码器(cross-encoder)的架构差异决定了它们各自的适用场景。双塔模型将查询和文档分别独立编码为向量,查询向量只需计算一次,文档向量可离线预计算后存入索引,因此在百万级文档库中可实现毫秒级近似最近邻(ANN)搜索。代价是查询与文档之间的交互信息完全压缩在两个独立向量中,细粒度语义匹配能力受限。Cross-encoder则将查询与候选文档拼接后一同送入Transformer,自注意力机制可在词元层面捕捉两者之间的精细交互,相关性判断准确率显著更高;但每次推理都需重新前向传播,无法预计算,计算开销与候选数量线性相关。因此工业界普遍采用"双塔粗召回 + cross-encoder精排"的两阶段架构,ReRankEval以LLM代替专用cross-encoder做重排,思路如出一辙。
如何科学评测一条 RAG 管线
这套项目最值得借鉴的地方,是它没有停留在“感觉更准了”的层面,而是引入了三项标准检索评测指标:
- Hit Rate(命中率):正确文档是否出现在返回结果中,衡量最基础的召回能力。
- MRR(平均倒数排名):正确答案排得越靠前,分数越高,衡量首个正确结果的位置。
- NDCG(归一化折损累计增益):综合考虑多个相关文档的排序质量,是最全面的排序评价指标。
作者用五份真实金融/支付文档和十个人工核验过的测试问题,对四种方案做了横向对比:仅向量、仅 BM25、无重排序的混合检索,以及完整的 ReRankEval。最终以一张带真实数字的对比表收尾,让各策略的优劣一目了然。
MRR与NDCG的计算逻辑值得稍作展开。MRR(Mean Reciprocal Rank)对每个查询取首个正确文档排名的倒数,再对所有查询取均值;若正确文档排在第1位得1.0,第2位得0.5,第3位得0.33,依此类推,对"至少找到一个答案且越早越好"的场景最为敏感。NDCG(Normalized Discounted Cumulative Gain)引入了"折损"概念——排名越靠后的相关文档对得分的贡献以对数衰减,并用理想排序的DCG做归一化,因此它能区分"Top-3里有2个相关文档"与"Top-10里有2个相关文档"的质量差异,更适合衡量返回多个候选时的整体排序质量。在RAG场景下,一个系统可能Hit Rate很高(正确文档总在Top-10内)但MRR偏低(正确文档经常排在第8、9位),两个指标结合才能暴露检索排序的真实瓶颈。
生产级代码结构的拆解
除了算法本身,项目还提供了一套清晰的工程化目录结构,把 RAG 管线拆成职责分明的模块:
ingest → vector_store → sparse_retriever → fusion → reranker → pipeline → generate → eval
这种分层把摄入侧(文档解析、切分、建索引)和查询侧(召回、融合、重排、生成)彻底解耦,既方便单独测试每个环节,也便于替换组件。
技术栈方面,项目使用 Python 搭配 Qdrant 作为向量数据库、rank_bm25(BM25Okapi)做稀疏检索、EURI LLM Gateway 提供聊天与嵌入模型、pdfplumber 做 PDF 的页级文本抽取,融合与重排则是作者自定义实现。整套组合覆盖了从文档解析到答案生成的全流程。
对 RAG 开发者的启示
这个开源项目的价值不在于某项独创技术,而在于它把混合检索的完整工程链路与评测方法论整合在了一起。对于正在构建 RAG 应用的开发者,几个要点值得记住:不要迷信单一检索策略;用 RRF 这类排名融合方法规避分数不可比的问题;把重排序当作精度的“最后一公里”;最关键的是,用 Hit Rate、MRR、NDCG 等量化指标做公平对比,而不是凭直觉下结论。
完整代码已在 GitHub 开源,感兴趣的开发者可以克隆下来复现并针对自己的数据集做调整。作者也将其标注为 Part 1,后续可能还有更深入的内容。
相关推荐

支撑阻力七步法:一套可复制的交易策略拆解
一位七年经验操盘手公开其支撑阻力七步交易法:从4小时图标注高低点、设置提醒,到1分钟图寻找突破入场,固定2:1盈亏比。本文完整拆解策略流程并还原55%胜率、2.4盈亏比的真实数据,并理性分析其适用边界。

看懂n8n工作流只需四要素:触发、数据、逻辑、动作
学n8n自动化不要只会抄模板。掌握触发、数据、逻辑、动作四个核心要素,你就能看懂任何工作流、独立搭建并在出错时快速调试,从模板搬运工进阶为真正的自动化构建者。

Browser MCP 登录会话保活:AI Agent 自动化的隐形门槛
AI Agent 接入 Browser MCP 后登录会话过夜失效、重复认证烧掉大量 token,是自动化落地的常见痛点。本文剖析会话持久化难题的本质,并给出持久化 profile、会话解耦、凭证轮换应对等务实思路。