07 - Prompt Caching 架构

Cache Rules Everything Around Me

Claude Code 的整个架构都是围绕 Prompt 缓存构建的。高命中率不光省钱,速率限制也会松很多。Anthropic 甚至会对命中率跑告警,太低直接宣布 SEV。

前缀匹配机制

Prompt 缓存按前缀匹配工作,从请求开头到每个 cache_control 断点之前的内容都会被缓存。顺序很重要:

Claude Code 的 Prompt 顺序:
1. System Prompt    → 静态,锁定
2. Tool Definitions → 静态,锁定
3. Chat History     → 动态,在后面
4. 当前用户输入     → 最后

破坏缓存的常见陷阱

  • 在静态系统 Prompt 中放入带时间戳的内容(让它每次都变)
  • 非确定性地打乱工具定义顺序
  • 会话中途增删工具

动态信息(如当前时间)怎么办?别动系统 Prompt,放到下一条消息里传进去。Claude Code 自己也是这么做的——用户消息里加 <currentDate> 标签,系统 Prompt 不动,缓存就不会被打坏。

跨模型缓存

Prompt 缓存是模型唯一的。假如已经和 Opus 对话了 100K tokens,想问个简单问题,切换到 Haiku 实际上比继续用 Opus 更贵——因为要为 Haiku 重建整个缓存。

需要切换的话,用 Subagent 交接:Opus 准备一条”交接消息”给另一个模型,说明需要完成的任务。

Compaction 的实际实现

上下文快满时,Claude Code 开一个 fork 调用,把完整对话历史喂给模型,加一句 “Summarize this conversation”。这一步命中缓存所以只需 1/10 的价格。压缩完之后,原来几十轮对话被替换成一段 ~20K tokens 的摘要,System + Tools 还在,再挂上之前用到的文件引用,腾出空间继续新的轮次。

Plan Mode 的缓存考量

直觉上 Plan Mode 应该切换成只读工具集,但这会破坏缓存。实际实现是:EnterPlanMode 是模型可以自己调用的工具,检测到复杂问题时自主进入 plan mode,工具集不变,缓存不受影响。

defer_loading:工具的延迟加载

Claude Code 有数十个 MCP 工具,每次请求全量包含会很贵,但中途移除会破坏缓存。解决方案是发送轻量级 stub——只有工具名,标记 defer_loading: true。模型通过 ToolSearch 工具”发现”它们,完整的工具 schema 只在模型选择后才加载,这样缓存前缀保持稳定。


Prev: 06 - Subagents 使用 | Next: 08 - 验证体系与命令速查