返回博客

Claude API 计费怎么算?预扣、结算、失败退款全流程拆解

Claude API 到底是怎么扣费的?从输入/输出 token 分开计价,到请求发起时的预扣、拿到真实用量后的结算、失败自动退款,再到怎么在开发阶段就把自己的成本估准。

Apiko 团队

如果你对着一张 Claude API 账单,发现数字和自己心算的对不上,不用怀疑是哪里算错了——大概率是没搞清楚计费流程里的几个环节。Claude API 计费表面上很简单:输入、输出 token 分开计价,按量付费。但账单背后的实际链路——请求发起时怎么估算、拿到结果后怎么对账、调用失败了钱怎么办——很多文档并不会展开讲。

这篇文章把这套机制拆开讲清楚,让你能自己推算账单,而不是靠猜。它不是一份价目表——具体到每个模型的实时价格,请始终以 /pricing 为准,毕竟价格会变动,写死在文章里的数字迟早会过期。

账单背后的两个数字:输入 token 和输出 token

和大多数 LLM API 一样,Claude API 计费按两个独立的 token 计数来算:

  • 输入 token —— 你发送的一切:system prompt、历史对话、当前这轮用户消息,以及附带的工具定义或上下文。多轮对话或 RAG 场景下,这个数字往往是大头,因为每次调用都要把之前的上下文重新发一遍。
  • 输出 token —— 模型生成回来的内容。普通聊天场景下这个数字通常比输入小,但一旦涉及长文生成、限定长度的摘要,或者推理链较长的任务,输出 token 就会反过来主导成本。

输入和输出各自独立定价,而且输出的单价通常比输入高——生成内容本身比读取上下文更"贵"。估算成本时这个不对称很关键:一个 system prompt 巨大但答案只有一行的请求,和一个短 prompt 触发长回答的请求,账单结构完全不同。

实际影响是:"每次调用的成本"从来不是一个固定数字,而是你 prompt 结构的函数。同一个模型,不同应用因为携带的上下文量、回答的啰嗦程度不同,单位经济模型可能天差地别。每个模型按 100 万 token 计价的实时输入/输出费率,始终挂在 /pricing——那张表和计费系统读的是同一份数据源,永远不会和实际扣费脱节。

计费流程:预扣、结算、退款

大多数文章讲到"按 token 付费"就停了。网关这一侧,一次请求实际要经过三步:

1. 请求发起时先预扣

请求刚进来的时候,网关还不知道最终会产生多少 token——回复都还没生成出来。所以它会先做一次预扣:按这类请求的合理上限,从你的余额里预先扣一笔估算金额。这一步的作用是防止并发请求把余额透支——如果没有这道预留机制,你同时发出十个并行调用,每个都各自过一遍余额检查然后通过,合起来完全可能把余额刷成负数。

2. 拿到真实用量后结算

上游服务商返回响应后,会附带模型自己统计的 token 数——是真实的输入输出计数,不是估算。网关据此结算实际扣费:如果预扣多了,差额会退回你的余额;真正扣掉的金额,永远对应服务商上报的真实用量,而不是那个最初的估算值。

3. 失败自动退款

如果上游调用失败——服务商返回 5xx、超时,或者任何没能拿到可用响应的情况——这次请求不计费。预扣的部分会自动退回。你不需要为一次失败的生成去开工单,账务会在同一个请求生命周期里自动纠正。网关跨渠道重试时也遵循这个逻辑:重试发生在同一次客户端调用背后,你看不到中间过程,只有真正返回给你的那次响应才会计费。

结论很直接:**账单反映的是真实 token 用量,失败不产生任何费用。**这句话值得记住,因为它会改变你写重试逻辑的方式——你通常不需要在自己代码里再叠一层"失败别扣我钱"的保护逻辑,这本来就是默认行为。

动手之前,怎么估算自己的成本

既然定价就是两个独立的按 token 单价,估算一个工作负载的成本,关键其实是把 token 用量估准——单价查表反而是最简单的一步。

一份可以直接照做的估算清单:

  1. 实测你的 prompt 大小,别靠猜。 system prompt + few-shot 示例 + 检索到的上下文 + 用户这轮输入拼在一起,过一遍分词器(或者直接看真实测试调用返回的 usage 字段,见下面的流式示例)。按字数估算 token,对英文文本还算凑合,但碰到代码、JSON 或非英语文本就很不靠谱。
  2. 算上对话历史的增长。 如果你每次调用都把之前几轮对话重新发一遍(多轮聊天最常见的做法),输入 token 会随对话长度大致线性增长。一个 10 轮对话,到最后一轮的单次成本可能是第一轮的好几倍,纯粹是因为重复发送的上下文越来越多——这一点最好在假设"每次调用成本恒定"之前先弄清楚。
  3. 有意识地限制输出长度。 不设上限的生成是失控输出成本最常见的来源。如果你的场景本来就有一个自然的输出上限(一段摘要、一个分类标签、一句简短回答),就把 max_tokens 设成对应的值,而不是图省事留个很高的默认值。
  4. 按真实调用量而不是峰值单日去乘。 单价 × 每次调用的 token 数 × 每天调用次数,能得出一个日估算;拿这个数字去对照你真实的流量模式(包括重试——如果你在网关自身的重试之外还做了客户端重试,也要算进去),而不是靠一次随手测试的样本量去外推。
  5. 拿用量日志做校验,而不是反过来。 上线之后,用量日志(控制台 → Usage)会展示每次调用真实的模型、prompt/completion token 数和费用,支持导出 CSV 做离线核对——这才是你估算应该收敛的真值,不是让真值去迁就估算。

具体填进这套公式的真实单价,去 /pricing 查——那是一张实时表,读的是网关计费用的同一份数据源,基于它做出的估算不会和实际扣费产生偏差。

从流式响应里读出真实用量

如果想看清楚一次请求最终结算用的确切数字,可以在流式响应的最后一块里要求返回用量信息。下面是对接 OpenAI 兼容网关时这次调用的样子:

curl {GATEWAY_BASE_URL}/chat/completions \
  -H "Authorization: Bearer $APIKO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5-20250929",
    "messages": [{"role": "user", "content": "Summarize this in two sentences: ..."}],
    "stream": true,
    "stream_options": {"include_usage": true}
  }'

{GATEWAY_BASE_URL} 换成你部署环境的网关地址(创建 API key 时配置的那个 base URL——具体来源可以看 /docs)。设置了 stream_options.include_usage 之后,流的最后一块会带一个 usage 对象,里面是真实的 prompt 和 completion token 数——正是计费结算这一步用的那组数字。这在开发阶段是个很实用的校验手段:跑一次有代表性的请求,读最后一块的 usage,再对照 /pricing 上的单价去算,就能得到这次调用的精确成本,而不是估算值。

上面示例里的模型 ID claude-sonnet-4-5-20250929 来自目录——具体要用哪个 ID,以 /models 上的实际列表为准,因为目录条目会随新版本上线而变化。

为什么不是按次收费的固定价格

有些 API 不管内容长短,按每次调用收一个固定价格;Claude API(以及大多数按量计费的 LLM API)选择按 token 收费,是因为一次请求的真实成本会因为 prompt 和输出大小的不同而相差几个数量级。一次一行文本的分类调用,和一次长文档摘要调用,根本不是同一个工作量级——固定价格要么会让前者多花钱,要么会让后者定价过低。

预扣→结算→退款这套流程,正是让按 token 计费能被放心用起来的原因:账务准确(结算对应真实用量,不是估算)、能防住并发透支(靠预扣)、非你自身原因导致的失败不计费(自动退款)。再加上一份不过期、在目录所有模型上通用的余额,实际结果是你可以用一份预算统一管理,而不用去对每个供应商各自的账单。

自己动手试一下

想对 Claude API 的真实成本有直观感受,最快的办法就是自己跑一遍。新注册账号会自动获得试用额度——无需绑卡——你可以先发几个有代表性的请求,读出真实的 token 用量,再对照 /pricing 核对结算后的费用,之后再决定要不要正式接入。注册,把你现有的 OpenAI 兼容客户端指向网关,看看第一批真实数字。