我在 RAG 流水线中加入了一个重排序器 —— 结果搞砸了一切
我在我的 RAG 流水线中加入了一个重排序器 (reranker)。它立刻让我的测试全部失败了。
在第 2 版中,我使用了结合 FAISS 和 BM25 的混合检索 (hybrid retrieval)。它通过了全部 19 个测试问题。随后,为了提高精度,我加入了一个交叉编码器 (cross-encoder) 重排序器。
原理很简单:
- 第一阶段:使用快速检索获取一组广泛的候选集。
- 第二阶段:使用智能重排序器选出最佳结果。
实现只花了 20 分钟。但它立刻导致 19 个测试中的 2 个失败了。
失败的原因在于数据格式。我的数据包含类似这样的密集型表格块: "Company: Zentara Robotics | CEO: Iris Kallas | Employees: 287"
交叉编码器模型是在自然语言段落上训练的。当它看到表格行时,给出的评分非常低。它认为这个数据块是不相关的。
混合检索找到了答案,但重排序器却把它丢弃了。
我尝试了 7 种不同的方法来修复这个问题:
- 使用更大的候选池。
- 融合重排序器和检索器的评分。
- 使用排名融合 (rank fusion)。
但都没有奏效。重排序器的评分太低了,以至于压倒了其他所有因素。模型不仅仅是降低了排名,它是在主动拒绝这种表格格式。
我不再试图从数学层面去修复,而是改变了结构。
我没有让重排序器决定一切,而是保护了我的最佳结果。我采用了一种“保底位” (guaranteed slot) 策略:
- 如果你想要前 3 个结果,请保留第一阶段的前 2 个结果。
- 仅使用重排序器来挑选第 3 个结果。
这确保了混合检索的结果能留在最终列表中。重排序器只负责优化剩余的席位。
结果:19/19 个测试全部通过。
经验教训:
- 重排序器并非即插即用的升级。它们可能会损害结构化或表格数据的性能。
- 你的评估集是你的安全网。如果没有这 19 个测试,我就会发布一个有缺陷的系统。
- 保护有效的方法。如果你的第一阶段检索效果很好,不要让重排序器覆盖它。
在考虑使用重排序器之前,先构建一个强大的检索器。
Optional learning community: https://t.me/GyaanSetuAi
