Token 预算不能靠本地计数器:预占、核销和并发超额怎么处理

发布时间:2026/10/25 18:17:55
Token 预算不能靠本地计数器:预占、核销和并发超额怎么处理

如果两个网关各自看到“今天还剩 100 元”,同时放出一笔 80 元请求,本地计数器都没有错,全站预算却已经失守。Token 计数能帮助估算,货币预算还需要一份跨请求的账。

三个账户,一笔请求

把预算拆成可用、预占和已结算。发出请求前按允许的最大输出和适用费率预占;拿到可信 usage 后核销;响应丢失时保留待对账状态。不能把超时直接解释成“没收费”,也不能用输出 token 上限证明总费用上限,搜索、缓存写入等费用可能另计。

DeepSeek 价格页及Search 文档需按币种、模型和生效时间核对。十月的新搜索能力让这件事更具体:调用次数也可能成为预算维度。本文不把未来生效费率写成已经发生的账单。

先验证最小记账不变量

这个整数单位示例没有并发和数据库,仅用来检查重复核销、剩余额度和超额实际费用。金额单位由业务约定,这里不是人民币报价。

class Ledger: def __init__(self, budget): self.free, self.spent, self.pending, self.done = budget, 0, {}, set() def reserve(self, rid, cap): if rid in self.pending or rid in self.done or cap <= 0 or cap > self.free: return False self.free -= cap; self.pending[rid] = cap return True def settle(self, rid, actual): if rid in self.done: return False cap = self.pending[rid] if actual < 0 or actual > cap: raise ValueError('reconcile overrun') self.free += cap - actual; self.spent += actual del self.pending[rid]; self.done.add(rid) return True l = Ledger(100) assert l.reserve('a', 80) and not l.reserve('b', 80) assert l.settle('a', 50) and not l.settle('a', 50) assert (l.free, l.spent) == (50, 50) assert l.reserve('unknown', 30) assert l.free + l.spent + sum(l.pending.values()) == 100 print('reservation, duplicate settlement, unknown hold: passed')

本地 Python 3 断言通过。实际费用超过预占时程序要求对账,不假装硬预算仍成立。生产实现需在同一事务里检查余额、建立唯一请求记录和扣减,并对结算幂等;Redis 事务只保护 Redis 内操作,PostgreSQL 隔离说明也提醒并发快照需要正确条件约束,跨供应商执行不在本地事务里。

如果计费无法给出可信上界,承诺应该是“限制风险敞口并持续对账”,而非“绝不超额”。依赖故障时可拒绝新请求,或使用事先分配、总量受控的离线额度;默认放行再谈硬上限,逻辑上站不住。没有实测外部账单,发布前需复核费率与 usage 字段。