RRF和Cross-Encoder rerank怎么实现
很好这两个东西基本就是现代 RAG 检索系统的“标配升级”。我给你直接讲清楚RRF 是融合算法Cross-Encoder 是重排序模型两者通常一起用先召回再精排我分开讲并给你可直接用的实现方式。一、RRFReciprocal Rank Fusion 它解决什么问题当你有多个检索器比如BM25 排名Embedding 排名它们的分数尺度不同不能直接相加。RRF 的思路是不看分数只看“排名” RRF 公式对每个文档[score \sum \frac{1}{k rank}]通常k 60常用经验值意思是排名越靠前 → 得分越高排名越靠后 → 影响迅速变小 为什么它好优点不需要统一分数非常稳定工业界常用对异常值不敏感 RRF 实现示例假设你已经有bm25_results[doc_id1,doc_id2,...]emb_results[doc_id3,doc_id2,...]实现fromcollectionsimportdefaultdictdefrrf_fusion(rank_lists,k60): rank_lists: List of ranked lists scoresdefaultdict(float)forrank_listinrank_lists:forrank,doc_idinenumerate(rank_list):scores[doc_id]1/(krank1)# 按分数排序returnsorted(scores.items(),keylambdax:x[1],reverseTrue)使用final_resultsrrf_fusion([bm25_top,embedding_top])二、Cross-Encoder Rerank这是更高级的。 它和普通 embedding 有什么区别Bi-Encoder普通 embeddingquery → 向量 doc → 向量然后算相似度。优点快可预计算可扩展缺点语义粗糙Cross-Encoder它是[query doc] 一起输入模型模型直接输出这个文档和 query 的相关性分数它会看到完整上下文做深度交互效果远好于 embedding但不能预计算速度慢只能用于 rerank Cross-Encoder 实现用 sentence-transformerspipinstallsentence-transformers示例代码fromsentence_transformersimportCrossEncoder# 加载模型modelCrossEncoder(cross-encoder/ms-marco-MiniLM-L-6-v2)defcross_rerank(query,documents):pairs[(query,doc)fordocindocuments]scoresmodel.predict(pairs)rankedsorted(zip(documents,scores),keylambdax:x[1],reverseTrue)returnranked 使用方式标准流程第一步召回快BM25 Embedding 取 Top 50第二步Cross-Encoder 精排top_candidates[...]final_rankedcross_rerank(query,top_candidates)三、工业标准架构现在主流系统是1️⃣ BM25 召回 100 2️⃣ Embedding 召回 100 3️⃣ RRF 融合 4️⃣ 取 Top 20 5️⃣ Cross-Encoder 重排 6️⃣ 取 Top 5 7️⃣ 交给 LLM这是非常成熟的结构。四、RRF vs Cross-Encoder 区别项目RRFCross-Encoder类型融合算法深度模型是否需要训练不需要需要预训练是否慢很快较慢精度中等很高用途融合多检索器精排五、推荐你怎么做如果你做代码检索Bug 分析RAG 系统建议结构BM25 Embedding ↓ RRF ↓ Cross-Encoder ↓ LLM六、性能建议RRF 用在前面Cross-Encoder 只对少量候选20~50条不要对全库用 Cross-Encoder太慢