DeepSeek API 价格:缓存命中后,怎样不重复计算输入费用
估算 DeepSeek 费用,需要三个 token 桶,以及实际付费服务的费率。重复提示词不保证命中缓存;应先读取 usage,从总输入中分出缓存命中,再与单次请求账单核对。
发布 2026-09-23 · 更新 2026-09-29 · KeepRouter Editorial · 5 分钟阅读

估算 DeepSeek API 费用,先把用量分成未缓存输入、缓存命中输入和生成输出,再分别乘以对应费率。通过 KeepRouter 付费时,应使用实时模型目录中的客户价格;直接向 DeepSeek 付费时,则使用其官方账单口径。模型名称接近,不代表两条服务路径的价格、缓存状态或能力完全相同。
本文以“对同一份文档连续提问”为例,说明怎样从 usage 得到可核对的估算。下面的数字是算术示例,代码是实现建议,都不是生产实测报告。可以先打开 DeepSeek V4 Pro 目录页,确认当前端点与价格,再在 API 费用计算器选择对应 KeepRouter 模型并填写用量假设。厂商直连费率应按下文公式另建工作表计算。KeepRouter 的模型 ID 表示本站路由,不应据此推断任意同名上游部署的完整能力。
先拆分用量,再计算金额
Chat Completions 响应里的 prompt 总数通常包含已命中的输入。DeepSeek 文档同时列出 prompt_cache_hit_tokens 和 prompt_cache_miss_tokens;兼容响应还可能使用 prompt_tokens_details.cached_tokens。这些字段可能是在表达同一份命中量,不能把它们当成两次折扣相加。
| 变量 | 含义 | 计算方式 |
|---|---|---|
| I | 总输入 token | 拆成未命中和命中两部分 |
| H | 报告为缓存命中的输入 | 乘缓存输入费率 |
| O | 输出 token | 乘输出费率 |
| Pi、Ph、Po | 每百万 token 美元价 | 使用同一服务的费率 |
公式为 ((I-H)×Pi + H×Ph + O×Po) / 1,000,000,并检查 0 <= H <= I。如果从控制台导出的输入列已经表示“未缓存输入”,就不要再次减去缓存量。保留原始 usage 与转换后的字段,才能在账单出现差异时恢复每列原来的含义。
用一笔假设请求算清楚
假设一笔请求有 20,000 个输入 token,其中 16,000 个命中缓存,另有 1,000 个输出 token。为了便于算术,假设未缓存输入每百万 $1、缓存输入每百万 $0.10、输出每百万 $4。以上是人为设置的整数费率,不是 DeepSeek 或 KeepRouter 的当前报价。
未缓存部分为 $0.004,缓存部分为 $0.0016,输出为 $0.004,合计 $0.0096。若同样的 token 数没有任何缓存命中,则为 $0.024。这里固定了输出长度与价格,并不能预测下一笔请求的命中比例,也不能说明另一模型会生成同样多的 token。
估算月度费用时,应逐笔相加,或把输入长度相近的请求分组。首次上传、以后不再读取的文档,与连续多轮提问的文档,成本结构不同。把冷请求、重复请求、重试与长回答分别统计,不能把最有利的一次命中比例乘到整个月流量上。
明确字段语义的解析代码
下面的本地解析器处理常见 DeepSeek/OpenAI Chat Completions 字段。它帮助理解账单,不替代服务端账本。
def token_buckets(usage):
total = usage.get("prompt_tokens")
details = usage.get("prompt_tokens_details") or {}
hit = details.get("cached_tokens")
if hit is None:
hit = usage.get("prompt_cache_hit_tokens", 0)
if total is None:
miss = usage.get("prompt_cache_miss_tokens")
if miss is None:
raise ValueError("No input breakdown; inspect raw usage")
total = hit + miss
output = usage.get("completion_tokens")
values = (total, hit, output)
if any(type(v) is not int or v < 0 for v in values):
raise ValueError("Incomplete or invalid token counts")
if hit > total:
raise ValueError("Cache hits exceed total input")
return {"uncached": total - hit, "cached": hit, "output": output}缺失输出计数时,应留下待核查记录,而不是默认为免费输出。流式客户端需要接收该路由提供的末尾 usage 事件;取消请求可能中断客户端采集,因此应继续用请求的用量记录核查,不能仅凭页面停止显示就认为没有扣费。
每次缓存实验只回答一个问题
DeepSeek 将前缀缓存描述为尽力而为,当前规则还区分已经落盘的前缀单元与任意重叠文本。因此,“几乎相同的提示词发了两遍”并不足以证明缓存坏了。
选择一份合成文档与固定系统指令,记录请求顺序及完成时间。先提出一个问题,再保留前面消息继续对话,然后另发一份不同文档作为冷请求。记录各笔命中计数。每轮只改变一个因素,例如文档前缀、消息顺序或空白字符,不要同时更换模型、端点与提示词排版。
实验结论应写明:哪种具体请求序列,在什么模型 ID、什么日期产生了报告中的命中。响应变快可以作为性能观察,但单凭速度不能证明命中缓存。命中缓存也不是重放旧答案;输出仍会重新生成,内容和长度都可能变化。
用固定样例抓住重复计算
总输入 20,000、缓存命中 16,000 的响应样例,应得到 4,000 个普通输入 token。再加一条缓存超过总输入的样例,要求报错,不能算出负费用。DeepSeek 缓存文档说明厂商机制,具体字段仍按所选端点实际返回含义处理。把估算接入月预算前,这个算术检查就能发现常见问题。
把实验结果变成预算
用目标功能的实际输入和输出分布做预算,同时保留零命中、观察到的命中比例、较长回答三种场景。如果三种预算差距很大,应在扩大调用量前给应用加上请求或任务上限。第一批付费调用完成后,把估算与控制台扣费记录对齐,有差异就保留请求标识继续调查。
想了解缓存字段和账本之间的关系,可以阅读缓存价格核对指南;接入代码见 OpenAI SDK 指南。价格或业务请求发生变化时,重新运行计算器,不要把本文的假设费率固化到生产配置。
常见问题
重复提示词一定命中缓存吗?
不一定。DeepSeek 将前缀缓存描述为尽力而为,应检查具体请求序列的命中计数。
缓存 token 要加到 prompt_tokens 上吗?
若 prompt_tokens 已包含缓存部分,就不应再次相加;应先拆成未缓存和缓存输入。
算例费率是当前报价吗?
不是。它们是便于计算的假设数字;实际应使用给该请求计费的服务价格。
能用一次热缓存请求估算整月吗?
不可靠。应先区分冷请求、重复上下文、重试和不同输出长度,再推算流量。
参考的一手资料
本文最近复核 2026-09-29
- [1] DeepSeek context caching
- [2] DeepSeek Chat Completions usage fields
- [3] KeepRouter current model prices