自己跑 AI Agent 最容易被忽略的不是部署是账单。本文用怡途Claw 的 /api/app/billing/* 接口,把查余额、看本月 Token 用量、拉单条明细、算单实例成本串成一条线,附分/元单位坑和别名对照。
自己跑 AI Agent,最容易被忽略的不是部署,是账单。一个实例挂在那儿,白天调几十次、夜里又被脚本拉起来跑批,月底一看账单,不知道钱花在哪个模型、哪条对话上。怡途Claw 把用量和计费做成了 /api/app/billing/* 一组接口,这篇文章把「查余额 → 看本月花了多少 → 拉单条 Token 明细 → 算清楚单个实例的成本」串成一条线,每个请求都带真实字段和容易踩的坑。
所有接口都要 JWT,放在 Authorization: Bearer <token>,和创建实例那条线是同一套登录态。下面假设你已经拿到 token。
一、查余额:别只看 balance 一个字段
GET /api/app/billing/balance
Authorization: Bearer <token>
返回:
{
"success": true,
"data": {
"userId": "...",
"balance": 86.42,
"frozenAmount": 0,
"availableBalance": 86.42,
"totalRecharged": 500.00,
"totalConsumed": 413.58,
"updatedAt": "2026-07-25T03:10:00.000Z"
}
}
重点看三个数:balance 是当前可用余额,totalRecharged 是累计充值,totalConsumed 是累计消耗。验账用 totalRecharged - totalConsumed 对一下 balance,对不上就是有退款或冻结没算清楚。frozenAmount 目前固定是 0,接口里留了这个字段但还没启用预扣,别指望它替你做并发预算控制。
这里有个隐藏动作:调 balance 时,服务端会异步触发一次充值订单对账(reconcilePaidRechargeOrders),对账失败不影响余额返回。意思是这个接口顺带会把你「刚付完钱、余额还没到账」的订单补上。所以充值后余额没立刻变,多刷一次 balance 通常就好了,不用去提工单。
二、本月花了多少:Token 用量统计
GET /api/app/billing/token-usage/stats
Authorization: Bearer <token>
{
"success": true,
"data": {
"currentMonthCost": 27.31,
"lastMonthCost": 41.88,
"totalCost": 413.58,
"currentMonthInputTokens": 1284000,
"currentMonthOutputTokens": 312000,
"currentMonthTotalTokens": 1596000
}
这是做成本趋势图最快的数据源。currentMonthCost 和 lastMonthCost 直接对比就能算环比,currentMonthInputTokens / outputTokens 拆开看是因为多数模型输入和输出单价差一个数量级——输出 token 才是花钱的大头,盯着输入量看会误判成本结构。
注意「本月」是按服务端时区的自然月切的,不是滚动 30 天。所以月底 23:59 跑的报表和月初 00:01 跑的报表,currentMonthCost 会断崖式跳变,做监控面板时要按月分段,别画成连续曲线。
三、拉单条用量明细:按实例和时间筛
统计接口告诉你「花了多少」,明细接口告诉你「花在哪」。核心请求:
GET /api/app/billing/token-usage?page=1&pageSize=20&instanceId=<实例ID>&startDate=2026-07-01&endDate=2026-07-25
Authorization: Bearer <token>
每条记录长这样:
{
"id": 91234,
"instanceId": "8f3a6c4c-...",
"providerId": "deepseek",
"modelName": "deepseek-chat",
"inputTokens": 1820,
"outputTokens": 460,
"totalTokens": 2280,
"cost": 0.0031,
"inputPrice": 0.001,
"outputPrice": 0.0021,
"requestId": "...",
"createdAt": "2026-07-25T02:14:33.000Z"
}
筛选参数里最实用的是 instanceId——把成本钉到具体那个 Agent 上。startDate / endDate 要传 ISO 日期字符串(2026-07-01 这种),传错格式会被 DTO 校验拦成 400。pageSize 最大 100,超出会被夹回来,想全量拉就分页 hasNext 循环。
一个常被问的点:cost 是这条请求的实际扣费,inputPrice + outputPrice 加起来等于 cost。如果你发现某条 cost 对不上模型公开报价,先看 providerId 和 modelName——怡途Claw 接了 14 家以上模型商,同一家不同模型单价差很多,别拿 deepseek-chat 的价去对 deepseek-reasoner 的账。
四、算单个实例的月成本
把上面两个接口拼起来。先拿实例列表(/api/app/instances),对每个实例调 token-usage?instanceId=<id>&startDate=...&endDate=... 把当月记录拉全,cost 求和就是单实例月成本。再配上 /api/app/billing/instance-limit:
GET /api/app/billing/instance-limit
Authorization: Bearer <token>
{
"success": true,
"data": { "currentCount": 3, "limit": 10, "canCreate": true, "remaining": 7 }
}
canCreate 是创建实例前最该先查的字段,省得 POST 到一半被配额挡回来。套餐越高 limit 越大,免费版通常只给 1–2 个。
五、价格的单位坑:分和元
看套餐价时最容易栽跟头。拉套餐:
GET /api/app/billing/plans
Authorization: Bearer <token>
返回里每个套餐同时给 price 和 priceCent:
{ "price": 99.00, "priceCent": 9900, "priceMonthly": 99.00, "priceYearly": 999.00 }
数据库存的是分(整数,避免浮点),接口给你换算成了元(priceCent / 100,保留两位)。自己写对接代码时,算账用 priceCent,展示用 price——别拿 price 去做累加再格式化,0.1 + 0.2 那种浮点坑在月账单汇总里能差出几分钱,对账时特别烦。账单记录 records、发票 invoices 也是同一套:amount 是元,amountCent 是分,两个字段都返回,挑一个用就别混。
六、别名和多模态用量
这组接口别名特别多,文档和代码不完全对齐时容易懵。subscription 和 package 是同一个东西,quota-usage 和 quota 是同一个,token-usage/stats 和 token-stats、media-usage/stats 和 media-stats 都是别名。接口留这些是为了兼容老客户端,新对接认长名就行,别两边混用。
如果你的 Agent 调了画图/视频,Token 接口查不到那部分成本,得走 /api/app/billing/media-usage,字段结构类似但多了 usageType(image / video)、unitType 和 totalUnits——多模态按张/秒计费,不是按 token。月底对总账时记得把 token-usage 和 media-usage 两份成本加起来,少算一块等于对不上账。
小结
把这几个接口走一遍,一个能落地的成本监控就有了:balance 看余额、token-usage/stats 看趋势、token-usage?instanceId= 钉到实例、instance-limit 卡配额、plans 对套餐价。真要在生产里跑,建议把 balance 和 token-usage/stats 包一层定时拉取,余额低于阈值就告警——比起事后看账单,提前知道哪个实例在烧钱才是这组 API 真正值钱的地方。