OpenAI API 的账单之所以难懂,不是因为单价藏着掖着,而是因为一次请求往往同时触发多个计费维度:普通输入、缓存命中、输出、推理 Token、图片、长上下文倍率、批处理折扣。只看“每百万 Token 多少钱”,很容易低估真实成本。
本文按“计费单位—三笔主账—附加规则—估算公式—降本顺序”拆开讲。所有单价、折扣和门槛以 模型价格 与 OpenAI 官方文档为准,本文不写死数字。
说明:OpenAI、GPT、ChatGPT 是其权利人的商标,本文仅作技术说明。价格随模型和账期变化,做预算前请以站内模型价格为准。
一、先统一单位:Token 不是字数
Token 是模型处理文本的最小单位。一个汉字、一个英文单词、一个标点,可能对应一个或多个 Token;图片、工具定义、结构化 schema 也会被折算成 Token。做预算时不要用“字数 × 单价”估算,直接用接口返回的 usage 字段。
一次请求的输入通常包括:
- system prompt 和开发者指令;
- 历史对话消息;
- 工具(function)定义与参数 schema;
- 检索出来的文档、网页正文、代码片段;
- 图片、音频等非文本输入折算的 Token。
输出则包括模型生成的正文。对推理模型来说,内部推理 Token 也按输出计费,即使界面上看不到完整思考过程。
| 计费项 | 是否计入账单 | 说明 |
|---|---|---|
| 普通输入 Token | 是 | 系统提示、历史消息、工具定义都算 |
| 缓存命中输入 | 是,按缓存价 | 只有稳定前缀才容易命中 |
| 输出 Token | 是 | 通常单价高于输入 |
| 推理 Token | 是,按输出价 | 推理模型常见,可能不展示全文 |
| 图片输入 | 是 | 按图像尺寸和细节档折算 Token |
| 失败请求 | 视情况 | 多数 400 类不计,已生成部分可能计费 |
二、输入、输出、缓存:三笔主账
输入账看的是“每次请求都带上了什么”。很多团队的成本不是输在问题上,而是输在每次都把整份文档、整套工具定义、全部历史消息重新传一遍。输入单价再低,乘上请求量也会变成主要成本。
输出账看的是“模型写了多少”。输出单价通常高于输入,长报告、长代码、冗长解释都会放大成本。把 max_tokens 设成一个合理上限,要求模型输出结构化结果,比事后压缩更有效。
缓存账看的是“哪些内容被重复使用”。OpenAI 的提示缓存按前缀匹配:只有请求开头一段完全一致,后续内容才可能命中。把固定不变的 system prompt、工具定义、知识库说明放在最前面,把变化的用户问题放在最后,命中率才会稳定。缓存有最短前缀长度和存活时间,不是永久存储,也不是开了就一定命中。
一个常见的误判是:把缓存当成“第二次请求免费”。实际是缓存命中部分按较低的缓存读取价计费,未命中部分仍按普通输入价计费。账单上要分别看 cached_tokens 和普通输入 Token。
三、附加规则:长上下文、批处理、推理模型
除了三笔主账,还有几类规则会改变最终金额。
| 规则 | 触发条件 | 对账单的影响 |
|---|---|---|
| 长上下文倍率 | 单次输入超过模型设定门槛 | 整个请求按更高倍率计费,不是只对超出部分加价 |
| 批处理 | 使用 Batch 接口、接受异步返回 | 通常有单独折扣,适合离线任务 |
| 推理强度 | 调高 reasoning effort | 推理 Token 增加,输出费用上升 |
| 图片细节档 | 使用高细节图片输入 | 图像折算 Token 增加 |
| 重试 | 429、5xx 后重新发送 | 每次重试都是新请求,可能重复计费 |
以站内 GPT-5.5 的资料为例,单次输入超过 272K Token 时,整个请求会触发输入、输出的倍率计费。这类门槛要写进预算模型,而不是等账单出来才发现。
四、一次请求的成本怎么估
把单价记作变量,公式如下:
单次请求成本 =
未缓存输入 Token × 输入单价
+ 缓存命中 Token × 缓存读取单价
+ 输出 Token(含推理 Token)× 输出单价
+ 图片/工具等附加 Token × 对应单价
最终金额 = 单次请求成本 × 长上下文倍率 × 批处理折扣
做月度预算时,用最近一周的真实日志统计四类 Token 的占比,再乘单价。不要用“平均一次多少钱”倒推,因为长请求和短请求的分布差异很大,平均值会掩盖异常。
五、用量日志要记哪些字段
OpenAI 兼容接口的响应里通常带有 usage 对象。把下面几个字段写进日志,对账时能省很多时间:
import json
from openai import OpenAI
client = OpenAI(
api_key="sk-你的密钥",
base_url="https://api.zhongshangqihang.com/v1",
)
resp = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "用三句话总结这份合同的风险。"}],
max_tokens=800,
)
u = resp.usage
prompt_details = getattr(u, "prompt_tokens_details", None)
completion_details = getattr(u, "completion_tokens_details", None)
record = {
"request_id": resp.id,
"model": resp.model,
"prompt_tokens": u.prompt_tokens,
"cached_tokens": getattr(prompt_details, "cached_tokens", 0) or 0,
"completion_tokens": u.completion_tokens,
"reasoning_tokens": getattr(completion_details, "reasoning_tokens", 0) or 0,
"total_tokens": u.total_tokens,
}
print(json.dumps(record, ensure_ascii=False))
如果网关或 SDK 版本不返回某个明细字段,用 getattr 兜底,不要让日志代码把主流程打断。
六、降本顺序:先做不花钱的
按投入产出排序,建议依次执行:
- 先量化:按业务线统计输入、输出、缓存和重试的 Token 占比,找出最大项。
- 压输入:用检索、摘要、分段处理替代整份文档直塞,避免触发长上下文倍率。
- 稳前缀:把 system prompt、工具定义、固定知识库放在最前面,减少缓存失效。
- 限输出:设置
max_tokens,要求 JSON 或固定字段,减少无效长回答。 - 做路由:简单分类、抽取、改写走轻量模型,复杂推理再上旗舰模型。
- 用批处理:离线任务走 Batch,接受更高的完成时延换取折扣。
- 设预算:按项目、按 Key 设额度上限和告警,异常调用能及时止损。
- 查重试:429 和 5xx 用指数退避,设置最大重试次数,避免重复计费。
七、常见问题
为什么输出比输入贵?
生成每个 Token 都需要模型逐步计算,算力成本高于读取已有上下文,所以输出单价通常更高。长回答、长代码、推理过程都会放大这部分费用。
缓存是自动生效的吗?
多数 OpenAI 兼容接口会自动尝试前缀缓存,但命中取决于前缀是否完全一致、是否达到最短长度、缓存是否还在存活期内。稳定前缀是提高命中率的前提。
推理模型的思考过程收费吗?
收费。推理 Token 通常按输出 Token 计价,即使客户端看不到完整思考内容。调高推理强度会同时增加延迟和费用。
同样的请求,两次扣费为什么不一样?
输入长度、输出长度、缓存命中、模型快照、重试次数都可能不同。用请求 ID 和 usage 日志对齐,才能定位差异。
网关价格和 OpenAI 官方价格一样吗?
不一定。网关可能包含汇率、支付通道和服务成本,也可能有活动折扣。具体以站内模型价格为准,不要拿旧截图做预算。
下一步
先注册中商起航 AI 网关,用一把测试 Key 跑通最小请求,把 usage 日志接上,再按业务线拆分预算。模型、上下文和价格以模型价格为准。
相关阅读:
