长文本任务的四个成本陷阱:钱花在了你没注意的地方

2026-08-06

长文本场景的账单失控,很少是因为单价贵,而是因为同一份内容被反复重发、上下文长度悄悄跳了档、以及重试把长请求又跑了一遍。这几件事在开发环境里都看不出来,量一上来就集中爆发。

这篇把四个陷阱逐个拆开,每个都给自查方法。想边看边换算长度和成本,开上下文长度计算器

陷阱一:上下文长度悄悄跳档

不少厂商按上下文长度分档计费:短提示走低档,超过某个阈值单价跳一档,超长再跳一档。你在开发时用短样例测,走的是最低档;上线后真实文档长得多,请求悄悄跳到高档,单价可能翻倍甚至更多。

自查方法:统计线上请求的输入 token 分布(不是平均值,要看分位数)。如果 P90 落在高档区间,你的实际平均单价就和价目表首行那个数没什么关系了。

处理:要么把输入压到阈值以下(裁剪、检索),要么按真实档位重做预算,别拿宣传价估。

陷阱二:多轮会话里,长文档被反复重发

这是最贵的一个坑。假设你在会话开头塞了一份长文档,之后用户连问十个问题——如果每轮都把完整历史发过去,这份文档就被计费了十次。

很多人以为「模型已经读过了,后面应该记得」,但模型没有记忆,每次请求都是全新的,你不发它就不知道。

自查方法:拿一次典型的十轮会话,把每轮实际发出去的请求体 token 数加起来,和「单轮 token × 10」对比。差距就是累加成本。

处理:三选一或组合——把文档换成检索片段(每轮只带相关的几段);把文档交给提示缓存(命中后这部分极便宜);把早期历史压成摘要。

陷阱三:重试把长请求又跑了一遍

长请求更容易超时,也更容易撞 TPM(每分钟 token 数)限流。而重试是全额重跑——一个十万 token 的请求失败重试三次,就是四十万 token 的账单。

更隐蔽的是流式输出中断:已经生成了一半的内容如果没做续接,重来一次两边都要付钱。

自查方法:在日志里记录重试次数和触发原因,按输入长度分组看重试率。长请求的重试率通常显著高于短请求。

处理:长请求单独设更长的超时;按 TPM 而不只是 RPM 控并发(长请求撞的往往是 TPM);重试用指数退避;区分可重试和不可重试错误,参数错误重试多少次都是白花钱。

陷阱四:静默截断带来的返工成本

有些客户端在超出窗口时会自动截断最早的内容,请求成功了,但模型丢了前半段上下文。你不会收到任何报错,只会发现输出质量莫名下降、前后矛盾。

这个陷阱的代价不只是钱,还有排查时间——因为没有报错,很难想到是截断导致的。

自查方法:发请求前自己估长度,超阈值时主动告警,而不是依赖客户端处理。把「本次请求输入 token 数」记进日志,异常输出时先查这个字段。

处理:主动裁剪优于被动截断。裁剪时保留 system prompt 和最近几轮,把中间部分摘要化。

怎么统计输入长度的分布

上面几个自查都要求你看「分布」而不是「平均值」,因为长文本场景的分布通常是长尾的:大多数请求不长,少数超长请求吃掉大部分预算。平均值会把这个结构完全抹平。

最小可用的做法:在调用处记录每次请求的输入 token 数(从 API 响应的 usage 字段取最准),按天聚合出 P50、P90、P99 三个分位数。

三个数字怎么读:

  • P50 决定你的常态成本,用来做基准预算。
  • P90 决定你的计费档位——如果 P90 已经跨进高档区间,说明相当一部分请求在按高档价计费,基准预算会低估。
  • P99 决定你的失败率——超长请求最容易超时和撞 TPM 限流,重试成本集中在这一段。

如果 P99 比 P50 大出一个数量级,说明有少数异常请求在拖累整体,值得单独查一查它们是什么——常见的是用户粘贴了超长文本、检索召回没设上限、或者某条会话历史没被裁剪。

一个排查思路:账单涨了,从哪查起

按这个顺序查,通常三步之内能定位:

第一步,看是量涨了还是单请求变大了。 请求数和输入 token 中位数分别对比上周期。请求数涨是业务问题(好事),中位数涨是工程问题(要查)。

第二步,如果是单请求变大,看变在哪一段。 把输入拆成固定前缀、检索片段、历史三块分别统计。多数情况下是检索片段没设上限,或者历史裁剪策略失效。

第三步,如果单请求没变大,看重试率和缓存命中率。 重试率上升通常是并发调高了或厂商限流收紧了;缓存命中率下降常常是有人往前缀里加了动态内容(时间戳、随机 ID),一个小改动就能让缓存全线失效。

这三步都依赖埋点,所以埋点要在上量之前做好,事后补是查不出历史原因的。

一个反直觉的结论:长上下文未必比检索准

除了成本,还有效果。超长上下文里,关键信息位于中间位置时,模型的召回稳定性通常不如短上下文。也就是说,你多花了十倍的钱,未必换来更好的答案。

这不是说长窗口没用——需要跨全文关联的任务(整本代码库分析、全局一致性检查)确实只能靠长窗口。但如果你的任务本质是「在文档里找到相关段落然后回答」,检索几乎总是更省更准。怎么权衡,看上下文长度怎么选

长文本场景值得单独做的三个工程约束

长文本的问题很难靠事后优化解决,更有效的是在代码里加硬约束,让它压根出不了问题。

约束一:给检索召回设 token 上限,而不是条数上限。 按条数限制是最常见的实现,但每条长度不一,十条短片段和十条长片段的成本能差好几倍。改成「累计不超过 N 个 token 就停止追加」,成本立刻可控。

约束二:发请求前做长度检查,超阈值走降级路径。 降级可以是自动摘要、可以是分段处理、也可以是提示用户缩小范围。关键是显式处理,而不是让请求带着超长内容撞上去,等 API 报错或客户端静默截断。

约束三:把「单次请求最大 token 数」做成配置项并接入告警。 有了这个开关,遇到成本异常时可以立刻收紧,不用改代码发版。这在事故处置时特别有用。

三个约束加起来代码量不大,但能挡掉长文本场景绝大部分的成本意外。

长文本场景的成本自查清单

上线前照着走一遍:

  1. 线上输入长度的 P50 / P90 分别落在哪个计费档?
  2. 一次完整会话的总 token 是单轮的几倍?
  3. 长请求的重试率是多少?重试原因是超时还是限流?
  4. 有没有请求被静默截断?(对比发出长度与窗口上限)
  5. 固定前缀有没有交给缓存?缓存命中率多少?

五个问题都有数字,成本就基本可控了。没有数字的话,先补埋点——参考 API 成本监控。算总账去月成本估算器

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。