Claude Code 长会话里的提示缓存:到底哪些部分被缓存了
本文以一次真实的 Claude Code 长会话为例,拆解提示缓存(prompt caching)在前缀中的命中情况:system prompt、工具 schema、静态文件上下文通常稳定可缓存,而每轮追加的对话、变动文件与命令输出会重写前缀。文章同时说明如何通过控制前缀稳定性、观察缓存读写字段来验证命中,并提醒不同供应商的缓存实现差异。
长会话里,Claude Code 每轮都会把大量上下文重新发给模型。如果每次都为整个前缀付费,成本会随对话轮数线性上涨。提示缓存(prompt caching)正是用来缓解这个问题的:它把前缀中重复的部分缓存起来,后续请求命中缓存时只需按更低的单价计费。但缓存不是自动生效的——它依赖前缀的逐字节稳定。下面用一个真实的 Claude Code 会话,拆解哪些部分会被缓存,哪些每轮都在重写。
先理解提示缓存的工作原理
大多数 LLM API 的提示缓存是前缀缓存:服务端对请求开头的 token 序列做精确匹配。只要前缀与上一次请求完全一致,就能命中;一旦中间某个 token 不同,从该位置之后的所有内容都无法复用缓存。
因此关键问题不是“什么内容值得缓存”,而是“什么内容在轮次之间保持不变”。在 Claude Code 这类 agent 工具里,请求结构大致是:
- system prompt
- 工具定义(tool schema)
- 历史消息(含用户输入、助手回复、工具调用结果)
- 当前轮的新增内容
缓存会从最前面开始匹配,直到遇到第一个变化点。
稳定前缀:system prompt 和工具 schema
在同一个 Claude Code 会话中,system prompt 通常是最稳定的部分。它由工具本身生成,只要版本、配置和会话模式不变,内容就逐字一致。这部分往往占据可观的 token 量,缓存命中后收益明显。
工具 schema 同样稳定。Claude Code 会注册一组工具(读文件、写文件、执行命令等),它们的名称、描述、参数结构在会话期间一般不会变。工具定义通常紧跟在 system prompt 之后,因此也属于可缓存前缀。
需要注意:如果工具集合在会话中途发生变化(比如动态启用了新工具、或某个 MCP 工具连接状态改变),工具 schema 部分就会变动,导致其后的所有内容缓存失效。保持工具集合稳定,是维持高缓存命中率的前提。
半稳定部分:文件上下文
文件上下文是缓存效果最微妙的一环。Claude Code 会把相关文件内容注入上下文,但这些文件按性质可以分为两类:
- 只读、未修改的文件:如果同一文件在后续轮次中内容不变,且注入位置和格式一致,这部分可以留在缓存前缀里。
- 被编辑或频繁变化的文件:只要文件内容变了,其对应的 token 序列就变了。如果它位于前缀中间,会切断之后的缓存。
实践中,文件上下文往往穿插在对话历史里,而不是集中在一个固定区块。这意味着一个文件的改动,可能让它之后的所有历史都无法命中缓存。这是长会话缓存命中率下降的常见原因。
每轮重写的部分
以下内容在 Claude Code 会话中几乎每轮都会变化,天然无法进入稳定前缀:
- 最新一轮的用户输入:总是追加在末尾,属于新增 token。
- 助手的回复:上一轮生成的内容,本轮成为历史的一部分;它是新增的,不影响之前前缀的缓存。
- 工具调用与命令输出:执行结果、日志、diff 等,内容每轮不同,且常被插入到历史中间。
- 时间戳、会话 ID、随机标识:如果它们出现在前缀靠前的位置,会直接破坏缓存。
把这些易变内容尽量放在请求末尾,是提升缓存命中率的核心策略。因为缓存是从前向后匹配的,末尾的变化不会影响前面已缓存的部分。
如何验证哪些部分命中了缓存
不同 API 供应商返回的缓存字段名称不同,但通常都会包含类似的信息:
- 本次请求写入缓存的 token 数(cache write / cache creation)
- 本次请求命中缓存的 token 数(cache read / cached tokens)
在 Claude Code 会话中,你可以观察这些字段的变化:
- 第一轮:缓存写入量高,命中量为零。
- 后续轮:如果 system prompt、工具 schema 和早期历史未变,命中量应显著上升。
- 当你编辑了某个早期文件、或工具集合改变后,命中量会骤降,甚至归零——这说明前缀被切断。
通过对比命中量的波动,就能反推出哪些部分真正进入了缓存。
实践建议
- 把稳定内容放前面:system prompt、工具 schema、固定的项目说明,尽量前置且保持不变。
- 把易变内容放后面:用户输入、命令输出、临时上下文,尽量靠近请求末尾。
- 避免前缀中的时间戳和随机值:它们会无声地破坏缓存。
- 谨慎编辑早期文件上下文:一次改动可能让之后的所有历史失效。
- 保持工具集合稳定:会话中途增删工具会重置前缀缓存。
不同模型的缓存行为差异
提示缓存的具体实现由各模型供应商决定,缓存粒度、TTL、最小可缓存长度、计价方式都可能不同。同一个 Claude Code 会话,走不同的 API 供应商时,命中情况和成本表现可能并不一致。因此,如果你通过聚合服务调用多个模型,需要分别观察各模型的缓存字段,而不是假设它们行为相同。
在按官方价 ×1.3 计费的聚合场景下,缓存命中的部分仍按供应商的缓存计价规则结算,理解哪些前缀被缓存、哪些每轮重写,有助于你判断长会话的真实成本结构,并据此调整上下文组织方式。