RAG 已经召回一批候选片段,但有用资料排在后面时,可以用 CrossEncoder 重新比较“问题与每个候选”的相关性,再将少量高相关片段交给回答模型。它处理的是已有候选,不能找回根本没有进入候选集的文档,也不能代替租户、版本或权限过滤。
下方使用三条虚构设备说明演示接口,不宣称实测排序提升。本文未下载并运行该模型;代码与模型选择依据为 2026 年 10 月 1 日读取的官方资料,实际速度、内存与相关性需要在自己的环境验证。

CrossEncoder 与向量召回分工不同
向量召回通常先为文档建立表示,收到查询后快速取得候选。CrossEncoder 则同时输入 query 和 passage,对成对文本打分;每个新问题都要重新处理这些候选,所以不应直接把整个大型知识库逐条送去重排。
Sentence Transformers 官方 CrossEncoder 用法提供 predict 的文本对输入和排序示例。本文选择 BAAI/bge-reranker-v2-m3,官方模型卡介绍其多语言重排用途。它是重排模型,不是生成答案的聊天模型。
先固定候选和人工目标
问题为“设备 A 保修多久?”。候选分别是保修说明、充电说明和包装说明;人工目标是保修片段排在前面。若真实任务的正确片段不在候选中,应先修召回或资料,不能用调重排阈值掩盖缺失。
在独立环境安装 python -m pip install sentence-transformers。首次加载需要取得模型权重;记录包版本、模型版本或提交标识。设备和精度配置应按当前模型、PyTorch 环境与资源核对,本例不指定未经验证的 GPU 条件。
成对打分后,保留原始来源 ID
将代码保存为 rerank_demo.py,再运行 python rerank_demo.py。不要先排序文本,再用未排序的 ID 列表拼回结果。
import math
from sentence_transformers import CrossEncoder
query = "设备 A 保修多久?"
candidates = [
{"source_id": "warranty-a", "text": "示例说明:设备 A 保修期为 12 个月。"},
{"source_id": "charging-a", "text": "示例说明:设备 A 首次使用前应充电两小时。"},
{"source_id": "package-a", "text": "示例说明:设备 A 包装内含一条充电线。"},
]
ids = [item["source_id"] for item in candidates]
if len(ids) != len(set(ids)):
raise ValueError("候选来源 ID 重复")
model = CrossEncoder("BAAI/bge-reranker-v2-m3")
pairs = [(query, item["text"]) for item in candidates]
scores = model.predict(pairs, batch_size=3)
if len(scores) != len(candidates):
raise ValueError("分数数量与候选数量不一致")
ranked = []
for item, score in zip(candidates, scores):
value = float(score)
if not math.isfinite(value):
raise ValueError("重排分数不是有限数")
ranked.append({**item, "rerank_score": value})
ranked.sort(key=lambda item: item["rerank_score"], reverse=True)
assert {item["source_id"] for item in ranked} == set(ids)
for item in ranked:
print(item["source_id"], item["rerank_score"], item["text"])
print("selected_context:", ranked[:2])
代码用一个对象同时携带文本、source_id 和新分数,排序后身份仍完整。分数范围会受模型与激活配置影响;本文只在同一次配置中按相关性降序排序,不把分数解释成“答案正确概率”,也不套用其他模型的固定阈值。
怎样判断这轮重排有没有帮助
- 先核对三条来源仍一一对应,没有丢 ID 或把文本接到错误来源。
- 检查实际第一条是否是 warranty-a,且原文直接包含 12 个月。若不是,保存实际结果和模型配置,不写成预期已经兑现。
- 换成“设备 A 包装里有什么”,人工目标改为 package-a;再用原文没有答案的问题,检查是否仍把不支持结论的片段误当依据。
- 真实项目用固定问题集对照重排前后的目标片段位置,并记录新增耗时。不能以一个演示问题排对证明全部业务有效。
selected_context 只是交给回答环节的候选。回答仍需引用来源,并核对数字、条件与版本;相关片段中没有答案时应说明依据不足。
这些情况需要回到上游
- 正确片段未召回:检查入库、分段、查询和检索配置,重排器不能凭空补出它。
- 旧版或越权文档在候选中:先按可信访问上下文和版本条件限制候选,不能让重排分数决定授权。
- 片段过长:核对当前模型的输入长度与截断策略,保留影响答案的条件,不把截掉的后半段当作已处理。
- 延迟不能接受:在不明显损害目标片段覆盖的前提下,测试候选数量和批量大小;不要盲目把全部库送去重排。
下一步是从现有检索日志导出一小组有来源的候选,固定问题与人工目标,运行成对打分并核对来源映射。先验收这一步,再接入完整回答链。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31978.html