读取用量与费用
调用 Zeabur AI Hub 时,每一次成功的响应都会带回两项常用信息:这次请求用了多少 token、花了多少钱。本页说明它们放在哪里,方便您接到自己的看板、设定每位用户的预算上限,或在开发阶段顺手核对一下价格。
两种获取方式
| 来源 | 内容 | 适合的场景 |
|---|---|---|
| 响应 header | 本次费用(USD)、密钥累计花费、Call ID | 最快,无需解析 body |
响应 body 的 usage 对象 | Token 数、prompt 缓存细分、推理 token | OpenAI SDK 默认就读这里 |
两者在每个成功响应里都会同时出现,不用二选一,按您代码里方便读的那个用就行。
从 header 读
每个响应都会带一组 x-litellm- 开头的 header:
| Header | 含义 |
|---|---|
x-litellm-response-cost | 本次请求的 USD 费用(浮点数) |
x-litellm-key-spend | 该 API 密钥到目前为止累计花费的 USD |
x-litellm-call-id | 本次请求的标识,反馈问题或链路追踪时用 |
x-litellm-model-id | 内部部署的模型 ID |
x-litellm-model-group | 您请求的公开模型名 |
curl
curl -i https://hnd1.aihub.zeabur.ai/v1/chat/completions \
-H "Authorization: Bearer YOUR_ZEABUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"messages": [{"role": "user", "content": "你好"}],
"max_tokens": 32
}'-i 会把响应 header 一起打印出来,看 x-litellm-response-cost 那行就是费用。
Python
OpenAI 官方 SDK 默认不会把响应 header 暴露给业务代码。如果要从 header 拿费用,直接用 httpx 走原生 HTTP:
import httpx
r = httpx.post(
"https://hnd1.aihub.zeabur.ai/v1/chat/completions",
headers={"Authorization": "Bearer YOUR_ZEABUR_API_KEY"},
json={
"model": "claude-sonnet-4-5",
"messages": [{"role": "user", "content": "你好"}],
"max_tokens": 32,
},
timeout=60.0,
)
print("费用 (USD):", r.headers.get("x-litellm-response-cost"))
print("usage:", r.json()["usage"])从 body 的 usage 对象读
响应 body 里的 usage 对象遵循 OpenAI 格式。针对 Anthropic、OpenAI 系列模型,会额外带上相应字段:
{
"usage": {
"prompt_tokens": 1024,
"completion_tokens": 256,
"total_tokens": 1280,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0
},
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}| 字段 | 适用模型 | 含义 |
|---|---|---|
prompt_tokens / completion_tokens / total_tokens | 全部 | OpenAI 标准字段 |
prompt_tokens_details.cached_tokens | OpenAI 系 | prompt_tokens 中来自 prompt 缓存的部分(已包含在 prompt_tokens 内) |
cache_creation_input_tokens | Anthropic 系 | 本次写入 Anthropic prompt 缓存的 token 数 |
cache_read_input_tokens | Anthropic 系 | 本次从 Anthropic prompt 缓存读出的 token 数 |
completion_tokens_details.reasoning_tokens | 推理模型(如 gpt-5、gpt-5-mini) | 内部推理消耗的 token |
Anthropic 与 OpenAI 对”命中缓存的 token”算法不同:Anthropic 的 cache_creation_input_tokens 和 cache_read_input_tokens 在 prompt_tokens 之外独立计;OpenAI 的 cached_tokens 是 prompt_tokens 的子集。body 会忠实地按各家原样返回,请按当前调用的模型选对应字段读。
流式(streaming)响应
走 streaming 时,usage 对象只在您主动开启时才会出现在最后一个 chunk。请在请求里加上 stream_options.include_usage: true:
import httpx, json
with httpx.stream(
"POST",
"https://hnd1.aihub.zeabur.ai/v1/chat/completions",
headers={"Authorization": "Bearer YOUR_ZEABUR_API_KEY"},
json={
"model": "claude-sonnet-4-5",
"messages": [{"role": "user", "content": "你好"}],
"max_tokens": 32,
"stream": True,
"stream_options": {"include_usage": True},
},
timeout=60.0,
) as r:
final_usage = None
for line in r.iter_lines():
if not line.startswith("data: "):
continue
payload = line[len("data: "):]
if payload == "[DONE]":
break
chunk = json.loads(payload)
if chunk.get("usage"):
final_usage = chunk["usage"]
# ...您原本的逐 chunk 处理...
print("最后一笔 usage:", final_usage)如果不带 stream_options.include_usage,整个 streaming 响应里都不会出现 usage 对象。
追踪特定一次调用
如需于事后查询某次具体请求——例如诊断异常响应、核对费用,或与应用端日志关联——请使用 response body 中的 id(completion ID):
resp = client.chat.completions.create(...)
print("request id:", resp.id)
# chatcmpl-715764bf-675d-4d95-bbdc-80c037c8ce3f请始终使用 response.id,请勿使用 x-litellm-call-id header。Header 中的值为 LiteLLM 内部路由使用的 trace 标识符,不会写入 spend log,以该值进行查询将不会返回任何结果。
在 Zeabur Dashboard 的 AI Hub 页面中展开相应的每日记录,点击任一行右侧的信息图标,详情对话框将显示 Request ID 并提供复制按钮;该值与 response.id 完全一致。
命中缓存的响应携带派生后缀
当 LiteLLM 直接从 response cache 返回完整响应时(Dashboard 中将显示「整条响应来自缓存」标签,且 cost = 0),所记录的 ID 为原始 ID 附加 _cache_hit<timestamp> 后缀:
chatcmpl-2ec370dd-83a6-41b4-817c-1646c57034bc_cache_hit1779350469.4126954原始请求与缓存提供的响应在 spend log 中分别记录为两条独立条目,共用相同的 UUID 前缀。可基于该前缀进行聚合,以统计特定 prompt 被缓存提供的次数。
历史记录
要查看每日累计或翻看每一笔请求的明细,请前往 Zeabur Dashboard 的 AI Hub 页面,它已经提供月度总览和单笔 spend log 查询。本页讲的 header 与 body 字段适合在代码里实时读取;事后翻账请直接用 Dashboard。