同样是 100 万 token 的输入,DeepSeek v4-flash 高峰时段:缓存命中 0.10 元,未命中 3.00 元——差价 30 倍。对纯聊天的普通应用,这个差距往往感知不到;但只要你的 Agent 不是「一问一答」,而是每完成一个指令要跑十几轮工具调用的多轮 Agent,这个差价就会直接变成账单上的「惊喜」。
原因很朴素:Agent 每走一步,都要把「系统提示 + 工具说明 + 聊天记录 + 刚拿到的工具结果」整体重发一遍;为了让 Agent「有记忆」,这些消息还是累加发送的——模型推理了几轮,前面的内容就跟着重发几遍。上下文越长、轮次越多,输入 token 的膨胀越夸张,缓存命中率对总成本的影响就越致命。
DeepSeek Harness(DeepSeek 官方 Agent 框架,本板块 8/16、8/22 已做过两期深度分析)在实测中把缓存命中率做到了 99%。它没有黑魔法,靠的是一套可复制的工程纪律。这篇文章把它的源码思路拆开,并对照 DeepSeek 官方缓存文档核实每一处规则——结论是:缓存优化不是调参,是消息组装架构。
一、先算账:30 倍价差是怎么落进账单的
DeepSeek 官方定价(每百万 token,元):
| 计费项 | v4-flash 空闲 | v4-flash 高峰 | v4-pro 空闲 | v4-pro 高峰 |
|---|---|---|---|---|
| 输入 · 缓存命中 | 0.05 | 0.10 | 0.15 | 0.30 |
| 输入 · 缓存未命中 | 1.50 | 3.00 | 4.50 | 9.00 |
| 输出 | 4.50 | 9.00 | 13.50 | 27.00 |
注意:不管是空闲/高峰、flash/pro,命中价与未命中价的比例恒为 1:30。所以实际输入单价可以这样算:
实际输入单价 = 命中率 × 命中价 + (1 − 命中率) × 未命中价
以 v4-flash 高峰价(命中 0.10 / 未命中 3.00)为例:
| 命中率 | 100 万输入 token 实际价格 | 相当于全未命中的 |
|---|---|---|
| 0% | 3.000 元 | 100% |
| 90% | 0.390 元 | 13% |
| 99% | 0.129 元 | 4.3% |
二、缓存在缓存什么:prefill 与 KV cache
要理解缓存规则,先理解 LLM 推理的两个阶段:
- prefill(预填充):模型收到输入后,对所有输入 token 做一遍前向计算,生成每一层的 KV 状态(Key-Value Cache)。长上下文的大部分 GPU 成本就花在这里。
- decode(解码):基于 KV 状态逐个生成输出 token。
DeepSeek 的「Context Caching」把请求输入部分的 KV 状态存到硬盘:当下一个请求的开头与之前完全一致时,服务端直接加载这份 KV 状态,跳过绝大部分 prefill 计算。可以理解为——模型读完上下文后留下了一份「计算结果存根」,下次遇到完全相同的开头,直接从硬盘取回,省掉重复计算。
prompt_cache_hit_tokens(命中的输入 token 数)与 prompt_cache_miss_tokens(未命中的),二者相加即本次输入 token 总数。缓存是尽力而为(best-effort),不承诺 100% 命中;缓存构建需要数秒,闲置后数小时到数天自动清除。三、官方命中规则:三条持久化 + 一个硬约束
DeepSeek 的磁盘缓存(受滑动窗口注意力机制影响)与常规前缀缓存有一个关键差异:缓存按「前缀单元」整块存储和匹配,后续请求必须完整匹配某个已持久化的单元才能命中。官方文档给出三条持久化时机:
- 请求边界持久化:每次请求在「用户输入结束处」和「模型输出结束处」各产生一个缓存前缀单元。例:第一轮
A+B,第二轮A+B+C→ 完整匹配A+B单元,命中。 - 公共前缀检测持久化:系统发现多次请求有公共前缀时,会把它单独持久化为一个单元。例:先发
A+B、再发A+C(本轮无法命中A+B),但系统检测出公共前缀A并单独保存;第三次发A+D→ 命中A。 - 固定 token 间隔持久化:对长输入/长输出,按固定 token 间隔切出单元,避免长前缀因永远到不了「结束位置」而完全无法缓存。
A+B+C+D+E,下一轮 A+B+X+D+E——能复用的只有 A+B,从 X 开始即使 D、E 与上轮完全一样,也无法续用旧缓存。这是理解一切缓存优化技巧的总纲。四、Agent 弄丢缓存的四种典型姿势
理论上多轮 Agent 是前缀缓存的最佳受益者——每轮在上一轮末尾追加内容,可复用前缀只会越来越长。但实际开发中命中率经常惨不忍睹,根因都是同一个:框架在调模型前重新组装了一次请求,而「组装」悄悄改变了开头。四种最常见的姿势:
① 系统提示每轮都在变
把当前时间、当前目录、权限状态、随机 ID 等动态信息直接拼进系统提示。系统提示位于请求最前面,任何一处变化都会截断整个缓存。这是最常见、杀伤力最大的一种。
② 工具列表顺序不稳定
上一轮工具顺序 read, bash, edit,下一轮变成 bash, edit, read——工具没变、Schema 没变,但序列化后的 token 顺序变了。若工具说明位于大量历史消息之前,这一变,后面整段缓存全部作废。
③ 每轮重新整理历史消息
发送前重排消息顺序、重新序列化 XML/JSON、改写之前的消息。程序看来「意思没变」,但多一个空格、字段顺序变化、重新序列化都会产生新的 token 序列,进而产生新的前缀。
④ 请求参数在后台悄悄变化
因额度/超时自动切换模型或服务商、插件运行时动态改参数或注入一段系统提示——只要这些变化最终影响了请求头、系统提示或工具定义,就形成一条新前缀。
五、DeepSeek Harness 的五步保前缀法
DeepSeek Harness 是插件化 Agent 框架:系统提示、工具、运行环境都由插件提供。插件一多,怎么保证前缀稳定?Harness 的思路是:缓存数据存在 DeepSeek 服务端,Harness 不管缓存本身,只管让自己发出去的相邻两轮请求拥有相同开头。实现分五步:
第 1 步:稳定内容与可变内容分开登记
插件把内容交给统一登记处,Harness 组装时统一决定谁在前、按什么顺序。源码里分了四类入口:系统提示 section()、工具 tools()、可变状态 context()、模型名/工作目录等填充值 variable()。判断标准只有一个:这项内容在会话运行期间会不会变。当前工作目录虽属环境信息,但同一会话内基本不变,就留在系统提示里。
第 2 步:每轮按同一套规则排序
每轮重新取出可见内容,按固定规则组装:系统提示按登记编号排列,工具未指定位置则按名称排序。顺序稳定本身就是为了避开「内容相同、顺序变了」这种毫无必要的缓存杀手。模型名、工作目录等动态值在此时写入系统提示;参数名写错或取不到值,Harness 在请求发出前直接报错,不带着脏前缀出门。
第 3 步:可变状态追加到历史末尾
沙箱模式、审批策略、子 Agent 权限这类「影响模型当下能做什么」的内容,会整理成一份运行状态快照(runtime context)。每轮开始时与上一轮比较:相同则不重复发送;变了则生成一条新消息追加到会话末尾;上一轮有、本轮清空了,也追加一条「清空消息」告知模型旧状态失效。这一步对缓存最关键——变化只发生在尾部,前面的 system、tools、历史消息原封不动,下一轮长前缀照常可复用。
第 4 步:请求参数与内容一并记日志
模型名、温度、最大输出长度等调用参数连同系统提示、工具列表一起写入会话日志:首次调用写完整记录,之后只有真正变化才新增变化记录。缓存命中率哪天突然下降,翻日志就能定位「哪一轮出现了新记录、模型/提示/工具/参数改了什么」。
第 5 步:每次从同一份日志还原请求,并冻结核对
每次调用模型,Harness 按日志顺序取回用户消息、模型回答、工具结果,与记录在 request header 里的系统提示/工具/参数合并成完整请求。组装好后请求被冻结——发送插件只能查看、不能临时改一句系统提示或换工具;发送前还会从日志取回消息逐项比对,对不上就报错阻止发送。模型返回后,回复追加进同一份日志。下一轮从头还原,中间没有改动,上一轮完整请求自然成为下一轮的开头。
六、自检清单:自己写 Agent 时照着查
核心口诀:旧内容不改,新内容后加。逐项检查:
- 系统提示的各段内容有固定名字、固定顺序(不要动态拼接)。
- 当前时间、随机编号、环境状态放到消息尾部,绝不进系统提示。
- 工具按名称或明确配置排序,工具参数的字段顺序也要稳定(序列化时固定 key 顺序)。
- 历史消息只追加、少重排少改写——「重新格式化」等于亲手废掉自己的缓存。
- 模型、服务商、参数变化时留下明确记录(日志里可审计)。
- 上下文压缩时,尽量保留前面仍可复用的内容——截断也是改变前缀。
七、延伸:前缀稳定是 Agent 框架的「隐形架构」
这篇文章的价值不止于省几十块钱。把视野拉高一层:「把动态内容沉到尾部」正在成为 Agent 框架的标准架构共识——OpenAI、Anthropic 等主流平台的 prompt caching 文档里,最佳实践第一条几乎都是「保持系统提示稳定、把易变内容放后面」。谁在框架层面把这条纪律做成了默认行为(而不是交给开发者自觉),谁就在长会话、高频工具调用的场景里天然拥有成本优势。
回头看本板块 8/16《DeepSeek Harness 深度分析》与 8/22《Harness 双雄》讲的「Agent 底座之争」——缓存命中率其实是被低估的第四维竞争维度:模型能力、生态、价格之外,同样的模型价格表,底座框架不同,跑同样任务的真实账单可能差一个数量级。对自研 Agent 平台来说,这不是「能省则省」的优化项,而是架构期就要定死的设计决策。
参考来源
· 叶小钗:《DeepSeek Harness 源码拆解:1/30 的输入价,99% 的缓存命中率》(2026-09-02,本文素材来源)
· DeepSeek API Docs:Context Caching(磁盘缓存机制、持久化时机、命中规则、usage 字段)
· DeepSeek API 定价页(v4-flash / v4-pro 输入命中/未命中/输出三档计费)
· 本板块:DeepSeek Harness 深度分析 · 开源 Agent 底座(2026-08-16)
· 本板块:Harness 时代——龙虾之死与双雄并立 · Agent 底座之争终局推演(2026-08-22)