
内部各业务线 Token 账单透明化基于 ClickHouse 的多维聚合与成本看板月底收到大模型供应商寄来的七位数账单时集团财务总监直接冲进了基础架构部门的办公室。账单上只有一行冰冷的总数字和全球统一的价格核算但对于全公司三千多个微服务、上百个业务研发团队而言这笔钱究竟是谁花掉的、花得值不值、有没有在非生产环境恶意刷量完全是一笔死账。这就是典型的大模型落地“公地悲剧”。由于初期缺乏精细化计量与内部成本分摊机制Showback Chargeback各业务线把大模型当成了免费的无底洞算法团队在测试环境跑大规模回测调用线上千亿参数大模型刷了上亿 Token某个早已经下线废弃的内部运营活动定时脚本每天依然在定时调用大模型做长文本摘要某些低优先级报表业务调用顶级昂贵模型而核心高价值场景反而因为配额紧张捉襟见肘。没有透明可下钻的成本账单任何降本增效都只能沦为口号。在大并发大模型网关背后必须有一套毫秒级响应、支持任意维度切片下钻的计量聚合分析引擎。我们基于 ClickHouse 构建了全链路 Token 账单看板将每一厘钱的算力消耗精准锁定到部门、服务乃至具体的接口负责人。传统日志分析方案在大模型计量中的溃败许多团队试图沿用传统的 Elasticsearch Kibana 方案来记录和分析网关的访问日志。但当公司内部大模型调用量冲破每天数千万次、涉及数十个维度下钻时传统日志架构遇到了三大致命瓶颈存储膨胀与成本倒挂ES 基于倒排索引的设计对于高基数High Cardinality字段如request_id、user_id、trace_id有着恐怖的索引膨胀率。记录完整的 Token 计量日志其存储和维护成本甚至快赶上了大模型本身的费用本末倒置。多维聚合查询缓慢财务和各业务线负责人最关心的查询往往是“按月份、按部门、按模型类别聚合总 Prompt Token、总 Completion Token 以及折算总成本”或者“查询过去 24 小时环比消耗暴增 Top 5 的应用”。在 ES 中进行这种长周期的多字段terms-stats聚合经常触发集群 GC 抖动甚至 OOM 查询超时。数据补账与版本迭代困难模型供应商的单价经常变动例如模型降价 50%或者夜间时段打折。如果存储层没有支持高效数据覆写与物化视图动态重算的能力价格规则一变历史账单全得人工写脚本离线重跑。ClickHouse 多维计量架构与预聚合流水线为了实现高性能与低成本的兼得我们采用“网关异步产出轻量事件 - Kafka 削峰解耦 - 向量化写入 ClickHouse - 物化视图自动预聚合”的整体流水线。[ 网关层 LLM Gateway ] │ (流式结束异步触发) ▼ ┌────────────────────────────────────────────────────────┐ │ Usage Event: { tenant, dept, app, model, tokens, ms } │ └──────────────────────────┬─────────────────────────────┘ │ 批量写入 (Batch 1000条/次) ▼ [ Kafka 计量削峰队列 ] │ ▼ ┌────────────────────────────────────────────────────────┐ │ ClickHouse 列式存储集群 │ │ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ 1. llm_usage_detail_local (明细日志表) │ │ │ │ - 采用 ZSTD 高压缩比, 存储原始请求维度信息 │ │ │ └──────────────────────────┬───────────────────────┘ │ │ │ 触发物化视图 │ │ ▼ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ 2. mv_llm_dept_cost_hourly (小时级部门成本聚合) │ │ │ │ - SummingMergeTree 引擎, 预聚合 Token 与费用 │ │ │ └──────────────────────────────────────────────────┘ │ └─────────────────────────────┬──────────────────────────┘ │ ▼ [ Grafana / 内部资产运营看板 / 财务自动分摊系统 ]ClickHouse 的列式存储天然适合纯数值聚合计算结合 ZSTD 压缩算法明细数据压缩比高达 8:1 至 12:1配合SummingMergeTree引擎可以在数据写入瞬间以后台合并树的方式完成按小时、按租户维度的指标预聚合看板查询延迟直接缩减至 15ms 以内。ClickHouse 表结构与高性能物化视图 DDL以下是经过线上百亿级数据验证的核心计量表结构设计-- 1. 原始大模型调用计量明细表 (按月分区, 按租户与时间排序) CREATE TABLE default.llm_usage_detail_local ( event_time DateTime64(3, Asia/Shanghai) CODEC(DoubleDelta, ZSTD(1)), trace_id String CODEC(ZSTD(3)), department_id LowCardinality(String) CODEC(ZSTD(1)), tenant_id LowCardinality(String) CODEC(ZSTD(1)), application_name LowCardinality(String) CODEC(ZSTD(1)), model_name LowCardinality(String) CODEC(ZSTD(1)), provider LowCardinality(String) CODEC(ZSTD(1)), prompt_tokens UInt32 CODEC(T64, ZSTD(1)), completion_tokens UInt32 CODEC(T64, ZSTD(1)), total_tokens UInt32 CODEC(T64, ZSTD(1)), cost_micros UInt64 CODEC(T64, ZSTD(1)), -- 实际核算成本(微元, 1元 1,000,000微元) duration_ms UInt32 CODEC(T64, ZSTD(1)), http_status UInt16 CODEC(ZSTD(1)) ) ENGINE MergeTree() PARTITION BY toYYYYMM(event_time) ORDER BY (department_id, tenant_id, application_name, model_name, toDate(event_time), event_time) SETTINGS index_granularity 8192; -- 2. 面向成本看板的小时级物化聚合表 CREATE TABLE default.llm_usage_hourly_agg ( window_hour DateTime(Asia/Shanghai), department_id LowCardinality(String), tenant_id LowCardinality(String), model_name LowCardinality(String), call_count UInt64, sum_prompt_tokens UInt64, sum_comp_tokens UInt64, sum_total_tokens UInt64, sum_cost_micros UInt64 ) ENGINE SummingMergeTree() PARTITION BY toYYYYMM(window_hour) ORDER BY (department_id, tenant_id, model_name, window_hour); -- 3. 自动同步更新的物化视图 CREATE MATERIALIZED VIEW default.mv_llm_usage_hourly_agg TO default.llm_usage_hourly_agg AS SELECT toStartOfHour(event_time) AS window_hour, department_id, tenant_id, model_name, count() AS call_count, sum(prompt_tokens) AS sum_prompt_tokens, sum(completion_tokens) AS sum_comp_tokens, sum(total_tokens) AS sum_total_tokens, sum(cost_micros) AS sum_cost_micros FROM default.llm_usage_detail_local GROUP BY window_hour, department_id, tenant_id, model_name;Go 1.27.1 网关异步非阻塞事件汇聚管道在网关处理流式响应的同时必须确保计量逻辑绝不阻塞用户的文本接收。采用环形无锁缓冲队列异步批量下发package meter import ( context sync time ) // LLMUsageEvent 单次模型调用计量凭证 type LLMUsageEvent struct { EventTime time.Time json:event_time TraceID string json:trace_id DepartmentID string json:department_id TenantID string json:tenant_id ApplicationName string json:application_name ModelName string json:model_name Provider string json:provider PromptTokens uint32 json:prompt_tokens CompletionTokens uint32 json:completion_tokens TotalTokens uint32 json:total_tokens CostMicros uint64 json:cost_micros DurationMs uint32 json:duration_ms HTTPStatus uint16 json:http_status } // AsyncUsageCollector 异步高吞吐批量收集器 type AsyncUsageCollector struct { queue chan *LLMUsageEvent batchCap int flushInt time.Duration wg sync.WaitGroup ctx context.Context cancel context.CancelFunc } func NewAsyncUsageCollector(bufferSize, batchCap int, flushInterval time.Duration) *AsyncUsageCollector { ctx, cancel : context.WithCancel(context.Background()) c : AsyncUsageCollector{ queue: make(chan *LLMUsageEvent, bufferSize), batchCap: batchCap, flushInt: flushInterval, ctx: ctx, cancel: cancel, } c.wg.Add(1) go c.workerLoop() return c } // Emit 非阻塞触发计量投递若队列打满则走降级旁路绝不阻塞用户通信 func (c *AsyncUsageCollector) Emit(event *LLMUsageEvent) { select { case c.queue - event: default: // 记录本地告警计数器避免队列满拖垮网关 } } func (c *AsyncUsageCollector) workerLoop() { defer c.wg.Done() ticker : time.NewTicker(c.flushInt) defer ticker.Stop() batch : make([]*LLMUsageEvent, 0, c.batchCap) for { select { case -c.ctx.Done(): c.flushBatch(batch) return case event : -c.queue: batch append(batch, event) if len(batch) c.batchCap { c.flushBatch(batch) batch make([]*LLMUsageEvent, 0, c.batchCap) } case -ticker.C: if len(batch) 0 { c.flushBatch(batch) batch make([]*LLMUsageEvent, 0, c.batchCap) } } } } func (c *AsyncUsageCollector) flushBatch(batch []*LLMUsageEvent) { if len(batch) 0 { return } // 批量写入 Kafka 计量 Topic由 ClickHouse Kafka Engine 自动摄入 }生产落地的成本看护与治理机制在数据看板上线后算力成本的精细化运营需要建立三套联动机制1. 异动检测与自动化熔断告警基于 ClickHouse 小时级视图配置定时巡检规则若某应用最近 1 小时的 Token 消耗量环比昨天同期暴增超过 300%且绝对成本超过 5,000 元系统自动在钉钉/企微群组中艾特服务负责人并同步下调该应用在网关的突发配额系数。这一机制曾成功拦截过一次因为业务研发手误把压测脚本指向生产模型的事故直接挽回数十万元算力损失。2. 精确到微元的阶梯定价核算各大模型供应商的模型调用计费差异巨大输入和输出单价通常相差 3 倍以上。在数据库中统一采用整数cost_micros微元即百万分之一元记录消除浮点数累计运算导致的精度丢失。无论是按实际供应商采购价计费还是按照内部指导价做预算结算均可通过标准 SQL 高速重算。3. 成本透明化驱动业务架构自优化有了直观的看板后原本无人关心的 Prompt 冗余问题被业务团队主动攻坚。当客服团队看到自己部门一个月在 Prompt 前缀重复传参上烧掉了上百万元时主动发起了上下文缓存Context Caching与小模型前置过滤改造在业务效果完全不变的前提下成功将该场景的整体 Token 消耗砍掉了 58%。看得清成本才谈得上驾驭算力。把算力账单晒在阳光下是架构师为大模型在企业内部健康演进建立的最坚固底座。