深色模式
Token 成本与用量监控
摘要:LLM 应用按 token 计费,成本是一等运行时信号——一次请求的成本可以相差两个数量级,且传统 APM 完全不统计。本文给出 token 用量的计量口径(输入/输出/缓存分别计费)、成本指标体系与 Prometheus 指标设计、Langfuse 等追踪侧的成本归集、预算管控与"成本失控熔断"的落地方式。适用栈:OpenAI / Anthropic API、自托管 vLLM、LiteLLM 网关、Langfuse。[版本相关]:各厂商价格与缓存计费折扣随时间调整,落地前以官方 pricing 页为准。
为什么成本必须单独监控
传统服务的成本约等于"请求数 × 单机成本",是容量的函数;LLM 服务的成本是流量的函数,且波动极大:
| 因素 | 对成本的影响 |
|---|---|
| 输入 token 数 | 上下文越长越贵,RAG 场景单请求输入可达数万 token |
| 输出 token 数 | 输出单价通常是输入的 3~5 倍 |
| 模型档位 | 旗舰模型与轻量模型单价差 10~50 倍 |
| 缓存命中 | Anthropic cache_read 约 0.1× 输入价;未命中时 cache_creation 约 1.25× |
| 重试 | 失败重试 = 成本翻倍但用户无感知 |
成本失控的典型路径
"重试循环 + 上下文膨胀"是最常见的失控模式:Agent 循环中工具调用失败 → 重试时携带越来越长的历史 → 单请求 token 数指数增长。数小时内可烧掉一周预算,而错误率监控图上全是绿色。成本信号必须与错误率同级对待。
计量口径:必须分开统计的 token
API 响应中的 usage 字段至少包含以下维度,监控时禁止只记总数:
json
{
"usage": {
"prompt_tokens": 3200,
"completion_tokens": 450,
"cache_read_input_tokens": 2800,
"cache_creation_input_tokens": 0
}
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 输入 token(
prompt_tokens):决定 prompt 工程/上下文管理是否有效。 - 输出 token(
completion_tokens):单价最高,直接受max_tokens约束。 - 缓存 token:命中缓存的输入按折扣计价,是"成本优化是否生效"的核心指标。
- 推理 token(如 o 系列的
reasoning_tokens):隐藏思考也计费,需单独归因。
指标体系与 Prometheus 设计
建议的指标分层(命名遵循 Prometheus 规范):
text
# 计数器:按模型/租户/场景维度累计
llm_tokens_total{model, tenant, scene, type="input|output|cache_read|cache_creation"}
llm_requests_cost_usd_total{model, tenant, scene} # 请求成本累计(估算)
# 直方图:单请求成本与 token 分布
llm_request_tokens{model, scene, type} # histogram
llm_request_cost_usd{model, scene} # histogram
# Gauge:预算水位
llm_budget_remaining_usd{tenant} # 剩余预算1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
成本估算在网关层做:LiteLLM Proxy 内置按模型单价计算 spend 的能力并写入 Postgres;自建场景维护一张模型单价表(配置化,随调价更新),在响应中间件中完成 tokens × price 的换算。
promql
# 每小时成本(按模型)
sum(increase(llm_requests_cost_usd_total[1h])) by (model)
# 单请求 P95 成本
histogram_quantile(0.95, sum(rate(llm_request_cost_usd_bucket[5m])) by (le, model))
# 缓存命中率(输入维度)
sum(rate(llm_tokens_total{type="cache_read"}[5m]))
/
sum(rate(llm_tokens_total{type="input"}[5m]) + rate(llm_tokens_total{type="cache_read"}[5m]))1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
口径陷阱
prompt_tokens 通常已包含缓存命中的部分(Anthropic 与 OpenAI 行为一致),计算缓存命中率时分母应包含 cache_read,否则命中率会超过 100% 或严重偏低。
追踪侧归集:Langfuse
指标层回答"花了多少",追踪层回答"谁花的、花在哪一步"。Langfuse 对每次 generation 记录 model、usage 与 calculated cost,可按 trace → session → user → 环境逐级下钻:
- 单次请求成本归因:定位"是哪个 Agent 的哪个循环吃掉了预算"。
spend视图按时间/模型/用户聚合,直接支撑月度账单分摊。- 与 Langfuse 的用法见 调用链追踪 Langfuse / Phoenix。
两层结合的分工:Prometheus 负责实时告警与趋势,Langfuse 负责下钻归因与账单。只做前者无法回答"成本为什么涨",只做后者无法触发分钟级熔断。
预算管控与熔断
三层防线,逐层收紧:
- 软预算告警:租户日/月预算消耗达到 70% / 90% 时告警到负责人,不拦截流量。
- 硬预算限流:达到 100% 后该租户降级到轻量模型或返回 429(LiteLLM 的 budget 功能、Higress 的消费级限流插件均支持)。
- 异常熔断:与预算无关的速率型保护——单租户 token 速率超过基线 3 倍持续 5 分钟,自动限流并告警。这是防御"失控 Agent 循环"的最后防线。
yaml
# LiteLLM 预算配置示例(节选)
litellm_settings:
max_budget: 100.0 # 全局月预算(USD)
budget_duration: 30d
general_settings:
max_budget: 100.01
2
3
4
5
6
2
3
4
5
6
告警阈值的量化建议
以"过去 7 天同时段均值"为基线,对以下信号告警:① 日成本 > 基线 1.5 倍(警告)/ 2 倍(严重);② 单请求 P95 成本环比涨 50%;③ 缓存命中率单日下降超过 20 个百分点(说明 prompt 结构被改动)。避免用固定绝对值——成本基线天然随业务波动。
落地优先级
- 第 1 周:网关层记录
usage明细日志(结构化),单价表配置化,日成本报表。 - 第 2 周:Prometheus 指标 + 成本仪表盘 + 软预算告警。
- 第 3~4 周:硬预算限流、异常熔断、按租户/场景的成本分摊视图。