跳到主要内容

Token FinOps:将 AI 支出归因到具体功能

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的云账单可以具体到标签,告诉你上个月一个被遗忘的 S3 存储桶花费了 14,000 美元。但如果你问 LLM 账单同样的问题——到底是哪个功能烧掉了价值 40,000 美元的 token——大多数公司的真实反应只能是耸耸肩。供应商的发票上每个模型、每个 API 密钥只有一行记录,而三个团队共享这个密钥,财务报表中的 “AI 成本” 行则是根据人头、感觉,或者在上次规划周期中抱怨最少的人来分摊的。

这不仅仅是一个小的簿记烦恼。当没人能说出每一美元的 token 支出背后具体对应哪个功能时,会出现两种失败模式。低成本的功能被限制了,因为它们与昂贵的功能共用一个预算额度。而真正浪费的功能却永远存在,因为它们的成本是隐形的——被分摊到了共享的密钥、共享的缓存以及服务于六个不同产品界面的共享智能体(agent)循环中。

FinOps 基金会 2026 年的调查发现,目前 98% 的组织都在积极管理 AI 支出,而一年前这一比例为 63%,再前一年仅为 31%——这是该基金会有记录以来最快的采用曲线。每个人突然都在做 “AI 领域的 FinOps”。但很少有人注意到,云 FinOps 的核心原语——资源标签(resource tag)——在 token 的世界里并不存在,而且现代 LLM 使用的三个特定机制正活跃地破坏着成本归因。

为什么云 FinOps 的玩法在 token 上失效了

云成本分配之所以有效,是因为支出与资源挂钩,而资源是持久的、可命名的实体。一个 EC2 实例会存在数月;你只需打一次标签,它运行的每一小时都会继承这个标签。账单导出时,标签列已经填充好了。

Token 支出则挂钩在**调用(calls)**上。一次调用只持续几秒钟,不属于任何资源,在发票上仅以聚合形式出现:这个 API 密钥、这个模型、多少输入和输出 token、多少美元。如果你没有在调用发生的那一刻记录是哪个功能发起的,那么这个信息就丢失了。没有追溯性的标签,也没有你可以下周运行的 “describe-instances” 来重构谁做了什么。

这种反转改变了工程问题。云 FinOps 主要是报告问题——数据已经存在,你只需要组织它。Token FinOps 则是**遥测(telemetry)**问题——除非你的代码主动发送数据,否则数据就不存在,且每个请求都必须如此,永远如此。这意味着归因系统存在于你的请求路径中,由产品工程师而非中央 FinOps 团队维护,并且每当有人在没有标签的情况下发布新的调用点时,系统就会失效。

即使是完美的人均请求标签也只能解决一半问题,因为三种常见的成本效率机制会将原本属于单次调用的支出变为集体支出。

三个归因杀手

共享提示词缓存(Shared prompt caches)。 提示词缓存是降低推理成本的最大杠杆——在 Anthropic 上,缓存的输入 token 费用约为基础费率的 10%,在 OpenAI 上则为一半甚至更低。但其会计处理非常诡异。在 Anthropic 上,写入(write)缓存需要支付溢价——为五分钟的 TTL 支付标准输入费率的 1.25 倍——而后续的读取(read)费用仅为 0.1 倍。因此,第一个触及共享系统提示词的功能支付了额外费用来构建缓存,而其他所有功能之后都能以 90% 的折扣读取。第一个调用者补贴了所有人。

如果你的仪表盘简单地按调用归因成本,那么在每次缓存过期后恰好第一个运行的功能看起来会比第二个运行的完全相同的功能贵 10 倍。这种差异并非真实存在的,完全取决于缓存轮转的顺序。

批处理调用(Batched calls)。 批处理 API 提供约 50% 的折扣以换取异步处理,因此具有成本意识的团队会将请求(通常跨功能,有时跨租户)聚合到单个密钥下的单次提交中。发票只看到一个批处理。而你的六个功能看到了六个不同的工作负载。除非批处理层记录了每个功能为每个批处理贡献了多少 token,否则折扣和成本都会被分摊到共享管道的所有人身上,贡献了 80% token 的功能在账单上看起来与贡献了 2% 的功能是一样的。

多租户智能体(Multi-tenant agents)。 在智能体工作负载中,归因从困难变成了极具挑战。微软研究院最近对智能体编码任务的一项研究发现,同一任务的运行在总 token 消耗上差异可达 30 倍,智能体任务消耗的 token 比普通的聊天或代码推理调用多出约 1,000 倍,而且输入 token(而非输出)占据了账单的主导地位,数量是输出 token 的 20–25 倍。对于希望制定预算的人来说更糟的是:前沿模型无法预测自己的 token 使用情况(相关性仅约为 0.39),人类专家对任务难度的估计也几乎与实际支出无关。

现在,将一个智能体循环放在六个产品功能之后。循环会跨工具调用积累上下文,因此询问第五个问题的功能的边际成本包含了前四个问题的对话负担。由一个功能的不可靠工具触发的重试风暴(retry storm)会增加共享该循环的所有功能的输入 token 账单。此时,按调用归因在技术上是准确的,但在经济上却毫无意义。

计量准则:在调用处打标签,根据响应计数

修复方案并不华丽,它分为三个层级,跳过其中任何一层都会导致仪表盘自信地得出错误结论。

第一,将身份标识透传到每一次调用中。 每一次 LLM 请求至少需要携带:功能(feature)、租户或客户(tenant/customer)、环境(environment)以及团队或成本中心(team/cost center)。FinOps 基金会的从业者指南建议,团队、项目、环境、模型和成本中心这五个维度可以覆盖 95% 的分摊计费(chargeback)用例。实现机制并不如强制执行重要:通过 LLM 网关(如 LiteLLM、Helicone、Portkey 或你自己的代理)为每个功能签发虚拟密钥是最稳健的模式,因为附加在密钥上的标签会自动流转到该密钥发起的每一次请求中。这样没人需要记住传递元数据,而且没有有效密钥的请求根本无法通过。

依赖每个工程师记住参数的打标签方式只能达到 60% 的覆盖率并陷入停滞。在网关层强制执行的标签方案在第一天就能达到 100% 的覆盖率。

第二,根据 API 响应计算 Token,绝不要依赖估算。 响应体中的 usage 字段——以及它在 OpenTelemetry GenAI 语义规范中的对应项 gen_ai.usage.input_tokensgen_ai.usage.output_tokens——是权威的计量标准。客户端的分词器(tokenizer)估算会随着模型版本的变化而产生偏差,且会漏掉系统提示词(system prompt)的开销;基于响应的计数与实际账单的误差通常在 1–3% 以内。请分别记录输入和输出(它们的定价不同,通常相差 4-5 倍),并将缓存读取(cache-read)、缓存写入(cache-write)和批量折扣(batch-discounted)的 Token 作为独立类别记录,而不是将其并入“输入”中。存储这些计数和标签;不要将原始提示词和补全结果与它们存放在一起——否则你会在没有获得任何归因收益的情况下,将计费管道变成敏感数据的风险源。

第三,在 Span 级别而非请求级别进行计量。 对于 Agent,映射到功能的单位不是 API 调用,而是追踪的任务(traced task):该 Agent 的运行代表某项功能进行了 11 次模型调用和 4 次工具调用,总成本为 0.87 美元。OpenTelemetry 的 GenAI 规范之所以存在,正是为了让每次模型调用都成为一个带有 Token 属性的 Span,并通过追踪(trace)将这些 Span 关联到原始请求。如果没有 Span 级别的计量,你只能说出 Agent 集群消耗了多少成本;有了它,你就能说出该功能的这项任务消耗了多少成本——而这正是每个下游决策所需的数字。

分配是政策决策,而非测量问题

这是工程团队经常搞错的地方:一旦计量变得诚实,剩下的争议就不再是技术问题了。谁来承担缓存写入的溢价?如何拆分批量折扣?如何处理 Agent 积累的共享上下文?没有任何测量手段能回答这些问题——它们属于会计政策,目标是简单且一致,而非绝对公平。

以下是一些可行的默认规则,大致按推荐程度排序:

  • 缓存写入(Cache writes):社会化分摊。将写入溢价折算成所有缓存读取流量的小额间接费用,这样就不会惩罚那个恰好在每次过期后重新填充缓存的功能。将写入费用归于第一个调用者虽然精确,但会产生负向激励。
  • 批量折扣(Batch discounts):按 Token 贡献比例分配。批次中的每个功能按其在折扣总额中的 Token 占比付费。这要求批处理层保留每个项目的溯源信息——请在第一天就构建好这个功能,因为事后补救意味着要重放你未记录的历史。
  • 共享 Agent 上下文:对任务收费,摊销配置成本。无论哪个功能发起请求都存在的系统提示词、工具 schema 和检索到的上下文,应被视为类似缓存写入的间接开销;而由功能自身提问生成的 Token 则直接计费。
  • 预置吞吐量(Provisioned throughput):如果你购买了跨用例共享的专用容量,FinOps 基金会的公式——实际费率按 (2 − 利用率) 乘以消耗的 Token 进行缩放——可以分摊固定成本,使得低利用率会明显推高每个人的单位价格,而这正是你希望采购决策能看到的信号。

在进行第一次分摊计费对话之前写下这些规则,而不是在对话过程中。一旦涉及到真实的预算变动,每个团队都会变成你分配方法的积极审计员,而“我们提前决定并统一执行”是唯一站得住脚的立场。

先展示计费,再实际扣费——关注单位成本,而非总支出

抵制立即向团队收费的冲动。标准的顺序是:先运行展示计费(showback)——即生成报告展示每个功能本应被收取的费用,但不发生资金转移——持续四到六周。展示计费可以在低风险的情况下排查出标签缺失、未打标签的遗留调用点以及分配中的边缘情况。一旦标签覆盖率稳定在 80% 以上且数据不再让人感到意外,再转向实际扣费(chargeback),让成本真正落地到团队预算中。

然后改变你的告警对象。AI 总支出是一个糟糕的信号——它会随着产品的成功而增长,40% 的月度增长可能是一个大好消息。能够发现真实问题的数字是每个功能的单位成本:每项任务、每次对话、每个处理文档的成本。检索方式的改变导致上下文长度翻倍、提示词修改破坏了缓存前缀对齐、Agent 开始重复尝试失效的工具——这些都不会在第一天改变总支出到触发告警的程度,但它们会立即在受影响功能的单位任务成本波动中显现出来。

最后,为你现在已知存在的波动制定预算。考虑到 Agent 任务在不同运行间可能存在 30 倍的差异,且模型无法预测自身的消耗,确定性预算只是幻想。针对 2026 年的 Agent 工作负载,从业者指南建议在建模支出之外预留 20-40% 的储备金,并明确报告消耗情况——将 Token 视为受天气影响的公用事业(如水电),而不是 SaaS 的坐席数。

能说清成本的功能才能上线

Token FinOps 通常被宣传为成本“控制”,这听起来像是那个只会说“不”的部门。但在实践中,因果关系恰恰相反。能够将支出归因于具体功能的团队,才是能够“捍卫”支出的团队:他们可以证明,那个昂贵的 Agent 功能带来的留存价值是其 Token 账单的 12 倍,砍掉那些入不敷出的功能,并将差额重新投入。而那些无法进行归因的团队,最终会面临一刀切的削减成本指令,这在清理浪费的同时也会扼杀那些成功的项目。

操作流程其实很乏味:在网关处强制执行身份验证,在 span 级别统计响应中的 Token,在资金支出前发布缓存和批处理的分配规则,运行费用分摊(showback)直到标签可信,并对单位成本漂移发出警报。这些都不是什么科研课题。但所有这些都必须在你那份 AI 账单变成 CFO 重点质询的条目 之前 就准备就绪 —— 因为到那时,你需要打标签的调用已经发生,而那些数据已经不复存在了。

References:Let's stay in touch and Follow me for more thoughts and updates