墨菲手记murphy
← 全部文章
开发笔记约 7 分钟

同一个账号,一个模型停了,另一个开始收钱

一次免费额度使用中的不同表现,让我重新检查应用的预算保护。模型开关、Token 用量和实际账单要分别核对,成本优化也要算到整笔请求上。

修订于 2026-10-16。

我在一个内部问答系统上接了阿里云百炼。当时的调用记录里,一个模型在免费额度耗尽后返回了 403,另一个模型继续调用,账单上出现了费用。

这件事让我意识到,应用需要有自己的预算保护。只记得平台提供了一个用完即停开关,还不够判断每次请求是否受它保护。

两个模型表现不同的原因,当时没有核清。需要逐项对照模型版本、开关状态、额度有效期和配置生效时间,才能判断问题出在哪里。

一 预算保护要落实到每个模型和请求

百炼目前的免费额度说明写明,不同模型及其快照版本的额度相互独立,用完即停开关可以按模型配置,配置生效也有延迟。已认证用户未开启相应开关时,额度用尽后会转为按量计费。这些是修订时的公开规则,当时账号的实际状态还得查历史配置和账单。

同一个账号,不能替代对每个模型的核对。候选链里加了新模型,也就多了一组额度、有效期和计费条件要检查。

我后来的处理是,在应用里增加一层按 Token 用量判断是否切换模型的逻辑,同时保留平台侧的保护。这样至少能把一部分预算判断放进自己的代码和日志里。

但切换模型本身仍可能产生费用。应用计数要覆盖输入、输出和重试;多个请求同时执行时,已经发出去的请求也会继续消耗额度。按 Token 数切换,距离限制实际金额还有一步。

如果要限制金额,可以在请求发出前预留预算,按实际用量结算,并给并发中的请求留出余量。模型价格、输出长度上限和超额处理方式,都需要一起确定。

这些是进一步设计预算保护时要做的事。已有的 Token 计数,只能承担它实际覆盖的那部分判断。

举个假设的并发场景:某个应用当期预算是 100 元,已经结算 80 元,同时来了两笔预计各需要 12 元的请求。如果两笔请求各自只检查已经结算的金额,它们都会看到还有 20 元,都会发出去。最后的花费就可能到 104 元。

预留预算要处理的就是这个时间差。第一笔请求通过检查时,先占住预计需要的 12 元,第二笔再检查就只剩 8 元。请求完成后,把预留值换成实际费用;请求失败或取消,也要按实际计费情况释放或结算。这个动作需要统一处理,不能让并发请求各看各的余额。

估算本身也可能有偏差。因此预算设计还要决定,余量不足时是拒绝请求、缩短可生成的长度,还是切到满足质量要求的其他方案。每种选择会改变使用体验,适合写成应用的明确规则,再用并发和失败场景检验。

二 用量和费用要分开记 再拿来对账

应用日志适合回答谁调用了什么、输入输出各用了多少 Token。供应商账单回答的是这些用量按什么规则计费、由什么额度抵扣。两者需要关联起来看。

缓存就是一个常见的差异来源。百炼的上下文缓存说明区分缓存创建和命中,不同部分可能适用不同价格。某段输入发送了一次,并不意味着它一定按完整输入单价收费。

但账单金额降低,也不能直接证明免费额度按同样比例扣减。计费规则、免费额度抵扣规则和统计时间范围,都要分别核对。

做费用估算时,可以先把请求分成三部分:未缓存输入、缓存输入和输出。每部分的用量乘上对应单价,再加总。存在缓存创建费、阶梯价格或其他项目时,也要单独计入。

最后拿这个估算和账单对照。出现差值,先检查模型版本、请求范围、单位和更新时间,再追缓存或抵扣规则。差值是排查线索,不能直接当成某一种原因的证明。

请求身份也应贯穿这两本账。本地至少保留应用标识、请求时间、模型版本、输入输出用量、结果状态,以及供应商返回的请求标识。这样查到一笔费用时,才能回到具体调用。提示词和回复里可能有业务信息,对账通常不需要顺手保存整段正文。

失败请求和重试应有各自的记录。同一个用户操作可能触发多次上游调用,只按操作次数记账就会漏掉中间过程。对流式响应,中途断开后是否拿到了最终用量,也需要检查;缺失的记录应单列出来排查,不能直接按零处理。

三 比较优化方案要算整笔请求

查看请求构成后,我发现系统提示和工具声明占了不少输入。它们反复发送,说明压缩上下文、按场景裁剪工具和利用缓存,都有优化空间。

换更便宜的模型,同样会影响这些重复输入的费用。它的收益要按所有适用的输入、缓存输入和输出计算。

举一个简化例子:假设一笔请求只有输入费用,且全部按同一单价收费。每次发送 10,000 Token,其中 9,600 是重复内容。单价降低一半,整笔输入费用也降低一半。若保持单价不变,把重复内容压到 4,800 Token,总量就变成 5,200 Token,输入费用降低 48%。

这两种办法都可能有效。实际请求还包含输出、缓存价格和质量差异,需要把各部分放回计算,才能比较收益。

如果原来那 9,600 Token 已经命中很便宜的缓存,压缩它们的节省幅度还会变化。省掉一半 Token 与省掉一半金额,只有在相应单价和其他条件满足时才等价。因此我会先列出输入、缓存和输出三项费用,再决定从哪一项下手。

减少工具声明也要看完成任务的结果。少传了几项工具,模型可能更容易选择,也可能失去完成任务所需的能力。如果因此增加追问、重试或人工补救,单次请求便宜了,完成一次任务的总成本仍可能更高。成本比较最好同时记录任务成功率和平均调用次数。

缓存也需要实测。公共前缀稳定时更容易复用,但一次命中多少、压缩后还能否命中,都要看返回的用量信息。调整提示词后,费用、延迟和回答质量应一起比较。

先看请求构成,再选优化办法。这样讨论换模型或压上下文,才有可以对照的数字。

四 网关可以把调用归属和预算连起来

只有一个应用调用一个模型时,清楚的日志和预算规则就能解决很多问题。调用方和供应商增加之后,费用归属会更难追。

几个应用共用一个密钥,供应商给出的是总账。要知道哪部分费用来自哪个应用,就需要在调用之前记录身份,在调用之后记下模型、用量和结果。网关可以集中做这些事,也可以承接令牌配额和用量导出。

我更关心的是,这套记录能否帮人回答具体问题:哪个应用花了钱,预算快用完时怎么处理,本地统计能不能和上游账单对上。统一接口之外,这些问题会在持续运行中反复出现。

准备把一套开源网关用于实际项目时,也要逐项核对它是否支持需要的计数、预算和并发处理方式。接上一个网关,还需要用真实请求验证配置。

验收可以从一个预算较小的测试应用开始,观察接近额度时的处理,再检查并发、超时和上游报错。预算用尽后,是明确拒绝,还是换模型继续调用,要和约定的规则一致。除了正常请求能不能完成,还要看到异常请求留下了什么记录。

使用网关前后,也要留意是否还有绕过它的调用路径。某个脚本继续直连供应商,本地账本就只覆盖了一部分花费。费用归属是否完整,要从所有调用入口检查,不能只看网关面板里的总数。

这次经历让我开始记录每次调用的归属和用量,明确预算判断采用什么规则,再定期和供应商账单核对。开关是否开启、应用是否拦住超额请求、最终花了多少钱,这三件事都要能查得到。

← 回到文章列表