缓存 Token 怎样记账:用整数费率做可重复结算

发布时间:2026/10/25 18:53:56
缓存 Token 怎样记账:用整数费率做可重复结算

缓存计费看起来只是三项相加:未缓存输入、缓存输入和输出。但账本真正麻烦的地方,是同一个请求重试后会不会扣两次,以及不同单位会不会悄悄截掉小数。

把金额先算成浮点美元再乘一百万,并不能因为最后调用了int就变成整数记账。更清楚的做法是先选足够细的整数单位,费率和数量都在该单位里计算。Python decimal文档解释了十进制金额与二进制浮点表示的差别;需要小数费率时,也可以使用带明确舍入规则的Decimal。

先分桶,再去重

下例使用虚构的整数费率,单位是“每Token纳美元”。它们不是任何厂商报价。输入总量已经包含缓存输入,因此未缓存部分应是二者之差,不能重复收费。一个请求ID若再次出现,既要识别重复,也要检查用量是否被换掉。

from dataclasses import dataclass @dataclass(frozen=True) class Usage: input_tokens: int cached_tokens: int output_tokens: int def cost_nano(usage): values = (usage.input_tokens, usage.cached_tokens, usage.output_tokens) if any(type(v) is not int or v < 0 for v in values): raise ValueError('nonnegative integer counts required') if usage.cached_tokens > usage.input_tokens: raise ValueError('cached input exceeds total input') rates = (100, 20, 300) # fictional nano-USD per token return ((usage.input_tokens - usage.cached_tokens) * rates[0] + usage.cached_tokens * rates[1] + usage.output_tokens * rates[2]) class Ledger: def __init__(self): self.receipts = {} self.total = 0 def settle(self, request_id, usage): if request_id in self.receipts: old_usage, cost = self.receipts[request_id] if old_usage != usage: raise ValueError('same ID with different usage') return cost cost = cost_nano(usage) self.receipts[request_id] = (usage, cost) self.total += cost return cost ledger = Ledger() u = Usage(100, 40, 10) assert ledger.settle('r1', u) == 9800 assert ledger.settle('r1', u) == 9800 and ledger.total == 9800 try: ledger.settle('r1', Usage(101, 40, 10)) except ValueError: pass else: raise AssertionError('conflicting duplicate accepted') print('integer cost, duplicate settlement, conflicting retry: PASS')

预冻结需要另一个状态机

这个内存账本已在本地验证整数计算和幂等语义,但没有处理进程崩溃或并发事务。生产环境需要持久化请求ID、预留金额、实际结算状态及补偿记录,不能把Python字典当成财务数据库。

输出上限也要统一:如果按2048个输出Token预留,发送给后端的上限却允许8192,就不能称为悲观冻结。取消以后已经生成的Token是否计费,必须按服务实际用量处理,而不是一律全额退款。

10 月9日Runway更新加入了项目额度上限,说明生成任务的成本控制正在进入项目层;它与逐次结算仍是不同功能。项目上限限制预算,账本解释实际花费。两者都需要,不能互相代替。官方更新

真实服务的价格、缓存字段和舍入规则应另行从其官方文档读取,本文没有付费调用,也没有验证供应商账单。