Claude Code 学习站

Claude Code 提效实录:Prompt Caching 才是关键

摘要 Anthropic 官方博文,讲解 Claude Code 团队如何通过 prompt 布局、消息更新、工具与模型一致性等手段最大化 prompt caching 命中率。

本页目录7
要点速览
  • prompt 前缀顺序决定缓存命中率,固定不变的内容应放在最前面
  • 信息更新应通过消息(如 system-reminder)插入,而不是修改已缓存的系统提示词
  • 会话中途不要切换模型或增删工具,否则会让已缓存前缀失效
  • 上下文压缩(compaction)时应保持系统提示词、上下文与工具定义不变,只让压缩指令(compaction prompt)本身成为新增 token
  • Claude Code 团队把缓存命中率当作核心可用性指标来监控,下降即视为严重问题

本文是对 Anthropic 官方博文《Lessons from Building Claude Code: Prompt Caching is Everything》(作者:Thariq Shihipar,Claude Code 团队)的中文要点摘要,完整内容以原文为准:https://claude.com/blog/lessons-from-building-claude-code-prompt-caching-is-everything

核心观点:缓存决定一切

对于像 Claude Code 这样长时间运行的 agent 系统,prompt caching(提示词缓存)几乎是性能与成本的命脉。缓存命中意味着可以复用之前的计算结果,直接降低延迟和费用。文章作者用一句话概括团队的态度:缓存命中率就像系统的「正常运行时间」一样被监控——一旦命中率下降,团队会将其当作严重故障(incident)来对待,而不是普通的性能波动。

Prompt 布局策略:顺序至关重要

prompt caching 的本质是前缀匹配(prefix matching)——只有当新请求与历史请求共享相同的前缀时,才能命中缓存。因此内容在 prompt 中的排列顺序直接决定了缓存能否命中。

官方建议按「越稳定越靠前」的原则组织 prompt,大致分为四层:

  1. 静态系统提示词与工具定义——全局范围内几乎不变,理论上可以在所有会话间共享缓存;
  2. CLAUDE.md 等项目文档——同一项目内的会话可以共享;
  3. 会话上下文(session context)——同一会话内共享;
  4. 对话消息本身——最动态,每轮都会变化。

这种由静到动的分层结构,能最大程度地让不同会话、不同项目复用已缓存的前缀。

文章也指出了两个常见的「踩坑」点,会直接破坏缓存:

  • 工具顺序不确定:如果每次请求中工具列表的排列顺序发生变化(以非确定性的方式排列),即使内容完全相同,前缀也会被判定为不一致,导致缓存失效。
  • 在静态提示词中插入时间戳:把当前时间等易变信息直接写进系统提示词,会让这部分「本应稳定」的内容每次都不同,从而破坏整个后续前缀的缓存。

用消息(messages)承载更新,而不是改写系统提示词

当某些信息(比如环境状态、提醒事项)发生变化时,直接的做法是回去修改已经写入 system prompt 的内容——但这样做会使该系统提示词及其后所有内容的缓存失效。

官方的做法是:不修改已缓存的 prompt,而是在对话轮次中通过新增消息来插入更新,例如使用 <system-reminder> 这类标签,把「新信息」作为一条追加的消息发送,而不是回头改写已经存在、且已被缓存的那部分内容。这样旧的前缀依然保持不变,可以继续命中缓存。

会话内保持模型与工具的一致性

两条明确的「不要做」原则:

  • 不要在同一次会话中途切换模型。不同模型对同一段前缀的处理和缓存机制并不通用,切换模型会让已缓存的前缀直接作废。如果确实需要把工作交接给另一个模型,应该通过 subagent 的方式来完成交接,而不是在同一上下文里换模型。
  • 不要在会话中途增删工具。哪怕只是新增或移除一个工具,也会破坏该会话此前积累的全部缓存。

针对「工具集需要动态变化」这一常见需求,文章给出了两种规避方案:

  • 用 Plan Mode 这类专门的工具来表达状态切换,例如通过 EnterPlanMode/ExitPlanMode 这样的工具调用来标记进入或退出某种模式,而不是直接增减工具本身;
  • 延迟加载工具 schema:先在 prompt 中发送轻量级的工具「占位符」(stub),并标记 defer_loading: true,只有当模型真正选中某个工具时,才加载它完整的 schema 定义。这样可以在不破坏缓存的前提下,支持大量可选工具。

缓存安全的上下文压缩(Compaction)

当对话长度超出上下文窗口限制、需要做摘要压缩(compaction)时,也要遵循「不动稳定部分」的原则:压缩前后应使用完全相同的系统提示词、上下文内容和工具定义,只让「压缩指令」(compaction prompt)本身作为新增的 token 追加进去。这样可以保证压缩操作不会连带破坏此前已经建立起来的缓存前缀。

五条要点速览(原文总结)

  1. Prompt caching 靠前缀匹配工作,顺序安排至关重要;
  2. 信息更新应通过消息插入,而不是修改系统提示词;
  3. 会话内部要保持工具集和模型的一致性;
  4. 把缓存命中率当作关键指标来监控,视为系统健康度的一部分;
  5. 分支(fork)类操作也必须与父会话共享相同的前缀,才能继续受益于缓存。

对开发者的启示

如果你在基于 Claude API 构建自己的 agent 系统,这篇文章的经验可以直接落地:提前规划好 prompt 的分层结构(静态在前、动态在后)、工具列表顺序保持确定性、避免把时间戳等易变信息写进系统提示词、动态信息一律通过消息追加、以及在做上下文压缩时保持前缀不变。这些做法能显著提升缓存命中率,从而降低延迟和调用成本。