016、RAG中的重排序与过滤机制
💡 核心导读:上一篇咱们聊了混合检索,把稀疏和稠密向量组合起来,确实能召回更多相关文档。但有个头疼的问题:召回的Top-K里,总有几篇“滥竽充数”的,或者排序靠前的文档其实相关性一般。这就是今天要解决的——检索后处理。重排序模型(Cross-encoder)能精打细算地重新打分,过滤机制能剔除噪声,去重能避免信息冗余。咱们直接上代码和原理,看看如何让LLM吃到“干净”的上下文。
文章目录
- 016、RAG中的重排序与过滤机制
- 一、核心原理:为什么检索后还需要重排序?
- 1. 检索器的“粗糙”本质
- 2. 重排序的“精排”逻辑
- 3. 过滤与去重的必要性
- 二、实战:用Cross-encoder实现重排序
- 1. 环境准备与模型选择
- 2. 核心代码:重排序流水线
- 3. 性能优化:批量预测与缓存
- 三、过滤机制:剔除噪声与低分文档
- 1. 基于阈值的硬过滤
- 2. 基于统计的异常过滤
- 四、去重策略:消除语义冗余
- 1. 基于向量相似度的去重
- 2. 基于Jaccard相似度的轻量去重
- 五、架构设计:完整检索后处理流水线
- 1. Mermaid流程图:从检索到生成的完整链路
- 2. 完整流水线代码
- 六、踩坑与优化建议
- 1. 常见错误:重排序模型与检索器不匹配
- 2. 阈值调优:用验证集找最佳值
- 3. 去重误杀:小心“近似但不同”的信息
- 📚 参考资料
- 🎯 下期预告
一、核心原理:为什么检索后还需要重排序?
1. 检索器的“粗糙”本质
咱们得先正视一个问题:无论是BM25还是稠密检索(Dense Retrieval),它们本质上都是“近似匹配”。稠密检索用余弦相似度算向量距离,但向量空间里“近”不等于“语义相关”。比如用户问“如何部署微服务”,检索器可能召回一篇“微服务架构设计”的文章,虽然向量距离近,但用户要的是“部署”步骤,不是“设计”理论。
我的踩坑经历:去年做客服问答系统,用稠密检索召回Top-10,前3篇里经常混入“产品介绍”而非“故障解决”的文档。LLM生成时被误导,输出了一堆无关内容。后来加了重排序,准确率直接提升20%。
2. 重排序的“精排”逻辑
重排序模型(通常是Cross-encoder)的核心思路是:把用户查询和每个候选文档拼接成一个文本对,输入一个Transformer模型,直接输出相关性分数(0到1之间)。这和检索器(Bi-encoder)完全不同:
| 对比维度 | Bi-encoder(检索器) | Cross-encoder(重排序器) |
|---|---|---|
| 输入方式 | 查询和文档分别编码 | 查询+文档拼接成对 |
| 计算效率 | 高(可预计算文档向量) |