
大模型费用从"平台兜底的公共开支"变成"需要说清楚的账",通常只隔一个季度。几十条业务线接进来,每日 Token 消耗冲到数十亿级,月末账单只剩一个总数:哪个部门在膨胀、哪个模型在漏水、哪个项目 ROI 已经转负,全部无从回答。问题根源在于计费模型的三维不对称,传统微服务调用量统计照搬不过来。
三维不对称:为什么总 Token 数没用
第一是输入输出单价差。主流商用模型的补全 Token 价格是输入的 3 到 5 倍,只统计总量等于放弃真实金额。第二是缓存折扣非线性。KV Cache 命中的输入 Token 通常只要 1 到 2 折,网关若不能把 Cache Read 与 Cache Write 剥离计量,分摊结果能出现八成的系统性偏差。第三是归属断层。后台长流程智能体跨多个微服务级联调用,入口网关不统一注入租户上下文(TenantId、BizLine、ProjectCode、UserId),底层日志就是溯源不了的黑盒。
还有一个容易漏掉的点:流式输出的 Token 数是在响应过程中逐帧累加的,网关必须在最后一帧发出的瞬间锁定数值完成折算,否则高并发下计量与真实响应会出现滑差。
数仓建模:宽表怎么设计
链路采用"网关本地环形缓冲 + 消息队列削峰 + 向量化存储"的分层。ClickHouse 侧按月分区的明细宽表是核心:
CREATE TABLE ai_token_billing_detail (
call_time DateTime64(3,'Asia/Shanghai') CODEC(DoubleDelta,LZ4),
trace_id String CODEC(ZSTD),
tenant_id LowCardinality(String) CODEC(ZSTD),
biz_line LowCardinality(String) CODEC(ZSTD),
project_code LowCardinality(String) CODEC(ZSTD),
provider LowCardinality(String) CODEC(ZSTD),
model_name LowCardinality(String) CODEC(ZSTD),
prompt_tokens UInt32 CODEC(T64,LZ4),
completion_tokens UInt32 CODEC(T64,LZ4),
cached_prompt_tokens UInt32 CODEC(T64,LZ4),
unit_prompt_price Decimal64(6) CODEC(ZSTD),
unit_comp_price Decimal64(6) CODEC(ZSTD),
unit_cache_price Decimal64(6) CODEC(ZSTD),
cost_amount Decimal64(6) CODEC(ZSTD),
http_status UInt16 CODEC(T64,LZ4)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(call_time)
ORDER BY (biz_line, project_code, model_name, call_time);
维度字段必须上 LowCardinality 字典编码,跨数十亿行聚合时内存和 CPU 能省七成以上。金额统一 Decimal64(6)——单次调用费用可能只有万分之几元,用浮点累加到月底能差出几千元的对账缺口,这种错没人愿意背。
网关侧计费的三个纪律
计费计算器在 Java 侧对应三条硬规则。其一,可计费输入要扣除缓存命中:billablePrompt = max(0, promptTokens - cachedTokens),三段分别乘各自单价再求和,全程 BigDecimal 保留 6 位小数。其二,结算钩子只做内存操作,事件经无锁环形队列异步进 Kafka,网关线程不做任何网络 I/O,避免计量拖垮转发。其三,价格矩阵放配置中心动态刷新,换供应商或调价时不用发版。
两个实战切片
成本黑洞排查一条 SQL 就够:
SELECT biz_line, project_code, model_name,
COUNT(1) AS req,
ROUND(SUM(cached_prompt_tokens)*100.0/NULLIF(SUM(prompt_tokens),0),2) AS cache_hit_pct,
ROUND(SUM(cost_amount),2) AS expense
FROM ai_token_billing_detail
WHERE call_time >= now() - INTERVAL 1 DAY
GROUP BY biz_line, project_code, model_name
ORDER BY expense DESC LIMIT 10;
缓存命中率列是排雷利器:某文档搜索系统曾在检索提示词里拼 64KB 冗余元数据且不做前缀对齐,命中率长期为 0,五十人的项目单日烧掉一万二。把命中率作为看板固定列,这类缺陷当天就能暴露。
模型替换裁决用灰度对比:同一任务 50% 流量切到国产模型,每千 Token 成本从 0.035 元降到 0.004 元,降幅 88.5%,再叠加业务满意度打标无显著差异——这组数字比任何 PPT 都有说服力。
防御性设计:别让账单被人做手脚
租户标签来自 HTTP Header 时必须强校验:客户端 API-Key 与租户、项目绑定关系在网关本地白名单核验,非法标签强制覆写并记审计日志,否则总有项目组会把成本挂到别的部门头上。
运维侧还要盯两件事:Kafka 积压会让账单延迟数小时,月末结算窗口需监控消费 lag;供应商临时调价若价格表未同步,折算金额会整体漂移,建议每日用抽样请求对账真实账单。每分钱都能定位到团队与场景,成本治理才谈得上精细化。

评论0