AI 成本归因:按功能/用户/请求拆账
"你一个月烧了 5 万 token 费,但说不清哪个功能/哪个用户烧的——这就是没有成本归因。本文讲清 AI 成本怎么归因:按请求打标(功能/用户/会话)、token 计量与聚合、单位经济(单用户/单功能成本)、异常检测(谁在烧钱),让 AI 成本从'一笔糊涂账'变'可优化可问责'。"
本文要点
- 主题聚焦:AI、DevOps
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
AI 应用最常见的一种死法,不是没人用,而是用得越多亏得越多,自己却不知道亏在哪。月底 OpenAI/Anthropic 账单 5 万,你打开后台一看——只有一个总数。这 5 万里,哪个功能烧的?哪个用户烧的?哪种调用最贵?一问三不知。
这就是没有成本归因的状态。token 成本控制(怎么省)是另一篇文章的事,本文只讲一件事:怎么把这一笔糊涂账,拆成可优化、可问责的财务数据。
一、为什么 AI 成本必须归因:可变成本 + 高方差
AI 应用的成本结构跟传统软件根本不同。传统 SaaS 的边际成本趋近于零——多一个用户,服务器分摊下来的增量可以忽略。但 AI 应用是可变成本:每一次 LLM 调用都真金白银,调一次烧几厘,一天几百万次就是几万块。
更麻烦的是高方差。同一个"智能助手"功能,张三问一句"你好"烧 50 token,李四丢一份 50 页 PDF 让它总结,烧 5 万 token。两者差 1000 倍。传统软件用均值思维就够,AI 成本必须用分布思维——尾部那 1% 的请求,经常吃掉你一半的账单。
所以不归因,你面对的是这些盲区:
- 产品经理说"加个 AI 摘要功能不贵吧",上线两周它单独烧了 2 万,你才知道。
- 某大客户每天调用 10 万次,你以为他在正常使用,其实成本已经超过他付的年费。
- 一个 prompt 回归让单次 token 涨了 3 倍,功能照常工作、零报错,你三周后才在账单上发现。
- 免费用户里有个脚本党,一晚上刷掉 8000 美元。
归因的本质,是把供应商给你的那一笔总数,拆成几万条带标签的原子记录,然后按任意维度聚合。归因不是目的,优化才是——知道哪个功能亏、哪个用户重、哪种调用贵,你才知道该砍什么、限什么、改什么 prompt。
二、按请求打标:每次 LLM 调用必须自带 metadata
归因的起点是打标(tagging)。每一次 LLM 调用,都必须带上一组 metadata,告诉计量系统:这次调用谁触发的、属于哪个功能、在什么上下文里。
不打标,你只有一笔总账(供应商 invoice 上那个数字)。打了标,才能把它拆开。一个够用的打标 schema:
interface LLMCallTags {
// 谁
userId: string; // 用户 ID
orgId: string; // 组织/团队(B2B 必须)
// 什么功能
feature: string; // 'chat' | 'summarize' | 'code-review' | ...
featureVersion: string; // 'summarize-v2',便于 A/B 对比成本
experimentId?: string; // feature flag / 实验桶
// 什么上下文
sessionId: string; // 会话 ID,聚合一整段对话
requestId: string; // 请求 ID,串起完整调用链
// 业务上下文
tier?: string; // 'free' | 'pro' | 'enterprise'
channel?: string; // 'web' | 'api' | 'mobile'
}
打标必须在调用入口完成,不能事后补。最干净的做法是走统一 LLM 网关——所有调用必须经过它,入口注入 tags,出口把计费结果连同 tags 一起落库。这叫"计量单点收敛"。
// 反面教材:业务代码各处直接调 SDK,必然有漏打标的
const res = await openai.chat.completions.create({ ... });
// 正面教材:走统一网关,强制带 tags,没 tags 直接拒
const res = await llmGateway.chat({
model: 'gpt-4o',
messages,
tags: { userId, feature: 'summarize', sessionId, tier },
});
// 网关内部:记录 prompt/completion token、算钱、把 tags 写入计量表
只要你允许业务代码各处直接 openai.chat.completions.create(),就一定有调用漏打标,归因数据永远对不齐账单。统一网关是归因可信的前提,这是硬约束,不是 nice-to-have。
三、token 计量:输入输出分开记,按模型系数换算成钱
打标解决"这次调用归给谁",计量解决"这次调用值多少钱"。
1. token 必须分开记
LLM 计费的基本规律:输入和输出单价不同,输出通常贵 3-5 倍。必须分开记,不能记总数。同时单独记缓存命中(prompt cache 有大幅折扣,不单独记就看不到这块收益)。
interface UsageRecord {
tags: LLMCallTags;
model: string;
promptTokens: number; // 输入 token
completionTokens: number; // 输出 token
cachedTokens: number; // 命中缓存的 token(折扣价)
latencyMs: number;
timestamp: number;
}
token 数从哪来?用供应商响应里的 usage 字段,别自己估算。自己估算永远跟账单对不上,归因就不可信。
2. 按模型计费系数换算成钱
每个模型单价不同,还会变(供应商调价)。所以需要一张计费系数表,做成配置而非硬编码:
const PRICING = {
'gpt-4o': { input: 2.5, cached: 1.25, output: 10 }, // $ / 1M tokens
'gpt-4o-mini': { input: 0.15, cached: 0.075, output: 0.6 },
'claude-sonnet': { input: 3, cached: 0.3, output: 15 },
};
function computeCost(u: UsageRecord): number {
const p = PRICING[u.model];
return (u.promptTokens - u.cachedTokens) * p.input / 1e6
+ u.cachedTokens * p.cached / 1e6
+ u.completionTokens * p.output / 1e6;
}
这张表要可热更新——供应商今天宣布降价,你明天就能在归因数据里反映,而不是等下次发版。
3. 聚合到各维度
原始 usage 是事件流,查询时现算太慢。常规做法是预聚合:按 (feature × user × model × day) 这样的维度做 rollup,存到 OLAP / 数仓。看板秒级响应,就靠这些预聚合表撑着。
四、三层归因:功能、用户、请求类型
打好标、算好钱,同一份数据能从三个维度切,回答三个不同的问题。
第一层:按功能——哪个 feature 在烧钱?
| 功能 | 调用次数 | 总成本 | 单次均价 | 占比 |
|---|---|---|---|---|
| chat | 1.2M | $18,000 | $0.015 | 36% |
| summarize | 800K | $14,000 | $0.0175 | 28% |
| code-review | 300K | $12,000 | $0.04 | 24% |
| translate | 2M | $6,000 | $0.003 | 12% |
这张表立刻暴露问题:code-review 调用次数不多,单次均价却是 chat 的近 3 倍——为什么?prompt 太长?用了贵模型?输出没收住?按功能归因,直接帮你定位优化 ROI 最高的功能。砍掉一个亏本功能,比优化十个 prompt 更直接。
第二层:按用户——谁在烧钱?
| 用户分位 | 人数 | 成本占比 | 人均成本 |
|---|---|---|---|
| Top 1%(重度) | 100 | 47% | $235 |
| Top 10% | 1,000 | 81% | $49 |
| 中位数用户 | 5,000 | 18% | $2 |
| 长尾用户 | 9,900 | 1% | $0.05 |
AI 应用的成本分布几乎都是重尾——少数重度用户吃掉大部分成本。这张表直接决定商业模式能不能跑通:Top 1% 用户人均成本 $235,但他们付的订阅费只有 $20/月,那这产品用户越多亏越多。
按用户归因还能识别两类问题用户:滥用者(脚本刷接口,爬你的能力)和异常用户(正常账号但使用模式奇怪,比如每次都贴超长上下文)。这两类都得靠阈值告警抓。
第三层:按请求类型——哪种调用贵?
同样是"chat"功能,内部还分带工具调用的、带 RAG 检索的、多轮长对话的。这一层把功能成本进一步拆成调用模式成本:
- 带 function calling 的请求,要喂工具 schema,prompt token 是普通请求的 3 倍。
- RAG 请求如果召回 20 条文档,prompt 塞了 15K token,实际有用只有 2K——检索质量在烧钱。
- 多轮对话不压缩历史,第 10 轮 prompt 是第 1 轮的 8 倍长。
这一层直指具体优化点:裁剪工具 schema、提升检索精度、压缩对话历史。
五、单位经济:算清楚哪些赚、哪些亏
归因的终极目的是算单位经济(unit economics):每个用户、每个功能到底赚不赚钱。这是商业决策的输入,不是技术自嗨。
单用户:LTV vs 服务成本
| 用户分层 | 月付费 | 月服务成本 | 毛利 | 毛利率 |
|---|---|---|---|---|
| Free | $0 | $0.8 | -$0.8 | 亏损(靠转化补) |
| Pro | $20 | $5 | $15 | 75% |
| Team | $50 | $12 | $38 | 76% |
| Enterprise | $500 | $180 | $320 | 64% |
关键洞察:付费层级越高,服务成本占比反而可能上升——因为重度用户用得最多。Enterprise 营收最高,毛利率却可能比 Pro 还低。这不是说不做 Enterprise,而是要么提价、要么限流、要么优化他们的使用模式。
单功能:毛利
把功能成本和它"驱动收入"配对。summarize 烧 1.4 万/月——它驱动了多少付费转化?是 Pro 套餐核心卖点、贡献 30% 升级,那它毛利为正;只是免费用户玩玩的玩具、不带来收入,那就是纯成本中心,该砍或该收费。
单位经济让你从"这个功能花了多少钱"升级到"这个功能值不值得做"。这是从工程视角到产品/商业视角的跨越,也是归因数据最有价值的一跳。
六、异常检测:谁在烧钱,立刻告警
归因的另一个核心价值是实时发现异常。AI 成本 bug 比传统软件更隐蔽——一个 prompt 改动让 token 翻倍,不会有任何报错,功能照常工作,只有账单会尖叫。必须建立三类告警:
- 用户级:某用户今日成本 > 过去 7 天日均的 5 倍。抓滥用、抓脚本、抓异常使用。前文那个一晚烧 8000 美元的脚本党,没有告警就只能等月底账单。
- 功能级:某功能单次均价突增 50% 以上。通常是 prompt 回归(加了无关上下文)、默认模型被改成贵的、或上游 bug(检索系统召回爆炸)。
- 全局级:总体日成本偏离预测超过 30%。多半是流量突涨(被 KOL 推荐)或某类请求 token 整体上升。
阈值要绝对值和相对值结合。绝对值("单次成本 > $0.5")抓明显异常调用;相对值("比日均高 5 倍")抓趋势变化。两者结合,漏报和误报都能压住。
七、落地:统一中间件 + 数据仓库 + 成本看板
把上面所有东西串起来,落地架构分三层。
第一层:计量中间件(在线)
所有 LLM 调用必经的网关。职责:强制注入 tags(没 tags 拒绝)→ 调用后取 usage 算 cost → 异步写事件流(Kafka/Kinesis)→ 同步做预算检查(用户当日预算耗尽就限流)。关键还是单点收敛,必须成为 LLM 调用的唯一出口。
第二层:数据仓库聚合(离线)
事件流进数仓(Snowflake/BigQuery/ClickHouse),做两件事:存原始 usage(留 1-2 年,供深度分析)+ 预聚合 rollup 表(按 day × feature × user 等维度)。为什么不用业务库直接查?因为成本分析经常跑"过去 90 天 Top 1000 用户趋势"这种重查询,放业务库会拖垮线上。
第三层:成本看板 + 告警(展示)
至少三张看板:总览(日/月总成本、按功能堆叠、按模型分布、预测月终成本)、下钻(用户成本榜、功能下钻到调用类型、时间序列趋势)、异常(实时告警、异常用户/功能、预算消耗进度)。消费者不只是工程师——产品、运营、财务都要看。归因是跨部门的事,数据得让非技术角色也读得懂。
闭环:用归因结果驱动优化
归因不是终点,优化才是。归因数据要能驱动这些决策:
code-review毛利率为负 → 换便宜模型 / 限制上下文 / 纳入高阶套餐。- 某 Top 用户人均成本 $235 只付 $20 → 分级限流 / 推 Enterprise。
- RAG 请求塞 15K token 只用 2K → 优化检索召回,裁剪上下文,直接省 60%。
summarize-v2比v1成本高 40% 但效果没明显提升 → 回滚,或继续调 prompt。
这就是归因的闭环:打标 → 计量 → 归因 → 看板 → 决策 → 优化 → 再观察。每一轮循环,成本就更可控一分。
小结
- AI 成本是可变成本 + 高方差,不归因就是糊涂账。 尾部 1% 的请求可能吃掉一半账单,均值思维在这里完全失效。
- 打标是归因的起点。 每次调用必须带 feature/user/session/experiment 等 metadata,通过统一网关强制注入,否则数据一定有漏洞。
- token 分输入输出单独记,按模型系数算钱,预聚合到多维度。 原始事件留全,rollup 表供查询——这是看板秒级响应的基础。
- 三层归因回答三个问题:功能(哪个烧)、用户(谁烧)、请求类型(哪种贵)。单位经济把它们换算成"赚不赚钱",驱动商业决策。
- 异常检测防滥用、防 bug 烧钱。 用户级、功能级、全局级告警,绝对值 + 相对值结合,别等月底账单才发现。
金句:没有归因的 AI 成本是成本,有归因的 AI 成本是杠杆。 把糊涂账拆成有标签的原子数据,你才知道该砍什么、提什么价、优化哪个 prompt——AI 成本从"失控的黑盒"变成"可优化的财务仪表盘",这一步就是从烧钱到赚钱的分水岭。
Related