Skip to main content

MaaS Usage

MaaS Usage 用于描述模型请求的资源消耗与计费统计。不同 Provider 的字段命名、cache 口径、reasoning 口径和 streaming 返回时机不同,设计统一统计时应同时保留:

  • 原始 Provider usage:用于供应商账单核对和协议排障。
  • 归一化 usage:用于平台统计、限额、报表和跨 Provider 对比。
  • 估算 usage:用于中断、异常、缺失 usage 时的兜底分析,不能当作精确账单口径。

适用范围

  • 生成类模型请求
    • OpenAI Chat Completions / Completions
    • OpenAI Responses API
    • Anthropic Messages
    • Gemini GenerateContent / StreamGenerateContent
  • 非生成类端点应单独定义 usage 口径
    • Embeddings
    • Rerank
    • Count Tokens
    • Image / Audio / Video generation
    • Speech / Transcription

计费维度

  • pay per token
    • 输入 token
    • 输出 token
    • reasoning / thinking token
    • cache read / cache write token
  • pay per request
    • 每次调用固定费用
    • server tool use,例如 web search
  • pay per item
    • image
    • audio
    • video
    • document / file
  • pay per compute
    • 按运行时长、算力、并发、GPU/TPU 等资源计费

通用归一化字段

field说明
input_tokens统一输入 token 数;用于统计、配额、报表
output_tokens统一输出 token 数;原则上包含需要计费/统计的 reasoning token
total_tokens统一总 token 数,通常为 input_tokens + output_tokens
cached_tokenscache token 总量;Provider 不区分 read/write 时使用
cache_read_tokens从 prompt cache 读取的 token
cache_write_tokens写入/创建 prompt cache 的 token
cache_write_5m_tokens5 分钟 TTL cache 写入 token,常见于 Anthropic 类口径
cache_write_1h_tokens1 小时 TTL cache 写入 token,常见于 Anthropic 类口径
reasoning_tokensreasoning / thinking token 明细
audio_tokens音频 token,输入或输出需结合字段上下文
image_tokens图片 token,若 Provider 暴露
server_tool_requests服务端工具调用次数,例如 web search
provider_usageProvider 原始 usage JSON,用于账单核对和排障
estimated标记 usage 是否为估算值
tip

跨 Provider 报表优先使用归一化字段;账单核对必须同时保留原始 provider_usage,因为各家对 cache、reasoning、tool use 的字段语义不完全一致。

OpenAI Chat Completions / Completions

OpenAI-compatible usage 通常位于响应顶层 usage

{
"usage": {
"prompt_tokens": 100,
"completion_tokens": 50,
"total_tokens": 150,
"prompt_tokens_details": {
"cached_tokens": 80,
"audio_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 20,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
}
}
field说明
prompt_tokens输入 token 数
completion_tokens输出 token 数;OpenAI 语义下通常已经包含 reasoning token
total_tokens总 token 数,通常为 prompt_tokens + completion_tokens
prompt_tokens_details.cached_tokens命中 prompt cache 的输入 token 数
prompt_tokens_details.audio_tokens输入音频 token,是否返回取决于模型和 Provider
completion_tokens_details.reasoning_tokens输出中的 reasoning token
completion_tokens_details.audio_tokens输出音频 token,是否返回取决于模型和 Provider
accepted_prediction_tokensprediction / speculative decoding 接受的 token
rejected_prediction_tokensprediction / speculative decoding 拒绝的 token

归一化建议:

input_tokens       = usage.prompt_tokens
output_tokens = usage.completion_tokens
total_tokens = usage.total_tokens
cached_tokens = usage.prompt_tokens_details.cached_tokens
reasoning_tokens = usage.completion_tokens_details.reasoning_tokens

兼容注意:

  • 部分 OpenAI-compatible Provider 可能把 cached_tokens 放在 usage.cached_tokens 顶层。
  • streaming 只有在 Provider 返回 usage chunk 时才有精确 usage。
  • 中途断流且未收到 usage chunk 时,不能得到精确输出 token。

OpenAI Responses API

Responses API 使用 input_tokens / output_tokens 命名。

{
"usage": {
"input_tokens": 100,
"input_tokens_details": {
"cached_tokens": 80
},
"output_tokens": 50,
"output_tokens_details": {
"reasoning_tokens": 20
},
"total_tokens": 150
}
}
field说明
input_tokens输入 token 数
input_tokens_details.cached_tokens命中 prompt cache 的输入 token 数
output_tokens输出 token 数
output_tokens_details.reasoning_tokens输出中的 reasoning token
total_tokens总 token 数

归一化建议:

input_tokens     = usage.input_tokens
output_tokens = usage.output_tokens
total_tokens = usage.total_tokens
cached_tokens = usage.input_tokens_details.cached_tokens
reasoning_tokens = usage.output_tokens_details.reasoning_tokens

兼容注意:

  • Responses API 通常只表达 cached_tokens,不区分 cache read / cache write。
  • Responses streaming 通常在完成事件中携带最终 usage。
  • 请求失败、超时或提前中断时 usage 可能缺失或不完整。
  • 完成状态需结合响应状态判断,例如 completedfailedincomplete

Anthropic Messages

Anthropic Messages usage 位于消息对象的 usage

{
"usage": {
"input_tokens": 100,
"cache_creation_input_tokens": 30,
"cache_creation": {
"ephemeral_5m_input_tokens": 10,
"ephemeral_1h_input_tokens": 20
},
"cache_read_input_tokens": 80,
"output_tokens": 50,
"server_tool_use": {
"web_search_requests": 1
}
}
}
field说明
input_tokens非缓存的新输入 token;不包含 cache read/write token
cache_creation_input_tokens本次写入/创建 prompt cache 的输入 token
cache_creation.ephemeral_5m_input_tokens5 分钟 TTL cache 写入 token
cache_creation.ephemeral_1h_input_tokens1 小时 TTL cache 写入 token
cache_read_input_tokens本次从 prompt cache 读取的输入 token
output_tokens输出 token 数
server_tool_use.web_search_requests服务端工具使用次数,例如 web search

归一化建议:

input_tokens       = usage.input_tokens
+ usage.cache_creation_input_tokens
+ usage.cache_read_input_tokens
output_tokens = usage.output_tokens
total_tokens = input_tokens + output_tokens
cached_tokens = usage.cache_creation_input_tokens + usage.cache_read_input_tokens
cache_read_tokens = usage.cache_read_input_tokens
cache_write_tokens = usage.cache_creation_input_tokens
cache_write_5m = usage.cache_creation.ephemeral_5m_input_tokens
cache_write_1h = usage.cache_creation.ephemeral_1h_input_tokens

兼容注意:

  • Anthropic 原始 input_tokens 是“新增输入”,不是“输入总量”。
  • 如果要得到总输入量,必须加上 cache_creation_input_tokenscache_read_input_tokens
  • 流式响应中,输入相关 usage 通常出现在 message_start,输出 usage 可能出现在 message_delta
  • Bedrock Claude、Vertex Claude 等封装可按 Anthropic Messages usage 语义理解,但仍应保留原始 Provider 字段。

Gemini GenerateContent / StreamGenerateContent

Gemini usage 通常位于 usageMetadata

{
"usageMetadata": {
"promptTokenCount": 400,
"candidatesTokenCount": 50,
"totalTokenCount": 470,
"thoughtsTokenCount": 20,
"cachedContentTokenCount": 150,
"toolUsePromptTokenCount": 0,
"promptTokensDetails": [
{ "modality": "TEXT", "tokenCount": 100 },
{ "modality": "AUDIO", "tokenCount": 300 }
],
"candidatesTokensDetails": [],
"cacheTokensDetails": [],
"toolUsePromptTokensDetails": [],
"serviceTier": "default",
"trafficType": "ON_DEMAND"
}
}
field说明
promptTokenCount输入 token 数
candidatesTokenCount候选输出 token 数;不一定包含 thoughts token
totalTokenCount总 token 数
thoughtsTokenCountGemini thinking / reasoning token 数
cachedContentTokenCountcached content 命中的 token 数
toolUsePromptTokenCount工具使用相关 prompt token 数,是否返回取决于模型能力
promptTokensDetails输入 token 的模态明细,例如 TEXT、AUDIO、IMAGE、VIDEO
candidatesTokensDetails输出 token 的模态明细
cacheTokensDetailscache token 的模态明细
toolUsePromptTokensDetails工具使用 prompt token 的模态明细
serviceTier服务层级,是否返回取决于接口/SDK
trafficTypeVertex 等场景的流量类型,是否返回取决于接口/SDK

归一化建议:

input_tokens     = usageMetadata.promptTokenCount
output_tokens = usageMetadata.totalTokenCount - usageMetadata.promptTokenCount
total_tokens = usageMetadata.totalTokenCount
reasoning_tokens = usageMetadata.thoughtsTokenCount
cached_tokens = usageMetadata.cachedContentTokenCount

兼容注意:

  • Gemini 的 candidatesTokenCountthoughtsTokenCount 可能分开报告。
  • 对于 Gemini 3 类模型,totalTokenCount 可能显著大于 promptTokenCount + candidatesTokenCount,差值常来自 thoughts token。
  • 因此统一输出量通常更适合用 totalTokenCount - promptTokenCount,而不是只看 candidatesTokenCount
  • cachedContentTokenCount 表示 cache 相关 token,但是否是 cache read 还是 cache creation,需要结合 cached content 生命周期判断。
  • 多模态明细适合排查原始 Provider usage,不建议在统一 token 统计里重复计费。

Cache 字段选择

需求建议字段
只关心 cache 总量cached_tokens
需要区分读写cache_read_tokens / cache_write_tokens
需要区分 TTLcache_write_5m_tokens / cache_write_1h_tokens
Provider 只返回 cached_tokens不强行拆分 read/write
Provider 返回原始 cached content 生命周期可按创建/读取行为归入 read/write

注意:

  • Prompt cache 命中的通常是稳定 prompt 前缀。
  • Tool schema、system prompt、上下文顺序变化都可能影响 cache 命中。
  • Cache 命中通常降低输入 token 成本,但不一定显著降低端到端延迟。

Reasoning 字段选择

  • reasoning_tokens 表示 thinking / reasoning 明细。
  • output_tokens 应按“需要计费或统计的输出总量”设计,通常应包含 reasoning token。
  • 若 Provider 的原始 output_tokens 不包含 reasoning,应在归一化时明确补齐逻辑。
  • 排查 reasoning 计费差异时,应同时查看:
    • 原始 provider usage
    • output_tokens
    • reasoning_tokens
    • total_tokens

Streaming / 中断计费

场景usage 状态
非流式正常完成通常有完整 usage
流式正常完成且 Provider 返回 usage有精确 provider usage
流式中断前已收到 usage chunk可保留最后一次 usage,但需确认是否最终值
流式中断前未收到 usage chunk没有精确输出 usage,只能估算
客户端断开 / 499是否有 usage 取决于上游是否已返回 usage
上游超时 / 错误usage 可能缺失、不完整或只含输入部分

设计建议:

  • 缺失 usage 时,不应把估算 token 当作 Provider 精确 usage。
  • 估算字段应显式标记 estimated: true
  • 对于 Agent 场景,中断时仍需要估算已消耗 context,避免后续上下文窗口失准。
  • 费用侧应区分“供应商精确 usage”和“平台估算 usage”。

异动检测

MaaS usage 常见分布特征:

  • 长尾分布
  • 突发性
  • Fat Tail / 肥尾
  • 强依赖模型、上下文长度、工具调用、cache 命中和 retry 行为

可观测指标:

指标说明
RPMrequests per minute
input TPMinput tokens per minute
output TPMoutput tokens per minute
total TPMtotal tokens per minute
cache hit tokenscache 命中 token
reasoning tokensreasoning token
abort rate中断率
missing usage rateusage 缺失率
estimated usage rate估算 usage 占比

检测建议:

  • 使用 3+Sigma + 15-30min 窗口检查用量异动。
  • 对 token 消耗建议同时看 request count 和 token per request,避免把请求量增长误判为单请求异常。
  • 对 reasoning 模型单独观察 reasoning_tokens / output_tokens
  • 对 cache 场景单独观察 cache hit token 和 cache write token。

快速公式表

协议统一输入统一输出cachereasoning
OpenAI Chat/Completionsprompt_tokenscompletion_tokensprompt_tokens_details.cached_tokenscompletion_tokens_details.reasoning_tokens
OpenAI Responsesinput_tokensoutput_tokensinput_tokens_details.cached_tokensoutput_tokens_details.reasoning_tokens
Anthropic Messagesinput_tokens + cache_creation_input_tokens + cache_read_input_tokensoutput_tokenscache_creation_input_tokens + cache_read_input_tokens原始 usage 通常不单列;如 Provider 扩展返回则保留
GeminipromptTokenCounttotalTokenCount - promptTokenCountcachedContentTokenCountthoughtsTokenCount

参考