峰谷定价与成本模型:算清每一分钱的账
同一个任务,跑在闲时还是高峰、吃没吃到缓存,账单能差出 4 倍以上。更狠的是:很多人 Agent 跑了一晚上,连"钱主要花在输入还是输出"都答不上来。这一节我们把 DeepSeek 的账单拆到骨头缝里。
本文导航
- 价目表:先把数字钉在墙上
- 峰谷定价:错峰就是打折
- Prefix Caching:Agent 的天然红利
- 成本核算表:五分钟建一个
- 实战推演:一个 Agent 任务到底多少钱
- 省钱的四个抓手
- 小结
- 下节预告
前面三节我们啃协议、啃数据结构、盘能力,都是"技术账"。今天算"经济账"。
为什么要专门用一节算钱?因为 Agent 和普通应用有个本质区别:普通应用的边际成本约等于零,Agent 的每一次任务都是真金白银。一个 Agent 任务跑十轮循环,每轮都带着几千 token 的上下文进出模型——你如果对成本没概念,等于开着一辆不看油表的车上高速。
这节就干三件事:把价目表拆透、把 Prefix Caching 的便宜占到、把一个真实 Agent 任务的账算到分。
价目表:先把数字钉在墙上
DeepSeek(deepseek-flash,2026 年 9 月价目)按百万 token计价,分闲时/高峰两档:
| 计费项 | 闲时 | 高峰 | 高峰/闲时 |
|---|---|---|---|
| 输入(缓存命中) | 0.02 元 | 0.04 元 | 2x |
| 输入(缓存未命中) | 1 元 | 2 元 | 2x |
| 输出 | 4 元 | 8 元 | 2x |
三个观察,直接颠覆直觉:
第一,输入输出价差 4 倍。输出 token(1M 输出 4~8 元)是输入未命中价(1~2 元)的四倍。而 Agent 循环里,恰恰是输出(模型每轮的思考和点菜)重复发生。所以控制模型输出长度,比控制输入更值钱——让模型少说废话,是实打实的省钱。
第二,缓存命中价是未命中的 1/50。0.02 元对比 1 元,差 50 倍。这意味着:你的成本模型必须把"命中多少"当成一等公民,按未命中价算账会把 Agent 成本高估一个数量级(下面细说)。
第三,高峰全线上浮 2 倍。这不是小数目,而是一个可策划的变量——什么时候跑任务,本身就是一个工程决策。
峰谷定价:错峰就是打折
DeepSeek 的峰谷怎么划分?简单记:闲时=夜间到清晨,高峰=工作时段(具体时段以官方计费说明为准,边界可能随运营调整)。高峰服务器紧张所以贵,闲时机器空转所以便宜——本质和你家电费的峰谷一个逻辑,算力也是一种电。
对 Agent 开发者的启示:
- 批处理任务放闲时跑。数据清洗、批量代码审查、过夜评测——这些不赶时间的活,设个定时任务放凌晨,成本直接砍半。第 14 章做性能与成本优化时,我们会把"闲时调度"真正落地到 DeepPilot
- 交互式任务避不开高峰。用户坐在那等回答,没法错峰。但交互式任务往往是短任务,绝对金额小,心疼不来的
- 并发红利别浪费。deepseek-flash 给到 2500 并发,闲时大批量铺开任务,既便宜又快。对比某些闭源旗舰个位数到三位数的并发限制,这是 DeepSeek 面向 Agent 场景的诚意
一句话策略:能等的任务统统闲时跑。你的 DeepPilot 会在留痕系统里记录每次调用的时段,月底一分析,错峰策略执行得怎么样,数据自己会说话。
Prefix Caching:Agent 的天然红利
价目表里最魔幻的一行是"缓存命中 0.02 元"。它背后是 **Prefix Caching(前缀缓存)**机制——这是整个 Agent 成本模型里最重要的一块,值得单独拆透。
原理一句话:服务端发现你这次请求的开头,和最近某次请求的开头一模一样,就把那段复用起来,只按 1/50 计价。
什么算"开头一样"?逐 token 从头比对,直到第一个不同的 token 为止。重合的部分全按缓存命中计费。
为什么说这是Agent 的天然红利?回忆第 11 节:Agent Loop 每一轮都要把完整历史重发给模型。而历史的特点是——只增不改,前缀稳定!第 N 轮的请求 = 第 N-1 轮的请求 + 新增的两条消息。这意味着 Agent 循环转得越多,缓存命中率越高,"重发历史"这个最大成本项被缓存打了一折。
直接上数字感受一下。假设一个 Agent 任务 10 轮循环,每轮 system+工具说明书占 3000 token 固定前缀:
- 无缓存的世界:10 轮 × 3000 token 全按 1 元档计,固定前缀花掉 3 万 token 当量的钱
- 有缓存的世界:第 1 轮未命中(3000×1 元档),第 2~10 轮那段全命中(27000×0.02 元档)→ 固定前缀成本降到约 1/8
而且你不用写一行代码去开启它——缓存命中自动发生、自动计费,服务端默默帮你省钱。你要做的只有一件事:设计好请求结构,让前缀尽可能稳定。这就是后面"省钱抓手"的第一条。
成本核算表:五分钟建一个
"五条铁律"说要算清每一分钱,现在动手建核算模型。用 pydantic 定义(JSON 处理一律走 pydantic,老规矩):
"""cost_model.py —— DeepSeek 峰谷成本核算模型(离线可跑)。"""fromdatetimeimportdatetimefrompydanticimportBaseModel,Field# 价目表(元 / 百万 token),来源:DeepSeek 官方 2026-09PRICING={"offpeak":{"hit":0.02,"miss":1.0,"output":4.0},"peak":{"hit":0.04,"miss":2.0,"output":8.0},}classUsage(BaseModel):"""单次调用的 token 用量——留痕系统里最核心的四个数。"""prompt_cache_hit:int=0# 输入:缓存命中部分prompt_cache_miss:int=0# 输入:未命中部分completion:int=0# 输出phase:str=Field(default="offpeak")# 峰/谷标记defcost_yuan(self)->float:p=PRICING[self.phase]m=1_000_000return(self.prompt_cache_hit*p["hit"]+self.prompt_cache_miss*p["miss"]+self.completion*p["output"])/m# 模拟一次典型 Agent 调用:3000 命中 + 500 未命中 + 800 输出,闲时u=Usage(prompt_cache_hit=3000,prompt_cache_miss=500,completion=800)print(f"闲时单次成本:{u.cost_yuan():.4f}元")u.peak_used=Noneprint(f"同一调用跑在高峰:{u.model_copy(update={'phase':'peak'}).cost_yuan():.4f}元")print(f"若无缓存(全未命中)闲时: "f"{u.model_copy(update={'prompt_cache_hit':0,'prompt_cache_miss':3500}).cost_yuan():.4f}元")$ uv run python cost_model.py 闲时单次成本: 0.0146 元 同一调用跑在高峰: 0.0292 元 若无缓存(全未命中)闲时: 0.0440 元看清楚这三个数的差距了吗?同一个调用,三种命运:闲时带缓存 0.015 元,高峰带缓存 0.029 元,无缓存 0.044 元。差 3 倍。这就是为什么成本模型必须区分峰谷和命中——一个变量都不该糊。
这张Usage模型后面会原封不动进 DeepPilot 的留痕系统(第 7 章):每次调用记一条,atexit 汇总输出。到时候你月末拿一句提示词就能问出"平均单次成本多少、峰值出现在哪天"这类问题。
实战推演:一个 Agent 任务到底多少钱
核算模型有了,来推演一个真实场景:**“帮我把这个项目所有 TODO 修掉”**这种中等复杂度的 Agent 任务。
先估算流量模型(实测经验值,量级可靠):
15 轮下来:输入总量约 11.7 万 token。因为历史只增不改(第 N 轮请求是第 N+1 轮请求的前缀),其中约 10.5 万 token 吃到缓存命中,真正的新内容只有约 1.2 万。代入核算模型:
"""task_cost.py —— 完整 Agent 任务成本推演(离线可跑)。"""ROUNDS,PREFIX,TASK,GROWTH,OUTPUT=15,3000,600,600,500# 关键机制:历史只增不改 → 每轮只有"新增的 600"未命中,其余全是缓存命中hit=miss=0forninrange(1,ROUNDS+1):ifn==1:miss+=PREFIX+TASK# 首轮:前缀+任务指令都是新的else:miss+=GROWTH# 后续轮:只有新增历史未命中hit+=PREFIX+TASK+GROWTH*(n-2)# 其余全是上一轮发过的旧内容out=ROUNDS*OUTPUT m=1_000_000forphase,(h,mi,o)in{"闲时+缓存":(0.02,1.0,4.0),"高峰+缓存":(0.04,2.0,8.0),}.items():cost=(hit*h+miss*mi+out*o)/mprint(f"{phase}: 命中{hit/10000:.1f}万 + 未命中{miss/10000:.1f}万"f" + 输出{out/10000:.1f}万 token →{cost:.2f}元")no_cache=((hit+miss)*1.0+out*4.0)/m# 对照:假设缓存不存在print(f"对照:闲时若无缓存(全未命中) →{no_cache:.2f}元")$ uv run python task_cost.py 闲时+缓存: 命中10.5万 + 未命中1.2万 + 输出0.8万 token → 0.04 元 高峰+缓存: 命中10.5万 + 未命中1.2万 + 输出0.8万 token → 0.09 元 对照:闲时若无缓存(全未命中) → 0.15 元三个结论直接出来:
- 修完整个项目的 TODO,闲时成本只要 4 分钱。这个价格在 2023 年够干什么的?连一次像样的 GPT-4 调用都买不起。这就是第 4 节说的"算力平权"落到你账单上的样子
- 缓存把 10.5 万 token 从 1 元档挪进了 0.02 元档——对照无缓存的 0.15 元,同样的活便宜了近 4 倍。这就是"历史只增不改"白送的折扣
- 高峰跑贵一倍:0.04 → 0.09 元。批处理任务放闲时,一次省一半
省钱的四个抓手
把本节内容沉淀成可执行的省钱策略,按性价比排序:
| 抓手 | 做法 | 收益量级 |
|---|---|---|
| ① 稳定前缀 | system+工具说明书放消息最前面,且绝不逐轮改动 | 命中率最大化,固定成本降 50 倍档 |
| ② 压输出 | 提示词里限定输出格式;思考模式按需开 | 输出价是输入 4 倍,砍输出最值钱 |
| ③ 错峰批处理 | 不赶时间的任务闲时跑 | 直接砍半 |
| ④ 砍历史 | 上下文工程(第 11 章):过期工具结果及时清退 | 输入增量的源头治理 |
其中 ① 和第 11 章的上下文工程直接挂钩——为什么系统提示要放最前、为什么"动态注入的检索内容"要放消息后部而不是前部?就是因为任何对前缀的改动,都会让后面全部内容的缓存一夜归零。这是缓存友好的请求设计,你会在 DeepPilot 里看到它被贯彻到底。
小结
- 价目三要点:输出是未命中输入的 4 倍价(压输出最值钱);缓存命中价是未命中的 1/50(命中是一等公民);高峰全线 2 倍(错峰=打五折)。
- Prefix Caching 是 Agent 的天然红利:循环重发历史的"只增不改"特性,让前缀缓存自动吃到 50 倍折扣,不需要写一行代码,只需把前缀设计稳。
- 成本核算三变量:峰/谷、命中/未命中、输入/输出——一个糊了账就废,用 pydantic
Usage模型固化下来进留痕系统。 - 实战量级:中等 Agent 任务(15 轮)闲时约 0.04 元——算力平权落到账单上的实感。
- 省钱四抓手:稳定前缀、压输出、错峰批处理、砍历史——①是设计约束,②③是策略,④靠第 11 章。
下节预告
账算清了,下一节解决体验——流式输出 SSE:逐 token 呈现的魔法与陷阱。为什么 ChatGPT 打字机效果背后是 SSE 协议?stream=True返回的 chunk 长什么样、finish_reason四种取值各代表什么、断流了怎么重连?我们手写一个带进度条的流式客户端,把"等 30 秒白屏"变成"每 50 毫秒看得见进展"。这也是 DeepPilot 交互体验的地基。
如果觉得本文对你有帮助,欢迎点赞、收藏、关注三连!
本系列持续更新中,80篇硬核实战,关注不迷路~