OpenAI API 怎样读取模型返回的使用量字段
OpenAI API 返回的使用量不在模型文本里,而是在响应对象的 usage 字段中。当前最容易混淆的是两套命名:Responses API 读取 input_tokens、output_tokens 和 total_tokens;Chat Completions 读取 prompt_tokens、completion_tokens 和 total_tokens。先判断接口类型,再读取对应对象,就不会把统计逻辑写进 choices 或输出文本解析器。
官方文档:https://developers.openai.com/api/reference/resources/responses/methods/create
Chat Completions 文档:https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create
- Responses API 的使用量入口是
response.usage,Chat Completions 的入口是completion.usage。 cached_tokens和reasoning_tokens是总量中的明细,不要再加回input_tokens或output_tokens。- 流式 Chat Completions 只有开启
include_usage后才会出现最终统计块;中断时要允许 usage 缺失。
先分清两种响应对象的字段名
如果请求走 Responses API,SDK 返回的是 response 对象,统计字段位于 response.usage。如果旧代码仍使用 Chat Completions,则对象通常叫 completion,字段名也随之改为 prompt_tokens 和 completion_tokens。两者的 total_tokens 都表示本次请求的总 token 数,但不能把两套字段混写。
| 接口 | 输入总量 | 输出总量 | 常见明细 |
|---|---|---|---|
| Responses API | input_tokens | output_tokens | input_tokens_details.cached_tokens、output_tokens_details.reasoning_tokens |
| Chat Completions | prompt_tokens | completion_tokens | prompt_tokens_details.cached_tokens、completion_tokens_details.reasoning_tokens |
Responses API 的官方接口地址是:https://api.openai.com/v1/responses。下面的代码只读取 SDK 已返回的对象,不把示例中的数字当成固定结果。
import os
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
# 用环境变量切换模型,避免把模型名写死在统计逻辑里。
model=os.getenv("OPENAI_MODEL", "gpt-5"),
input="用一句话说明什么是幂等请求。",
)
usage = response.usage
if usage is None:
# usage 可能为空,调用方要把它当作“未知”而不是 0。
raise RuntimeError("响应没有返回 usage,不能生成 token 统计")
input_detail = usage.input_tokens_details
output_detail = usage.output_tokens_details
stats = {
"input_tokens": usage.input_tokens,
"output_tokens": usage.output_tokens,
"total_tokens": usage.total_tokens,
# 这些是总量中的拆分项,不要再次累加到总量。
"cached_tokens": getattr(input_detail, "cached_tokens", None),
"reasoning_tokens": getattr(output_detail, "reasoning_tokens", None),
}
print(stats)

把总量和明细映射成自己的统计记录
接入日志或成本统计时,建议先统一成应用自己的字段,再交给后续存储。最重要的判断是:缓存 token 已包含在输入总量中,推理 token 已包含在输出总量中;它们适合做拆分分析,不是额外消耗。字段不存在时保留 None,这样能区分“接口没有提供”与“确实为零”。
def read_chat_usage(completion):
# Chat Completions 使用 prompt/completion 命名,不要套用 Responses 字段。
usage = completion.usage
if usage is None:
return None
prompt_detail = getattr(usage, "prompt_tokens_details", None)
completion_detail = getattr(usage, "completion_tokens_details", None)
return {
"input_tokens": usage.prompt_tokens,
"output_tokens": usage.completion_tokens,
"total_tokens": usage.total_tokens,
"cached_tokens": getattr(prompt_detail, "cached_tokens", None),
"reasoning_tokens": getattr(completion_detail, "reasoning_tokens", None),
}
completion = client.chat.completions.create(
# 兼容仍使用 Chat Completions 的项目。
model=os.getenv("OPENAI_MODEL", "gpt-5"),
messages=[{"role": "user", "content": "解释一次 API 重试的风险。"}],
)
print(read_chat_usage(completion))
这层映射还可以顺手记录模型名、请求 ID 和时间,但不要把 total_tokens 通过输入加输出再次计算后覆盖原值。官方返回的总量应作为本次请求的主统计字段。
流式响应要等最后一个 usage 块
非流式响应通常在整个响应对象中直接读取 usage。Chat Completions 流式请求则不同:需要设置 stream_options={"include_usage": True},中间块的 usage 通常为空,额外的最后一块才携带整次请求的统计。网络中断或主动取消时可能收不到最后一块,因此业务记录必须接受未知值。
stream = client.chat.completions.create(
# include_usage 会在结束前追加一个携带整次统计的块。
model=os.getenv("OPENAI_MODEL", "gpt-5"),
messages=[{"role": "user", "content": "用三点说明如何记录 API 用量。"}],
stream=True,
stream_options={"include_usage": True},
)
final_usage = None
for chunk in stream:
# 文本增量和 usage 是两条独立信息,先保存最后一个非空统计块。
if chunk.usage is not None:
final_usage = chunk.usage
if final_usage is None:
# 中断时不要伪造 0;保留“未收到统计”的状态供重试或补记。
print("usage unavailable")
else:
print({
"prompt_tokens": final_usage.prompt_tokens,
"completion_tokens": final_usage.completion_tokens,
"total_tokens": final_usage.total_tokens,
})
如果统计对计费或配额很重要,可以同时记录请求是否完整结束,并把缺少最终 usage 的记录标记为待补偿状态。不要只因为流中已经收到文本,就认为本次 token 统计也完整。

上线前用四个判断避免统计失真
- 入口判断:Responses 读
response.usage,Chat Completions 读completion.usage。 - 空值判断:usage 为空时记录未知,不要自动写成 0。
- 明细判断:缓存和推理字段是总量拆分,不能重复加入总量。
- 流式判断:只在收到最终 usage 块后提交完整统计;中断记录应保留缺失原因。
官方 token 统计说明还指出,报告的输出 token 不只等于用户可见文本,某些模型的格式、工具调用或其他内部结构也可能计入输出量。因此不要用字符串长度或可见词数反推 API 返回值。
常见问题
为什么 response.usage 是 None?
usage 是可选结果,流式响应尚未结束、请求被中断,或当前响应形态没有返回统计时都可能为空。把它记录为未知比填 0 更可靠。
cached_tokens 要不要加到 input_tokens 上?
不要。cached_tokens 是 input_tokens 的明细,应该用于分析缓存命中,而不是作为额外输入再次相加。
为什么输出文字不多,output_tokens 却更大?
API 统计的是生成的总输出 token,可能包含不可见的结构、工具调用或推理相关 token,不能只按最终展示文本估算。
OpenAI Batch API 怎样查询批处理任务状态
- 上一篇
- OpenAI Batch API 怎样查询批处理任务状态
- 下一篇
- Kubernetes Deployment 怎样理解滚动更新的最大不可用数
-
- 科技周边 · 人工智能 | 51分钟前 | 人工智能 · OpenAI Batch API batch status 批处理任务 API状态查询
- OpenAI Batch API 怎样查询批处理任务状态
- 292浏览 收藏
-
- 科技周边 · 人工智能 | 52分钟前 | Parquet Hugging Face Datasets shard to_parquet push_to_hub
- Hugging Face Datasets 导出 Parquet 时怎么控制分片大小
- 378浏览 收藏
-
- 科技周边 · 人工智能 | 56分钟前 | PyTorch DataLoader IterableDataset get_worker_info
- PyTorch IterableDataset 怎样为每个 worker 分配不同数据片段
- 455浏览 收藏
-
- 科技周边 · 人工智能 | 59分钟前 | python · 人工智能 · snapshot_download Hugging Face Hub HF_HUB_CACHE HF_HOME 模型缓存 huggingface_hub
- Hugging Face Hub 怎样用缓存目录管理模型文件
- 247浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Hugging Face Transformers 怎样用 ignore_mismatched_sizes 加载分类模型
- 113浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- OpenAI API 怎样为请求设置幂等键
- 174浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- OpenAI Responses API 怎样让长任务异步运行
- 327浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | temperature top_p OpenAI API reasoning.effort max_output_tokens 采样参数
- OpenAI API 怎样用 temperature 之外的参数控制采样
- 131浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- OpenAI API 怎样限制输出内容使用指定文本格式
- 268浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- ONNX Runtime 怎样查看模型输入名称与形状
- 349浏览 收藏
-
- 科技周边 · 人工智能 | 11小时前 |
- Hugging Face Datasets IterableDataset batch 丢弃尾批的配置方法
- 297浏览 收藏
-
- 科技周边 · 人工智能 | 11小时前 |
- Hugging Face Transformers generate 怎样用 max_new_tokens 控制输出长度
- 437浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 719次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 726次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 801次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 762次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 599次使用
-
- 量化模型本地推理的显存估算方法
- 2026-10-17 501浏览
-
- 本地大模型反复输出同一句话怎么调整生成参数
- 2026-09-06 501浏览
-
- Python 调用大模型时如何用结构化输出校验 JSON:从解析失败到可重试
- 2026-08-29 501浏览
-
- AI写作工具免费版安装教程(含豆包Clawdbot)
- 2026-05-30 501浏览
-
- WPS AI能自动生成PPT吗?输入主题一键制作演示文稿
- 2026-05-27 501浏览

