把系统消息顶部大约30个token挪到底部,稳态推理成本降96%。这是一份在DeepSeek上跑出来的基准测试结果。

如果你在做聊天或角色扮演类应用,系统消息大概率是你发给模型的内容里最大的一块。一张角色卡、一本世界书、一段记忆摘要,动辄几万token,而且每一轮对话都要重新发一遍。

打开网易新闻 查看精彩图片

DeepSeek的上下文缓存本来就是为了让这部分变便宜。它默认开启,不需要改代码,缓存命中的输入价格是未命中的五十分之一——每百万token 0.003美元,对比未命中的0.15美元(非高峰时段)。

但实际用起来,大多数应用几乎一点缓存都吃不到。问题不在缓存本身,而在系统提示词顶部的一行代码。

三个变体,只差一个位置

测试用的是一段真实的角色扮演提示词:角色卡、含20条词条的世界书、长期记忆、关系状态,拼成一个约20000 token的稳定块。

然后跑三个变体。三个变体里的稳定内容逐字节完全相同,唯一变化的是那一小段易变头信息放在哪里。这段头信息长这样:会话上下文,包含本地时间戳、轮次、会话ID、情绪指数。

总共大约30个token,几乎可以忽略不计。三个变体分别把它放在:顶部、稳定块之后、底部。

每个变体都对着deepseek-flash跑了8轮真实对话,关闭思考模式。所有数字都来自API自己的用量字段——缓存命中token数和缓存未命中token数,没有任何建模推算。

第一轮在所有变体里都是缓存未命中,因为缓存是冷的,还没有东西可以匹配。排除这次冷启动,只看稳态:

  • 变体A:8轮里一次缓存命中都没有。整个17000 token的前缀每次都按全价重新处理,只因为请求最前面那约30个token不一样。
  • 变体B和C:命中率落在彼此0.7个百分点以内。

一行改动,拿走大部分收益

B和C的差距小到可以忽略。你不需要重新设计架构就能拿到绝大部分收益,只需要挪动一个字符串。

但对话变长之后,C会逐渐拉开差距。看每轮的绝对缓存命中token数:

B稳定在16896 token不动,这个数字是264乘以64,而64看起来就是缓存的粒度。因为B的系统消息每轮都在变,只有头信息之前的稳定块能被复用,对话历史成了永远被重算的死重。

C则持续攀升,因为它的系统消息是冻结的,历史是只追加的,每一轮命中的缓存前缀都包含之前的所有内容。

放在8轮对话里,这个差距很小。放到50轮的会话里,就不是了。

规则写得很清楚,但很容易漏掉

DeepSeek的文档把规则写得很明白:缓存命中要求对应的前缀已经被持久化,后续请求只有完全匹配某个缓存前缀单元时才能命中。

“完全”是关键词。前缀缓存在分叉点上是全有或全无的。把一个时间戳放在位置零,那么它之后的所有内容在缓存看来都是新内容——哪怕99.99%的字节和上一次请求一模一样。

这一点不用花钱也能验证:直接对比第一轮和第二轮请求体的原始差异,84665字节里只有75字节不同。整个故事就藏在这75个字节里。

把实测的稳态单轮成本外推到日活1000、平均50轮的应用上,就是那个96%的降幅。比例才是真正的发现,绝对金额取决于你的提示词大小和调用量。

顺手再检查一件事

如果你用的是这个模型系列,还有一件事值得确认:思考模式默认开启,强度设为高,而推理token是按输出计费的。

角色扮演和聊天应用并不需要思维链。用户想要的是角色内的回复,不是一段内心独白。如果你的集成没有显式关掉它,可能每条消息都在为推理付费。关闭方式是在请求里加上:thinking 类型设为 disabled。

第一轮排查不需要什么基准测试框架。只要看一眼你的请求是怎么拼的,问自己两个问题:系统消息里有没有时间戳、轮次、会话ID这类