01 缓存到底缓存了什么
要讲缓存,先得把它和几件容易混在一起的东西分开。
这里说的 prompt caching,重点在输入前缀复用。它和模型长期记忆、语义相似检索属于不同问题:模型厂商发现这次请求的前半段,和之前某次请求的前半段一致,于是已经处理过的那部分输入可以用更低成本读取。
关键点在“前缀一致”。
一个简化后的 Agent 请求,大概可以拆成这样:
[tools]
[system]
[project rules]
[conversation history]
[tool results]
[new user message]
普通聊天里,用户可能不太关心这个结构。到了 AI Agent,前面的固定内容会变得很大:工具定义、系统提示词、项目规则、开发规范、模型能力说明、平台上下文、历史消息、工具结果,都可能进入同一轮输入。
真正新增的内容,很多时候只是最后那句用户指令。
缓存能省的,就是前面那批重复输入。
如果 [tools][system][project rules] 这些内容连续多轮保持一致,后续请求追加新消息时,前缀就有机会命中缓存。模型不需要每次都按普通输入价格处理这段内容,首 token 延迟也可能下降。
反过来,缓存也很容易被一些动态内容打断。
比如这些内容如果出现在请求靠前位置,并且每轮都变化,命中率就会受到影响:
- 当前时间
- 随机 request id
- 每轮重新排序的工具列表
- 动态拼接的 system prompt
- 会变化的 token budget 提示
- 当前 git branch、cwd、窗口大小等运行状态
- MCP server 临时增删后产生的新 tool schema
这类问题在 Agent 框架里很常见。用户并没有输入多少新内容,但框架每轮都在前缀里加入动态字段,导致本来可以复用的上下文被当成新输入处理。
所以,prompt caching 不能只看模型厂商有没有支持。Agent 怎么组织上下文,同样重要。
比较稳妥的做法,是把长期稳定的内容放在靠前位置,把每轮变化的内容放到后面。工具 schema、系统规则、项目规则这类内容越稳定,缓存越容易发挥作用;时间戳、运行状态、临时提示这类内容越靠前,缓存越容易失效。
还要注意一点:缓存主要影响输入侧。
模型最终输出的内容,每轮仍然要生成。缓存省的是重复上下文的读取成本和预填充延迟。它不会让输出免费,也不会自动提升回答质量。
因此,看缓存有没有发挥作用,不能只看总 token。更有用的是看输入 token 里有多少被缓存读取,有多少新写入缓存,有多少完全没有命中。
不同厂商给这些字段起的名字不一样:
- Claude:
cache_creation_input_tokens、cache_read_input_tokens、input_tokens - OpenAI:
cached_tokens - DeepSeek:
prompt_cache_hit_tokens、prompt_cache_miss_tokens
字段名字不同,真正要看的问题很直接:这一轮输入里,重复内容有没有被低价复用。
只要这个问题看不见,模型单价就只能解释账单的一小部分。长会话和 Agent 的真实成本,还取决于上下文怎么排、缓存怎么命中、命中之后有没有体现在账单里。
后面讲 Claude 的 cache breakpoint、5 分钟和 1 小时 TTL、OpenAI 的自动缓存、DeepSeek 的硬盘缓存,核心都围绕这一点展开:稳定前缀越清楚,缓存收益越容易计算;动态内容越早出现,账单越容易失控。