先说答案:大模型 API 的账要对得上,靠的不是供应商的「透明计费」口号,而是三层能自己复算的数据。第一层是单个任务:在 HopBase,视频、异步生图等异步任务结束后,查询接口的响应里直接带 usage.cost(这一单从余额实际扣掉的金额)和 usage.currency,失败且未扣费的任务报 0,用一条 curl 就能核。第二层是逐笔明细:控制台「使用记录」可按日期、Key、成员、部门、创建人筛选后导出 CSV,每行都带官方费用、折扣、折算率和扣费金额,可以按「官方费用 × 折扣 ÷ 折算率 = 扣费金额」逐行验算。第三层是分摊:每把 Key 显示创建人、可以按 Key 看消耗趋势图,部门负责人能看、能管本部门成员的 Key 和用量,额度可以按 Key、成员、部门分别设。三层对齐了,财务按部门分摊就只是一次筛选加导出。
为什么大模型账单难对
一家公司同时用对话、生图、视频模型时,计费单位至少有四种:对话按 token,生图多按张,视频按秒或按 video token,还有一些按次收费。再叠加几个现实问题,账就很难对上:
- 异步任务的钱在「结束时」才确定:视频提交时只是预估,真正扣多少要等任务完成;失败的任务是否扣费、扣多少,各家口径不同。
- 失败请求的口径:请求失败一般不计费,但如果客户端在输出已经生成之后才断开,已生成的部分通常要计费。账单里如果不标清楚,就会出现「明明报错了还扣钱」的争议。
- 多币种:官方牌价多是美元,账户余额可能是另一种币种,中间差一个折算率;少了这个除数,任何人都没法复算。
- 多人共用:一把 Key 被多个项目共用,事后就分不清是谁花的。
所以对账的目标很具体:任何一笔钱都能追到「哪个任务 / 哪次请求、哪把 Key、谁建的 Key、属于哪个部门」,并且金额能用公开牌价复算出来。
第一层:单个任务,查询响应里直接拿实扣金额
异步任务(视频、异步生图等)结束后(完成、失败或取消),单任务查询接口的响应根对象会多出一个 usage 对象:
usage.cost:这个任务从余额实际扣掉的金额,和使用记录里的扣费金额是同一个数;usage.currency:余额币种,当前为CNY。别默认是美元,以这个字段为准;- 失败且没有扣费的任务报
0;个别生图任务在扣费结算之后才失败(比如模型没有返回可用图片),报的是实际扣费; - 任务进行中不返回这个字段;而且只有创建任务的那把 Key 查得到。
覆盖的查询路径:GET /v1/video/tasks/{task_id}(Seedance、Grok Imagine、可灵、MiniMax、Midjourney)、GET /api/v1/tasks/{task_id}(万相、快乐马)、GET /v1/images/tasks?task_id=...(GPT Image 与 Gemini 生图的异步任务)。自己核一下只要一条命令:
# 用提交任务的那把 Key 查询;jq 只挑出状态和费用
curl -s https://api.hop-base.com/v1/video/tasks/$TASK_ID \
-H "Authorization: Bearer $HOPBASE_API_KEY" \
| jq '{status: (.task.status // .status), usage}'
# 任务结束后的输出形如(金额仅作示意):
# { "status": "completed", "usage": { "cost": 2.4, "currency": "CNY" } }
Seedance 的响应里 task.usage 是计费用的 token 数,根对象的 usage.cost 才是金额,两者别混;MiniMax、万相这类本来就有根 usage 的,cost 与 currency 会合并进去。这一层的用处是:业务系统可以在任务结束时把实扣金额直接写进自己的订单或工单,不用再定时去控制台翻记录,也不用拿提交时的预估当成本。
第二层:逐笔明细,导出 CSV 并逐行验算
同步的对话请求不产生任务,响应体里只有 token 用量,金额以使用记录为准。控制台「使用记录」页的导出按钮会按页面当前的筛选(日期区间、Key、成员、部门、Key 创建人)导出 CSV,单个文件最多 5 万行、最长 400 天。每行九列:
- 时间、模型、用量;
- 官方牌价币种、官方费用(原币);
- 折扣、折算率、扣费金额(账本币种);
- 备注。
中间四列从左到右正好读成验算式:官方费用 × 折扣 ÷ 折算率 = 扣费金额。牌价币种与账本币种相同时折算率留空,等式退化成「官方费用 × 折扣 = 扣费金额」。官方费用可以拿厂商官方价格页自己算,折扣就是你所在分组的折扣,所以每一行都能独立复算,不需要相信任何人的汇总数。早期记录没有牌价快照时,这几列会留空。
失败请求在备注里写明「请求失败,未扣费」;客户端中途断开、但输出已经生成的请求,写明「请求中断,按已生成的用量扣费」,文件末尾分别汇总条数。这正是最容易起争议的两类行,把口径写在明细里,比事后解释省事得多。需要自动化时,GET /v1/usage 用 API Key 就能查余额和这把 Key 的额度用量。
第三层:按 Key、按部门分摊
分摊的前提是「一个成本中心一把 Key」。HopBase 的企业账户里有成员和部门,几个事实决定了分摊能不能落地:
- 每把 Key 显示创建人:成员自己建的、企业主或部门负责人代建指派给成员的,都分得开;导出也能按创建人筛。
- 按 Key 看消耗图表:控制台可以按 Key 查看消费趋势、请求数和模型分布,异常消耗一眼能看出来是哪把 Key。
- 部门负责人的范围:部门负责人能看到并管理本部门成员的 Key 和用量,能给本部门成员建 Key;看不到别的部门。企业主看全公司。成员调岗后,负责人的范围随之变化。
- 分层额度:Key、成员、部门都可以设额度,任何一层用完都会拦截;超额时返回 402,信息里写明是 Key 额度、成员额度还是部门额度用完,不会只丢一个笼统的「余额不足」。
月底给各部门出账,就是在使用记录里选部门、选月份、导出;每个部门拿到的是自己那份明细,并且可以用上一节的等式自己复算。
一份可以拿去核任何供应商的对账清单
- 异步任务结束后,能否从 API 直接拿到这一单的实扣金额,而不是预估或基础成本?
- 明细能否导出,是否包含官方费用、折扣、折算率,能否逐行复算?
- 失败请求与「中途断开但已生成」的请求,明细里是否分开标注?
- 金额字段有没有写明币种?牌价币种与余额币种不同时,折算率是否可见?
- 能否按 Key、成员、部门筛选导出,Key 有没有创建人?
- 额度能否分层设置,超额报错能否看出是哪一层?
- 你付费调用的是不是你以为的那个模型?这一项可以用API 中转保真检测方法自己测。
这份清单每一项都能用 curl 或导出文件验证,拿去评估任何供应商都适用,包括我们。
常见问题
任务查询里的 usage.cost 和控制台的扣费金额一样吗?
一样。usage.cost 取的就是这笔任务使用记录里的实扣金额,也就是余额真正减少的数,可以直接拿来和导出明细逐笔对。
为什么任务还在跑的时候看不到 usage.cost?
异步任务的最终费用要等任务结束才确定,进行中返回的任何数字都只能是预估。所以只在完成、失败或取消之后返回;进行中的任务响应里没有这个字段,按原来的逻辑继续轮询即可。
失败的任务会扣费吗?
视频任务失败一律不扣费,查询里 usage.cost 报 0。生图任务极少数情况下会在扣费结算之后才失败,这时报的是实际扣费,使用记录里也能看到同一笔。同步请求失败不扣费;客户端中途断开但输出已经生成的,按已生成的部分扣费,并在导出明细里单独标注。
换一把 Key 查同一个任务,为什么没有费用字段?
费用只对创建任务的那把 Key 返回。这是为了让「一个成本中心一把 Key」的分摊边界不被打破,也避免同账户下其他 Key 看到不属于自己的消耗。
对话请求有没有类似的单笔金额?
对话响应里只有 token 用量,没有金额。单笔金额在控制台使用记录里,导出 CSV 可以逐行验算;按 Key 或部门汇总,用筛选加导出即可。