先说这套东西解决什么问题:月底账单来了,没人说得清钱花在哪个业务上;某天费用突然翻倍,查了半天不知道是谁干的。这两个场景你们遇到过任何一个,这篇就值得往下读。方案不复杂,一个网关层加一张宽表加几条告警规则,小团队两三天能搭完。
第一步:让所有调用走同一个口
拆账的前提是每笔调用都留痕,留痕的前提是调用有统一入口。业务代码里各自 import SDK 直连模型厂商,是成本失控的头号结构性原因——你连有多少个调用方都数不清。
做法是收口到一个内部网关。可以自己用几百行代码写个转发层,也可以直接用现成的开源网关(new-api、LiteLLM 这类),或者接聚合平台。我们的做法是内部一层薄网关,后面接 147AI 这种聚合服务,一个 OpenAI 兼容接口挂两百多个模型,业务方换模型只改配置里的模型名,网关这层不用动。聚合平台还有个适合拆账的特性:同一个模型分不同倍率的分组,批量离线任务和在线实时任务可以走不同的组,成本档位在接入层就分开了。
收口的同时定一条铁规矩:每个请求必须带业务标签。做法很轻,HTTP header 里加两个自定义字段,app_id 标业务线,scene 标场景(客服问答、文案生成、评测回归……)。网关对没带标签的请求直接拒绝,宁可前期麻烦一点,也别留"unknown"这个口子——有这个口子,三个月后 unknown 会成为你最大的"业务线"。
第二步:记一张调用宽表
网关上每笔调用记一条流水,字段不用多,够拆账就行:
时间戳、请求 ID、app_id、scene、模型名、分组/档位、输入 token、输出 token、缓存命中 token(有提示缓存的话必须单独记,计价不同)、推理 token(推理类模型单独记)、状态码、是否重试、耗时。
token 数从 API 响应的 usage 字段里拿,别自己数。费用可以实时算好存进去,也可以查询时再乘单价——建议前者,因为单价会变,事后追溯当时的价格很烦。单价放一张独立的价格表,带生效日期,模型调价时插一条新记录,历史账单不动。
存储随意,量小用 PostgreSQL,量大丢 ClickHouse。日均百万次调用以下,单机 PG 完全够,别过度设计。
第三步:几张必看的报表
表有了,报表按人剪裁。给管理层的就一张:本月各业务线费用、环比、预测月底总额。给工程团队的细一些:
按 scene 的日费用趋势,谁在涨一眼看到;按模型的用量分布,看看有没有简单任务在用贵模型;单请求成本分布的分位数,P50 和 P99 差距大,说明有一批异常肥的请求值得看;重试率和失败请求费用,这是纯浪费,理论上应该趋近于零;缓存命中率,有提示缓存的话,命中率掉了通常意味着有人改了系统提示的前缀。
报表工具无所谓,Grafana、Metabase,甚至定时跑 SQL 发群里都行。关键是有人每周真的看。
第四步:告警,这是整套系统里回本最快的部分
预算是月底才知道超没超的东西,告警是当天就响的。三条规则起步:
一,日消耗超过近七天均值的 2 倍,通知负责人。这条能抓住重试风暴、接口被刷、死循环上线,都是烧钱最快的事故。二,单个 app_id 的小时消耗突破自定的绝对阈值,直接限流或熔断——注意是自动动作,不是发通知等人处理,凌晨三点的事故没人看群。三,重试率超过 5% 持续半小时,通知。多数时候这意味着下游解析逻辑出了问题,在把正常响应当失败反复重打。
阈值别调太灵敏,告警疲劳之后整套东西等于没有。宁可从宽起步,跑一个月再收紧。
最后
搭完这套,你会得到三样东西:每个业务的真实单位成本(此后谈优化有了依据)、异常当天被抓住(不再是月底惊吓)、以及和供应商谈判的底气(用量结构清清楚楚)。至于更花哨的优化——模型路由、请求合并、语义缓存——都建立在这张宽表之上。先有账,再谈省钱,顺序反了都是白忙。
269



被折叠的 条评论
为什么被折叠?



