Rerank(重排序)是 RAG 链路里最容易被低估的成本项。它单次调用看起来不贵,但每条用户问题都要跑一遍;候选文档一多,账单就会随查询数和文档量一起放大。

不同厂商的计费单位并不一样:有的按查询,有的按文档,有的按 Token。直接比较“每次调用多少钱”没有意义,必须换算到自己的查询量、候选集和文档长度上。本文拆解计费结构、候选集、缓存与预算测算,不写死单价;具体以站内模型价格和厂商文档为准。

说明:Cohere、Jina、Voyage、BAAI 等名称是其各自权利人的商标,本文仅作技术与计费结构说明。计费单位、限额和价格可能调整,采购前请以官方页面为准。

一、Rerank 在链路里做什么

典型的两阶段检索是:

用户提问
  → 向量/关键词召回 20–200 条候选
  → Rerank 精排,取前 5–10 条
  → 拼接上下文,交给生成模型

Rerank 的输入是“一个查询 + 一批候选文档”,输出相关性分数和排序,不生成文字。它解决的是“正确片段虽然被召回,但排在第十名,直接截断就会丢掉”的问题。

成本位置因此很清楚:每次检索调用一次,有时多次;每条候选都要过模型。重排通常比换更大的生成模型便宜,但不是零成本。

二、三种常见计费口径

计费口径 计费单位 成本随什么增长 常见代表 预算关注点
按查询 一次查询,含一定数量文档 查询次数;长文档切块也计入 Cohere Rerank 切块规则会放大文档数
按 Token 查询 Token 与文档 Token 查询长度、候选数、文档长度 Voyage、Jina 等 查询 Token 会乘以文档数
按文档或按次 每条文档或每次请求 文档条数、请求数 部分托管服务 确认截断和单次上限
自建 GPU 小时与运维 并发、模型大小、利用率 开源 BGE 系列 固定成本,看利用率

Cohere 按 search unit 计费,其价格页的定义是“一次查询,最多 100 条文档”。但长文档会被切块,切块分别计入文档数。所以“100 条文档”不等于“100 条计费文档”,长文档多的知识库要按切块后的数量估。

Voyage 按 Token 计费,公式是:查询 Token × 文档数 + 所有文档 Token 之和。查询越长、候选越多,乘数效应越明显。响应里的 usage.total_tokens 可以直接对账。其接口单次最多 1000 条文档,超长输入默认可能被截断,截断规则要提前确认。

Jina 同样按输入总 Token 计费,查询和文档都算;官方说明失败请求不计费,并提供余额阈值自动充值。免费额度用完后转为付费,具体以账单页为准。

自建开源重排模型(如 BGE 系列)没有按次费用,但有 GPU、带宽和运维成本。流量稳定且规模大时,自建可能更可控;流量小或波动大时,固定 GPU 成本往往比按量付费更高。

三、候选集怎么定

Rerank 的成本大致随候选文档数增长。召回 200 条全部重排,成本通常是召回 50 条的数倍,延迟也会上升。

候选数 相对成本 延迟 适用场景
20–30 低 低 高频客服、延迟敏感接口
50 左右 中 中 通用知识库的常见起点
100 较高 较高 文档长、召回噪声大
200 以上 高 高 先优化召回,不建议直接上

建议从 50 条左右起步,用评测集比较 Recall@k 和答案正确率,再决定加还是减。

一个常见误区:调小 top_n 只减少返回条数,通常不减少计费文档数。省钱要在“送进重排之前”砍,而不是“出来之后”砍。元数据过滤、近似去重、相似度阈值和按业务线限定文档范围,都比事后截断有效。

四、文档长度与切块

很多重排接口对单条文档有 Token 上限,超长部分会被截断。被截断的内容不参与打分,可能把关键段落切掉,效果反而变差。

按 Token 计费时,文档越长成本越高;按文档计费时,长文档可能被切成多条计费文档。两种口径下,切块策略都会同时影响效果和账单。

  • 只把检索命中的片段送去重排,不要送整篇文档。
  • 切块大小与模型上限对齐,标题和关键上下文不要丢。
  • 入库前去重,近似重复的块不要重复计费。
  • 记录每块的 Token 分布,按 P95 而不是平均值做预算。

五、延迟与成本怎么平衡

Rerank 会增加延迟,候选越多越明显。平衡的办法不是一刀切,而是按场景分层:

  • 高频 FAQ 可以跳过重排,直接走缓存或关键词检索。
  • 对延迟敏感的接口限制候选数,先做元数据过滤。
  • 对质量敏感、并发低的离线任务,可以放宽候选数。
  • 设置客户端超时和重试上限。一次超时后重试,可能让同一查询计费两次。
  • 用 P95 而不是平均值评估延迟。

六、缓存与去重

Rerank 缓存放在检索之后、生成之前。缓存键至少包含:规范化查询、文档 ID 与版本、模型名、top_n。少一项就可能把错误结果复用给别的租户。

  • 高频问题:TTL 可以按小时到天。
  • 快速更新的文档:TTL 按分钟,或在文档更新时主动失效。
  • 权限:缓存键必须带租户和权限范围,不能跨租户命中。
  • 失败结果:不要缓存;短 TTL 的负缓存也要谨慎。
  • 批量任务:同一批文档在同一天内重复打分,可以直接复用结果。

客服、内部制度问答这类场景,重复问题比例高,缓存的收益通常比换更便宜的模型更直接。

七、预算怎么估

先按目标厂商的计费口径,把“每次查询”换算成计费单位,再乘查询量:

月成本 ≈ 日查询量 × 30 × 每次查询计费单位 × 单价
        + 重试与峰值冗余

按 Token 计费时:

每次查询 Token = 查询 Token × 候选文档数 + 所有候选文档 Token 之和

可复现的估算步骤:

  1. 从日志取日均查询量和峰值查询量。
  2. 抽样 100–200 条真实查询,统计候选数和文档 Token 的 P50、P95。
  3. 按厂商口径换算每次查询的计费单位。
  4. 乘日查询量和 30 天,再加 10%–30% 的重试、增长和峰值冗余。
  5. 用模型价格的最新单价相乘,不要用旧截图。
  6. 上线后按周对账,用真实账单修正估算。
# Token 计费口径的成本估算:单价从 /pricing 填入
QUERY_TOKENS = 60             # 抽样得到的中位数
DOCS_PER_QUERY = 50
AVG_DOC_TOKENS = 180
UNIT_PRICE_PER_MILLION = 0.0  # 占位,请替换为实际单价

def cost_per_query(q_tokens, n_docs, doc_tokens, price):
    total_tokens = q_tokens * n_docs + n_docs * doc_tokens
    return total_tokens / 1_000_000 * price

per_query = cost_per_query(
    QUERY_TOKENS, DOCS_PER_QUERY, AVG_DOC_TOKENS, UNIT_PRICE_PER_MILLION
)
print(f"单次查询约 {per_query:.6f}")
print(f"日均 1 万次约 {per_query * 10_000:.2f}")

单价、免费额度和阶梯折扣都可能变化,脚本里的单价应从当前价格页读取,不要写死在代码仓库里。

八、账单对账与告警

  • 按 Key、项目、业务线拆账,不要把所有调用混在一个 Key 里。
  • 分别记录查询数、候选文档数、Token、模型和延迟。
  • 把 Embedding、Rerank、生成三段的成本分开,否则不知道优化哪一段。
  • 关注重试、空查询、前端重复提交和后台重建索引任务,这些是常见的账单尖峰。
  • 设置日预算和余额告警,余额低于阈值时通知负责人。

厂商返回的用量字段可用于对账,具体字段名和口径以各自文档为准。

常见问题

Rerank 比换更大的生成模型更划算吗?

多数情况下是。重排只处理几十条候选,成本可控,而且直接改善“正确片段排在后面”的问题。但如果召回本身没命中,重排也救不回来,先修召回。

调小 top_n 能省钱吗?

通常不能。计费一般按送进去的候选文档或 Token 计算,top_n 只影响返回给生成模型的条数。要省钱,应该在重排前减少候选、去重和过滤。

候选文档越多效果越好吗?

不一定。候选越多,噪声越多,延迟和成本也越高。先用评测集比较 Recall@k 和答案正确率,找到收益拐点,常见起点是 50 条左右。

长文档需要先切块吗?

需要。多数接口会按 Token 上限截断,超长部分不参与打分;按文档计费的服务还可能把长文档切成多条计费文档。切片时保留标题和上下文,避免把答案切断。

自建 Rerank 一定更便宜吗?

不一定。自建省掉按次费用,但有 GPU、部署、扩缩容和运维成本。流量稳定且利用率高时自建更可控;流量小、波动大或团队没有运维能力时,按量付费的 API 更省事。

下一步

先用一批真实查询统计候选数和文档长度,再在中商起航 AI 网关用小额预算跑通“召回—重排—生成”链路,对比开启和关闭重排的质量、延迟与成本。模型可用性与价格以模型价格为准。

相关阅读: