把上游用量和用户用量分开记
很多网关在设计上就把「上游实际消耗」和「用户应扣额度」混成一个数字。这会在两个地方同时出错:账单算不准,监控也说不清。
两个数字各有用途
上游消耗是平台的成本,用户扣减是产品的收入逻辑。两者之间可能有折扣、赠送、失败不计费等调节项。
并发上限和速率上限是两回事,两个都要有。
失败请求的计费口径要明确
请求级错误(参数错、上下文超长)通常不扣用户额度,但已经产生的上游 token 成本是实打实的。这两个判断要分开做。
用量统计的时间口径必须写清楚,是 UTC 还是某个业务时区,一周从哪天开始。
因为一个请求可能跑几十秒,几十个并发请求同时在跑,额度还没用完,服务就被并发上限卡住了。
成功率统计要标注口径
「近一小时请求统计」里的失败包含了输入被拒和额度拒绝——这些不是上游故障。所以这个指标不能直接当故障率用。
成功率、时间窗口、历史保留时长——这些数字如果口径不透明,看板就失去了参考价值。
例如「近一小时请求统计」和「历史明细保留 90 天」这类信息,必须在页面上明确标注。
幂等约束防止重复落库
沿用 (request_id, usage_id) 唯一约束,防止结算重试导致重复记账。这是整套统计可信度的地基。
用量按 UTC 存储、按 UTC+8 统计,这是最不容易出错的组合。
实操:把调用明细按天和模型聚合出来。
用量查询页展示的是「用户应扣」的口径,和内部成本口径不同。
import collections, json
# 用量查询接口返回最近 100 条调用明细
detail = fetch_usage_detail() # 你的查询函数
by_model = collections.Counter()
by_day = collections.Counter()
by_status = collections.Counter()
for row in detail:
by_model[row["model"]] += row.get("total_tokens", 0)
by_day[row["created_at"][:10]] += row.get("total_tokens", 0)
by_status[row["status"]] += 1
print("按模型:", by_model.most_common())
print("按天 :", sorted(by_day.items()))
print("状态 :", by_status)
# 明细只保留最近 100 条,所以这里看的是「近期趋势」,
# 要看整月账目应该以服务端返回的汇总口径为准。
几个容易踩的坑
- 把「今日额度」「并发上限」「账户余额」当成同一个东西。
- 日/周/月窗口用的时区没说清楚,用户看到的数字和自己的记录对不上。
- 没有 Key 级限流,一个跑飞的脚本把共享额度吃完。
- 结算重试没有幂等约束,同一笔用量被记了两次。
小结
把配置项和凭据都外置,是成本最低、收益最持久的一个工程习惯。
如果你也碰到上面这些问题,可以看看 https://aiminis.info/ —— 一个把协议适配、渠道调度、用量与额度都收敛在一起的 AI API 网关,OpenAI 与 Anthropic 两套协议都能直接接。
- 点赞
- 收藏
- 关注作者
评论(0)