固定费用模型只要先扣一次积分。切到 Token 计费后,实际用量要等服务商返回才知道。如果仍然先扣很小的固定费用,再在成功后补扣,就可能出现一个尴尬状态:外部模型已经完成,用户却因为余额不足拿不到成功结果。
不可逆动作之前要控制成本
这次修复将流程改成:估算输入费用,加上受约束的最大输出费用,在调用前形成预扣额度。余额不够就提前拒绝,不能先产生外部成本,再把支付问题留到结果阶段。
服务商请求也要收到最大输出 Token 参数。只在本地估计一个上限,却不约束实际输出,前后仍然没有闭环。
成功、缺少 usage 和失败要分别处理
| 服务商结果 | 结算处理 |
|---|---|
| 成功,实际费用低于预扣 | 按实际费用结算,退回差额 |
| 成功,计算费用高于预扣 | 按预扣上限封顶,保持成功结果 |
| 成功,没有 usage | 按配置的固定回退费用结算 |
| 调用异常 | 退回预扣并记录退款状态 |
这里的“上限”包含输入估算,不代表一定等于服务商实际账单。封顶意味着平台需要承担超过预扣部分的成本;它是一项明确的产品取舍。
不能只验证 HTTP 成功
这类修改的验收要同时看返回状态、余额、交易金额、账本变化和服务商调用次数。
尤其要检查两类反例:余额不足时是否仍然调用了服务商;模型已经成功时,结算是否又把它转换成失败。缺少 usage 的服务商也必须验证,否则预扣上限可能被错误地当成最终费用。
留下的检查点
涉及第三方成本的功能,先把业务时间线画出来:什么时候检查余额,什么时候外部动作无法撤销,什么时候得到真实用量,什么时候可以退款。
AI 能很快写出扣款和退款方法,但它们在时间线上放错位置,功能照样会出问题。我需要负责把这条时间线和失败规则讲清楚。
记录来自 2026-07-10 的提交 c79dc1205,包含计费实现、服务商参数映射、测试与对应契约文档。