Rerank(重排序)是检索链路的第二道排序:先用向量或关键词召回一批候选,再用重排序模型逐条打分,把最相关的几条放进大模型上下文。它解决的是“召回不少、但前排不准”的问题,不能解决“根本没召回”的问题。
本文从端点与鉴权、请求与响应,讲到 top_n 与候选集、向量检索集成、延迟降级、常见错误和评测指标。模型与价格以站内模型价格为准。
说明:Cohere、Jina AI、BAAI、阿里云等名称归其权利人所有,本文仅用于技术说明。中商起航 AI 网关与上述厂商无隶属关系,接口、模型与计费以站内说明为准。
一、重排序在检索链路中的位置
典型的 RAG 检索分三段:召回、重排、生成。召回追求快和全,重排追求准,生成只使用筛好的上下文。
| 阶段 | 典型方法 | 输入 | 输出 | 主要指标 |
|---|---|---|---|---|
| 召回 | 向量检索、BM25、混合检索 | 用户查询 | 30–100 条候选 | Recall@k |
| 重排 | Rerank 模型 | 查询 + 候选集 | 5–10 条 | nDCG@10 |
| 生成 | 大语言模型 | 重排后的上下文 | 回答 | 正确率、忠实度 |
重排模型通常是交叉编码器,把查询和每篇文档一起读并输出相关性分数,比向量相似度更准,也更慢。它适合放在召回之后,而不是替代召回。
二、接口、鉴权与请求参数
中商起航 AI 网关的重排序端点是:
POST https://ai.zhongshangqihang.com/v1/rerank
鉴权使用 Authorization: Bearer <key>,请求体为 JSON。网关也兼容 /rerank 路径。Key 的创建与安全配置见另一篇教程。
| 参数 | 必填 | 说明 |
|---|---|---|
model |
是 | 重排序模型名,以站内模型列表为准 |
query |
是 | 用户查询,不能为空 |
documents |
是 | 候选文档数组,通常为字符串;对象结构各上游不同 |
top_n |
否 | 返回条数;建议显式设置,不要依赖默认值 |
return_documents |
否 | 是否在结果中带回文档内容 |
max_chunk_per_doc |
否 | 长文档分块上限,具体支持情况看上游 |
overlap_tokens |
否 | 分块重叠 token 数,按上游文档确认 |
多数实现接受字符串数组,也有平台接受带 text 字段的对象。接入前先用一条最小请求确认格式,不要直接批量迁移。
三、请求与响应:Python 与 curl
Python 示例,先召回再重排:
import os
import requests
api_key = os.environ["RERANK_API_KEY"]
base_url = "https://ai.zhongshangqihang.com/v1"
documents = [
"试用期为 14 天,到期前可申请延长。",
"支持对公转账和平台担保交易。",
"发票在付款后 3 个工作日内开具。",
]
resp = requests.post(
f"{base_url}/rerank",
headers={"Authorization": f"Bearer {api_key}"},
json={
"model": "你的重排序模型名",
"query": "试用期多久?",
"documents": documents,
"top_n": 2,
"return_documents": False,
},
timeout=20,
)
resp.raise_for_status()
for item in resp.json()["results"]:
print(item["index"], item["relevance_score"], documents[item["index"]])
同样的请求用 curl:
curl "https://ai.zhongshangqihang.com/v1/rerank" \
-H "Authorization: Bearer $RERANK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "你的重排序模型名",
"query": "试用期多久?",
"documents": ["试用期为 14 天。", "支持对公转账。"],
"top_n": 2
}'
响应里的 results 已按相关性降序排列,每项包含:
index:文档在原始documents数组中的下标,不是排名。务必用它回查原文。relevance_score:相关性分数,通常归一化到 0 到 1,但不是概率,也不代表线性差距。document:仅当return_documents为 true 时可能返回,结构随上游不同。usage:token 用量,用于账单核对和成本分析。
不要把 relevance_score 直接当阈值复用。换模型、换语言、换文档类型后,分数分布会变,阈值要重新标定。
四、top_n 与候选集大小
top_n 是返回条数,候选集大小是送给模型的文档数量,两者不是一回事。常见误区是把 top_n 设得很大,却只召回十几条文档,重排没有发挥空间。
| 候选集大小 | 适用场景 | 相对延迟 | 注意事项 |
|---|---|---|---|
| 20–30 | 小知识库、低延迟问答 | 低 | 召回上限低,容易漏答案 |
| 50 | 多数 RAG 的起点 | 中 | 先跑评测再增减 |
| 100 | 文档多、查询表达多样 | 较高 | 注意单文档长度和截断 |
| 200 以上 | 高价值查询、离线评测 | 高 | 成本和延迟都要单独评估 |
实践建议:候选集从 30–50 条起步,top_n 设 5–10 条。候选集太小会限制上限,太大则延迟和费用上升,还可能把噪声带进上下文。上游对文档数和单文档长度可能有上限,超长文档会被截断,截断位置可能正好丢掉关键句。
另外,部分上游在省略 top_n 时只返回 1 条结果。生产代码里始终显式传 top_n,不要依赖默认行为。
五、与向量检索集成
重排不是孤立的一步,接入顺序会影响效果和成本。推荐流程:
- 对用户查询做必要改写,补全指代和省略。
- 用 Embedding 模型把查询转成向量。
- 向量检索召回前 30–50 条,同时可并行跑关键词或 BM25 召回。
- 合并两路结果,按文档 ID 去重。
- 在送重排前做权限和元数据过滤,避免把无权文档发给模型。
- 调用 Rerank API,取
top_n为 5–10 条。 - 设分数阈值或条数上限,拼进上下文交给生成模型。
几个容易忽略的点:
- 先过滤再重排:权限、租户、语言、版本应在召回阶段或重排前过滤,不要等生成后再删。
- 保留稳定 ID:重排返回的是下标,业务侧要能通过下标映射回文档 ID、标题和 URL。
- 块级重排:RAG 通常重排的是切块,不是整篇文档。切块太长会稀释相关性,太短会丢上下文。
- 混合召回:专有名词、型号、编号靠关键词更稳,语义问题靠向量更稳,两路合并后再重排通常比单路好。
六、延迟、超时与降级
重排的延迟大致随“文档数量 × 文档长度”增长。100 条短文档通常很快,几百条长文档就会明显变慢。上线前至少测三个数:候选集 30 条、50 条、100 条时的 P50 和 P95 延迟。
工程上建议:
- 给 Rerank 请求设独立超时,常见起点是 10–30 秒,再按实测收紧。
- 只对 429 和 5xx 做有限次退避重试,401、403、422 不要重试。
- 重排超时或失败时,降级为向量召回顺序,不要让整个问答直接失败。
- 对高频、低变化的查询做结果缓存,缓存键至少包含查询、文档 ID 和模型名。
- 向量召回和关键词召回并行执行,合并后再重排,减少串行等待。
- 重排接口一次性返回完整结果,不支持流式,不要按流式接口设计前端。
延迟仍然偏高时,先减候选集和文档长度,再考虑换更小的模型。直接上更大模型不一定划算,尤其是召回质量本身不高的时候。
七、常见错误与排查
| 状态码或现象 | 常见原因 | 处理 |
|---|---|---|
| 400 / 422 | query 为空、documents 为空、JSON 结构错误 |
检查必填字段和数组类型 |
| 401 | Key 无效、过期或请求头缺失 | 核对 Authorization 与 Key 状态 |
| 403 | Key 无模型权限或账户受限 | 检查模型范围和账户状态 |
| 404 | 模型名或端点路径错误 | 核对 /v1/rerank 与模型列表 |
| 429 | 并发或额度触发限流 | 退避重试,检查额度与速率限制 |
| 500 / 502 / 504 | 上游异常或超时 | 有限重试,失败后走降级路径 |
网关会校验 query 和 documents,为空时直接返回参数错误。排查时先看响应体的 message,再对照请求日志;不要把 400 当成网络问题反复重试。
八、评测:别只看“感觉更准了”
重排上线前,先准备一个小型标注集:100–300 条真实查询,每条标出 1–3 篇相关文档。没有标注条件时,至少人工抽检 50 条,记录两种排序。
| 指标 | 看什么 | 怎么用 |
|---|---|---|
| Recall@50 | 候选集里有没有正确答案 | 判断召回上限,低了先修召回 |
| nDCG@10 | 前排排序质量 | 对比加不加重排 |
| MRR | 第一条相关结果的位置 | 适合问答型查询 |
| 回答正确率 | 生成结果是否正确 | 端到端验证 |
| P95 延迟 | 慢请求有多慢 | 决定候选集和超时 |
| 单查询成本 | 每次问答的检索开销 | 结合价格页估算 |
评测时保持变量固定:同一批查询、同一个召回结果、同一个 top_n,只切换是否重排或切换模型。线上再做小流量 A/B,观察正确率、无答案率和延迟。若重排后效果反而下降,优先检查候选集是否漏召回、文档是否被截断、模型是否适合中文,以及阈值是否照搬了其他场景。
九、常见问题
Rerank 能替代向量检索吗?
不能。重排只能在已有候选里重新排序,无法找回没被召回的文档。召回负责覆盖面,重排负责前排精度。
top_n 应该设多少?
给大模型拼上下文时,5–10 条是常见起点;后面还有业务规则筛选,可以设 20–50 条。最终以评测为准。
候选集越大越好吗?
不是。候选集变大能提高召回上限,但延迟、费用和噪声同步上升。先从 30–50 条起步,用 Recall@50 和 nDCG@10 判断是否扩大。
为什么加了重排效果反而变差?
常见原因有四个:候选集没召回正确文档、切块太长或太碎、模型与语言不匹配、阈值照搬其他场景。逐项排查,不要只换模型。
Rerank 接口支持流式返回吗?
不支持。重排需要看完整个候选集才能给出完整排序,通常一次性返回。前端按普通 JSON 请求处理,并设置合理超时。
