跳到主要内容

DeepSeek API 成本计算:缓存、输出与 Agent 重试预算指南

2026 年 8 月 6 日,DeepSeek 官方中文价格页新增了一条脚注:计划近期整体上调 API 服务定价,预计涨幅较大,具体方案以正式通知为准。

最终新价没有公布,生效日期也没有确认。

这篇文章不猜价格,不预测涨幅。它要解决一个更基础的问题:如果你现在的日志只有全月总 Token 或总金额,等新价公布后,你仍然无法解释是哪类任务、哪次缓存失效、哪轮重试推高了成本。你能换算出一个新的总数,但解释不了差异从哪里来。

本文的目标是帮你建立新价公布后可以直接回算的任务级成本记录。记录结构确定之后,无论是旧价算一遍还是新价算一遍,操作是一样的,只需要换价格表版本。


第一步:保存可复算的原始记录​

完整 usage,不只是总 Token​

DeepSeek 的 Chat Completions API 会在 usage 字段里返回这次调用的 Token 明细。关键字段包括:

  • prompt_tokens:本次请求的全部输入 Token
  • prompt_cache_hit_tokens:其中命中磁盘缓存的部分
  • prompt_cache_miss_tokens:未命中缓存、实际计算的部分
  • completion_tokens:模型生成的输出 Token

在 Chat Completions 格式下,命中 + 未命中 = 全部输入 Token(prompt_tokens)。这三个数字加上输出,构成了一次调用的完整计价基础。

Responses API 使用另一组字段:输入总量是 input_tokens,缓存命中量位于 input_tokens_details.cached_tokens,输出是 output_tokens;未命中输入可用输入总量减去缓存命中量。两种格式不要混用。最稳妥的做法仍是保存原始 usage,再把它们映射到统一的 hit、miss 和 output 字段。对应格式可核对 Chat Completions API 与 Responses API 文档。

很多系统只保存 total_tokens 或者直接丢弃 usage,等到需要解释成本时才发现无法重建。保存完整 usage JSON 是最低成本的修复方式:你不需要改变调用逻辑,只需要在落日志时把这个字段一起写进去。

同一条记录里还需要什么​

除了 usage,一条可复算的任务调用记录还需要:

字段说明
task_id把同一个 Agent 任务的所有调用关联起来
call_id识别单次 API 调用,使用响应 ID 或自建 ID
model不同模型价格不同,不能事后推断
call_index这是该任务的第几次调用
success这次调用是否成功返回了预期结果
is_retry是否是失败后的重试
failure_reason如果失败,原因是什么(超时、模型拒绝、工具报错等)
timestamp调用时间,用于对应价格表版本
price_table_version计算时使用的价格表日期标识
cost_calculated_at成本是什么时候算的

task_id 是最容易被忽略的字段。Agent 任务通常包含多次调用,如果每次调用只作为独立事件记录,合并任务成本时要靠事后拼凑,非常脆弱。

关于字段名:不同框架、不同 SDK 封装层的响应格式不完全一致,不建议用本文给出的名字直接覆盖你的字段命名。优先保留原始 usage 对象,再按你自己系统的标准字段做一次映射。映射关系也应该记录下来。


第二步:用版本化价格表计算三路 Token​

当前价格表(2026-08-06)​

以下是截至本文写作时间的当前价格,单位:元 / 百万 Token。这不是未来价格。

模型输入·缓存命中输入·缓存未命中输出
DeepSeek-V4-Flash0.0212
DeepSeek-V4-Pro0.02536

两个数字值得注意:

  • V4-Flash 的命中 / 未命中输入单价差 50 倍(0.02 对 1)。
  • V4-Pro 的命中 / 未命中输入单价差 120 倍(0.025 对 3)。

官方价格页:https://api-docs.deepseek.com/zh-cn/quick_start/pricing

三路计算公式​

每次调用的 API 成本 = 三路分别计算后相加:

成本 = (hit_tokens / 1,000,000) × 命中单价
+ (miss_tokens / 1,000,000) × 未命中单价
+ (output_tokens / 1,000,000) × 输出单价

这是一组"分路电表":缓存命中走一路计价,缓存未命中走另一路计价,输出走第三路。重试会让同一个任务的 Token 再次过表,每路都重新计量。

透明算术示例​

以下是纯价格表算术,不是真实 API 运行,也不代表常见 Agent 任务的 Token 规模。

场景 A:V4-Flash,80 万 hit + 20 万 miss + 10 万 output

(800,000 / 1,000,000) × 0.02
+ (200,000 / 1,000,000) × 1
+ (100,000 / 1,000,000) × 2

= 0.8 × 0.02 + 0.2 × 1 + 0.1 × 2
= 0.016 + 0.2 + 0.2
= 0.416 元

场景 B:同样 100 万输入,全部 miss + 10 万 output

(1,000,000 / 1,000,000) × 1
+ (100,000 / 1,000,000) × 2

= 1 × 1 + 0.1 × 2
= 1 + 0.2
= 1.2 元

场景 B 约为场景 A 的 2.88 倍,差距完全来自缓存命中情况,输出量相同。

这个对比不是建议你去优化缓存命中率——那是另一个话题。它的用途是说明:如果你的日志只有"共消耗 X 万 Token",你无法区分这两个场景,也无法在换价格时准确重算。


第三步:从"调用成本"合并到"任务成本"​

单次调用的成本只是起点。一个 Agent 任务通常不是一次调用就能完成的。

常见情况包括:规划调用、工具调用、验证失败后的重试、任务拆解后的子调用。每次调用都会在 usage 里产生独立的 Token 消耗,每路都按当时的缓存状态分别计价。

合并方法很直接:先按模型与价格版本分组,再把同一个 task_id 下各组调用的三路 Token 分别加总,分别用对应价格表计算。

下面的公式只适用于同一模型和同一价格版本的一组调用:

任务总命中输入 Token = sum(call.hit_tokens) for call in task.calls
任务总未命中输入 Token = sum(call.miss_tokens) for call in task.calls
任务总输出 Token = sum(call.output_tokens) for call in task.calls

任务 API 成本 = 三路合并后套公式

失败的调用不要丢。重试调用产生了真实 Token 消耗,就应该出现在任务成本里。如果你的日志只保留了最后一次成功调用,这条任务记录是不完整的,重算时会系统性低估。

is_retry 和 failure_reason 字段的价值就在这里:合并后你能看到这个任务因为哪类失败重试了几次,而不只是看到一个偏高的总数。

一个务实的边界:本文不给出"平均重试次数"或"缓存命中率"的参考数字,因为这些数字与任务类型、提示设计和缓存策略强相关,没有在自己系统里实测过的数据不可信。


第四步:单列人工 Review 与返工​

API 金额和人工时间是两种不同单位,不建议直接相加。

当 Agent 输出需要人工审核、修改或重做时,这部分时间是真实成本,但它不应该被换算成某个伪精确的"总交付成本",直接加到 API 金额后面。原因是:内部时薪口径、标准工时的定义和不同团队的记录粒度差异很大,用统一系数换算会掩盖真实差异。

建议的做法:

  • 人工 Review 时间单列记录,不与 API 金额合并。
  • 记录字段包括:task_id、reviewer(可匿名)、review_minutes、rework 是否发生、rework_reason。
  • 如果团队有统一认可的内部时薪口径,在做决策时自行换算,不要把换算结果写死在成本记录里。

这样做有一个额外的好处:当新价公布、API 成本变化时,人工成本部分不需要重算,两条记录完全独立。


第五步:正式新价公布后回算​

当 DeepSeek 正式公布新价时,回算操作应该是:

  1. 新建一个价格表版本,例如 price_v2_2026-XX-XX,填入新价格。不要覆盖 2026-08-06 的版本。
  2. 用历史任务记录分别套旧价和新价,得到两列成本。
  3. 按任务类型聚合,而不是直接比较全月总额。全月总额的差值告诉你涨了多少钱,任务类型的拆分告诉你哪类任务受影响最大。
  4. 如果你的任务类型之间缓存命中率差异明显,新价对不同任务类型的影响可能完全不同。只看总数会遮蔽这个差异。

如果你在考虑换 provider:先做字段映射,确认新 provider 的 usage 结构和你的记录格式对应,再做任务结果的对照评估,最后才比较成本。直接比较百万 Token 单价,在任务结果没有对齐之前意义不大。


关于 DeepSeek 磁盘缓存的几个边界​

DeepSeek 的上下文硬盘缓存对所有用户默认开启,不需要修改代码或传入额外参数。API 文档:https://api-docs.deepseek.com/zh-cn/guides/kv_cache

但默认开启不等于必然命中。几个实际边界:

  • 缓存命中要求完整匹配已经落盘的前缀单元,提示结构的细微变化可能破坏匹配。
  • 缓存是 best effort,不提供 100% 命中的保证。
  • 缓存构建耗时在秒级;如果一段时间没有使用,一般会在数小时到数天内清除,具体时间未公开。

所以"我的系统用了系统提示,缓存应该命中"是一个假设,不是结论。唯一可以信任的命中数字是 API 返回的 prompt_cache_hit_tokens。

同样的道理:用字符数估算 Token 数,只是粗略参考。实际计费以 usage 里的 Token 数为准。


五个常见错误​

用字符数估 Token,不保存 API usage。 字符换算是粗略估计,Token 化规则因语言和提示格式而异。等到需要解释账单时,估算值没有任何约束力。

假设默认缓存等于必然命中。 默认开启只意味着系统会尝试缓存。实际命中率取决于提示结构的稳定性和调用间隔,需要从 usage 里观测。

只记最后成功调用,漏掉失败和重试。 重试产生的 Token 消耗是真实的,不记录等于系统性低估任务成本。新价公布后回算时,低估的部分会被放大。

把低 API 金额写成低交付成本。 API 成本只是全部成本的一个维度。人工审核、返工和接入维护的时间没有出现在 Token 账单里,但它们是真实存在的。

把价格写死在业务逻辑,无法保留历史版本。 如果价格表没有版本化,新价公布后你只能选择全部重算或者放弃历史可比性,两个选项都很糟糕。价格表版本化是最低成本的预防措施。


最小行动清单​

以下操作不需要为本文额外发起任何调用,从现有任务记录里开始就可以:

  • 找一条真实任务日志,检查是否保存了完整 usage;Chat Completions 至少核对 hit、miss 与 completion_tokens,Responses API 至少核对 input_tokens、cached_tokens 与 output_tokens。
  • 确认这条记录有 task_id,能关联同一任务的所有调用(含失败调用)。
  • 如果当前日志只有总 Token 或总金额,确定从哪里能拿到原始响应,或者调整日志写入逻辑,从下一条任务开始保存完整 usage。
  • 建立 2026-08-06 价格版本,把当前三路价格写进一个可以引用的文件或配置项。
  • 用三路公式回算这条历史任务,把公式和结果一起保存。
  • 等 DeepSeek 正式公布新价后,新建价格版本,用同一批历史任务再算一次,按任务类型对比两次结果。

不同系统接入日志的方式不同,完成上面每项的时间因系统而异,不在本文估算。


说明​

如果你在阅读 DeepSeek 价格页时注意到了"当前表格 + 涨价脚注"这个组合,你可能和我有同样的反应:我没有继续猜涨幅,转而检查当前成本记录在价格变化后还能不能用。

Agent 任务的 API 账单不是一个数字,它是一组分路计量的结果:缓存命中走一路,缓存未命中走另一路,输出走第三路,重试会让所有路再过一遍。只要你把这三路数字保存下来,无论价格怎么变,回算都只是换一列数字的事。

DeepSeek V4-Flash 的模型权重和仓库以 MIT 协议开放,这与托管 API 的定价是两个不同的控制层。开放权重不能直接推导出自托管一定更便宜,那需要单独的成本建模,不在本文讨论范围内。

如果你已经在使用 DeepSeek API 驱动 Coding Agent,可以参考站内 DeepSeek V4 + Codex CLI 的接入教程,本文的记录结构可以直接叠加在那套接入方式上,不需要修改调用逻辑。