DeepSeek API 成本计算:缓存、输出与 Agent 重试预算指南
2026 年 8 月 6 日,DeepSeek 官方中文价格页新增了一条脚注:计划近期整体上调 API 服务定价,预计涨幅较大,具体方案以正式通知为准。
最终新价没有公布,生效日期也没有确认。
这篇文章不猜价格,不预测涨幅。它要解决一个更基础的问题:如果你现在的日志只有全月总 Token 或总金额,等新价公布后,你仍然无法解释是哪类任务、哪次缓存失效、哪轮重试推高了成本。你能换算出一个新的总数,但解释不了差异从哪里来。
本文的目标是帮你建立新价公布后可以直接回算的任务级成本记录。记录结构确定之后,无论是旧价算一遍还是新价算一遍,操作是一样的,只需要换价格表版本。
第一步:保存可复算的原始记录
完整 usage,不只是总 Token
DeepSeek 的 Chat Completions API 会在 usage 字段里返回这次调用的 Token 明细。关键字段包括:
prompt_tokens:本次请求的全部输入 Tokenprompt_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-Flash | 0.02 | 1 | 2 |
| DeepSeek-V4-Pro | 0.025 | 3 | 6 |
两个数字值得注意:
- 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 正式公布新价时,回算操作应该是:
- 新建一个价格表版本,例如
price_v2_2026-XX-XX,填入新价格。不要覆盖2026-08-06的版本。 - 用历史任务记录分别套旧价和新价,得到两列成本。
- 按任务类型聚合,而不是直接比较全月总额。全月总额的差值告诉你涨了多少钱,任务类型的拆分告诉你哪类任务受影响最大。
- 如果你的任务类型之间缓存命中率差异明显,新价对不同任务类型的影响可能完全不同。只看总数会遮蔽这个差异。
如果你在考虑换 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 的接入教程,本文的记录结构可以直接叠加在那套接入方式上,不需要修改调用逻辑。