交叉编码重排是什么
交叉编码(Cross-Encoder)把「查询 + 候选片段」拼成一条序列送进模型,直接输出相关性分数。因为查询与文档在同一序列里做了完整注意力交互,它的排序质量通常明显优于双塔向量余弦;代价是无法预先计算,只能对已召回的少量候选逐对打分,因此固定在召回之后使用。
基本信息
| 输入 | (查询,候选片段)配对列表 |
|---|---|
| 输出 | 每对的相关性分数,用于重新排序 |
| 位置 | 召回之后、上下文组装之前 |
| 常用模型 | BAAI/bge-reranker 系列、托管重排接口等 |
| 成本 | 与候选条数成正比,候选越多延迟越高 |
召回 → 重排两阶段
召回 → 重排两阶段
import numpy as np
from sentence_transformers import CrossEncoder
reranker = CrossEncoder("BAAI/bge-reranker-base")
candidates = vector_store.search(q_vec, top_k=50) # 粗排
pairs = [(query, c.text) for c in candidates]
scores = reranker.predict(pairs) # 逐对打分
ranked = [c for _, c in sorted(zip(scores, candidates), key=lambda x: -x[0])]
top_docs = ranked[:8] # 进入上下文适用与不适用
- 适用:候选池几十条、需要把真正相关的片段提到前几位
- 适用:召回够但排序差,典型表现是正确答案排在第 5 名之后
- 不适用:全库检索,逐对打分的计算量无法承受
- 不适用:候选池本身没召回正确答案,重排只能在错集合里排序
- 可选:托管重排接口省去部署成本,但要注意数据出域与调用限流
与向量检索的差别
| 对比项 | 双塔向量 | 交叉编码 |
|---|---|---|
| 是否可预计算 | 文档向量可预计算并建索引 | 不能,必须在线逐对计算 |
| 排序质量 | 中等,受表示能力限制 | 较高,查询与文档充分交互 |
| 延迟 | 单次查询毫秒级 | 与候选数成正比,通常几十毫秒到数百毫秒 |
| 典型位置 | 召回阶段 | 精排阶段 |
重排分数与向量分数不在同一量纲:依赖分数阈值做判断时,以重排分数为准单独校准,不要沿用向量相似度的经验阈值。
上线顺序
- 先把召回率做上去:正确答案进不了候选池,重排再好也无从发挥
- 再加重排并单独记录排序指标,确认前几位命中率确实提升
- 然后压缩进入上下文的条数,观察答案完整性是否随之下降
- 最后再调生成提示词,避免多层同时改动导致结论无法归因
- 重排服务单独部署与限流,防止生成侧流量把它拖垮