Claude Code 技术中的 Prompt Caching 学习笔记

文章目录

    • 前言
    • 一、理解基础:大模型如何处理输入和生成输出
      • [1.1 大模型处理的是 token,不是直接处理文字**](#1.1 大模型处理的是 token,不是直接处理文字**)
        • [1.1.1 那么什么是 token?](#1.1.1 那么什么是 token?)
        • [1.1.2 大模型输入输出的流程](#1.1.2 大模型输入输出的流程)
      • [1.2 模型不是一次性生成完整答案**](#1.2 模型不是一次性生成完整答案**)
        • [1.2.1 自回归预测](#1.2.1 自回归预测)
        • [1.2.2 采样技术](#1.2.2 采样技术)
      • [1.3 一次请求通常有两个阶段**](#1.3 一次请求通常有两个阶段**)
    • [二、理解 KV Cache:Transformer 内部的缓存机制](#二、理解 KV Cache:Transformer 内部的缓存机制)
      • [2.1 Transformer 中的 Q、K、V 是什么](#2.1 Transformer 中的 Q、K、V 是什么)
      • [2.2 为什么需要缓存 Key 和 Value](#2.2 为什么需要缓存 Key 和 Value)
    • [三、理解 Prompt Caching](#三、理解 Prompt Caching)
      • [3.1 Prompt Caching 是什么](#3.1 Prompt Caching 是什么)
      • [3.2 Prompt Caching 和 KV Cache 的关系](#3.2 Prompt Caching 和 KV Cache 的关系)
      • [3.3 Prompt Caching机制](#3.3 Prompt Caching机制)
      • [3.4 Prompt Caching 是谁在做](#3.4 Prompt Caching 是谁在做)
      • [3.5 Agent 负责"让 prompt 更容易被缓存"](#3.5 Agent 负责“让 prompt 更容易被缓存”)
    • [四、Claude Code 的 Prompt Caching 技术脉络](#四、Claude Code 的 Prompt Caching 技术脉络)
      • [4.1 Claude Code 为什么特别依赖 Prompt Caching](#4.1 Claude Code 为什么特别依赖 Prompt Caching)
      • [4.2 五个技术脉络](#4.2 五个技术脉络)
    • [五、Prompt Caching 的应用场景](#五、Prompt Caching 的应用场景)
    • 六、参考资料
    • 总结

前言

Claude Code 这类编程 Agent 为什么能在长上下文、多轮对话、频繁工具调用中保持相对可用的速度和成本?一个关键答案是:Prompt Caching

它并不是简单地缓存模型回答,而是缓存模型处理稳定 prompt 前缀时产生的中间状态,让后续请求不必反复计算相同的系统提示、工具定义、项目文档和历史上下文。

本文会从大模型的 token 生成机制讲起,逐步解释 KV Cache、Prompt Caching 以及它们之间的关系,再梳理 Claude Code 如何通过 prompt 编排、工具设计、模型选择和上下文压缩来提高缓存命中率。

最后也会讨论一个现实问题:如果把 Claude Code 底层模型换成其他模型或 API,缓存机制是否还会生效。


一、理解基础:大模型如何处理输入和生成输出

1.1 大模型处理的是 token,不是直接处理文字**

我们平时看到的是自然语言文本,比如:

请帮我解释这段代码

但模型真正接收的不是这句话本身,而是 tokenizer 切分后的 token 序列。

1.1.1 那么什么是 token?

可以先粗略理解为:

Token 是大模型处理文本时使用的最小输入单位。它可能是一个汉字、一个英文单词、一个词的一部分、一个标点符号,甚至是一段常见字符组合。

1.1.2 大模型输入输出的流程

大语言模型在回答我们的问题时,流程大概是:

  1. 输入文本:接收自然语言(e.g., "请帮我解释...")。
  2. Tokenizer 切分:Tokenizer 将文本切分为最小语义单元(Tokens)。
  3. Token IDs 转换:每个 Token 被映射为词表中的唯一数字索引(Token IDs)。
  4. 输入 Transformer 模型:这串数字序列作为模型的真实输入。
  5. 模型预测:Transformer 根据当前序列,预测下一个最可能出现的 Token ID。
  6. 逐 Token 生成:预测出的 Token 被加入序列,不断重复,最终生成完整的回答。

简而言之,大模型的输入和输出,在本质上都是 Token 序列。

1.2 模型不是一次性生成完整答案**

1.2.1 自回归预测

大语言模型(LLM)生成回答并非瞬间完成,而是采用一种称为**自回归(Autoregressive)**的方式,一个 token 一个 token 地逐步构建。其核心循环过程如下:

  • 输入上下文:模型首先接收当前的上下文(包括 prompt 和已生成的所有 token)。
  • 预测概率分布 :模型分析上下文,输出对下一个可能 token 的完整概率分布(Probability Distribution)
  • 采样选择:模型根据设定的参数,从该概率分布中采样(Sample)选出一个 token。
  • 更新上下文:将选出的新 token 追加到旧上下文的末尾,形成新的上下文。
  • 重复循环:新的上下文作为输入,再次执行上述步骤。
  • 生成结束 :这个循环会一直持续,直到模型预测出特定的结束标记(End-of-Sequence token, <EOS>

因此,我们可以给出一个更准确的技术定义:大语言模型本质上是一个基于已有 token 序列,迭代地预测下一个 token 概率分布的统计模型。

1.2.2 采样技术

虽然模型输出了一个完整的概率分布,但实际生成时并不一定永远选择概率最高的那个 token

为了引入多样性、创造性或避免陷入死循环,模型使用了采样(Sampling)技术

同一个 Prompt 有时会生成不同的回答,关键在于以下两个核心参数对采样过程的控制:

  • Temperature(温度系数)

    • 低 Temperature(例如 0.2) :使概率分布更加陡峭(对高概率 token 更有利),导致输出更加确定(Deterministic)、保守和重复。
    • 高 Temperature(例如 1.0) :使概率分布更加平坦,给予低概率 token 更多机会,导致输出更加随机(Random)、多样和创造。
  • Top-P(Nucleus Sampling,核心采样)

    • 模型不从所有可能的 token 中采样,而是仅从累积概率之和超过设定阈值 P(例如 0.9)的"核心" token 集合中进行采样。
    • 这可以过滤掉极端低概率的长尾 token,同时保留高概率 token 之间的合理随机性。

1.3 一次请求通常有两个阶段**

大模型推理通常可以分成两个阶段:

  1. Prefill 阶段:处理输入 prompt,读完整个上下文。
  2. Decode 阶段:一个 token 一个 token 生成输出。

长上下文 Agent 变慢,很多时候慢在 Prefill 阶段:模型每一轮都要重新"读"一遍很长的上下文。


二、理解 KV Cache:Transformer 内部的缓存机制

2.1 Transformer 中的 Q、K、V 是什么

要理解 Prompt Caching,需要先理解 KV Cache。

Transformer 的注意力机制中,每个 token 会产生三类向量:

  1. Q = Query:查询,我现在想找什么信息?
  2. K = Key:索引,我这里有什么信息,别人怎么找到我?
  3. V = Value:内容,如果别人关注我,实际拿走什么信息?

注意,这里的 Key 和 Value 不是数据库里的键值对,而是神经网络里的向量表示。

可以用一个简单比喻理解:

Query 像问题,Key 像标签,Value 像内容。

当前 token 会用自己的 Query 去匹配前面 token 的 Key。

匹配度越高,说明当前 token 越应该关注那个历史 token,然后取用对应的 Value。

2.2 为什么需要缓存 Key 和 Value

假设模型正在处理:

text 复制代码
北京 是 中国 的 首都

当模型要预测后续 token 时,它需要回看前面的 token:

text 复制代码
当前 Query vs "北京"的 Key
当前 Query vs "中国"的 Key
当前 Query vs "首都"的 Key

这些历史 token 的 Key 和 Value 已经算过了。如果每生成一个新 token,都重新计算所有历史 token 的 Key/Value,会非常浪费。

所以推理系统会把已经算过的 Key/Value 存起来,这就是 KV Cache。

没有 KV Cache 时,生成过程会变得非常重复:

有 KV Cache 后,流程变成:

所以 KV Cache 解决的是:

在单次请求内部,生成后续 token 时,不要反复重算前面 token 的 Key/Value。

它是 Transformer 推理中的底层优化机制。


三、理解 Prompt Caching

3.1 Prompt Caching 是什么

Prompt Caching 比 KV Cache 更上一层。

KV Cache 通常发生在一次请求内部;Prompt Caching 是把"相同 prompt 前缀"的计算结果跨请求复用。

一句话定义:

Prompt Caching 是把已经处理过的一大段相同 prompt 前缀对应的模型内部状态缓存起来,下次遇到同样前缀时直接复用,而不是重新从第一个 token 算一遍。

这里非常重要:Prompt Caching 缓存的不是最终答案。

普通答案缓存是:

text 复制代码
用户问 A
模型答 B
下次用户又问 A
直接返回 B

这叫 response cache 或 answer cache。

Prompt Caching 不是这样。Prompt Caching 缓存的是模型处理输入 prompt 时产生的中间计算状态。

举一个具体例子

text 复制代码
[系统提示 + 工具定义 + 项目文档 + 历史上下文]

第一次请求时,服务端完整处理这段内容,并保存它对应的内部计算结果。

第二次请求时,服务端发现前缀一样,就可以直接复用之前保存的内部状态,只处理后面新增的"新问题 2"。

所以模型仍然会正常生成新答案,只是不用重复计算前面那一大段稳定上下文。

3.2 Prompt Caching 和 KV Cache 的关系

可以这样理解:

  1. KV Cache = 单次模型推理时,真正被保存和复用的模型中间状态
  2. Prompt Caching =多次api请求时, 判断之前请求中哪些 prompt 前缀可以跨请求复用的工程机制

它们的关系可以总结成表格:

概念 作用范围 缓存内容 解决问题
KV Cache 单次请求内部 历史 token 的 Key/Value 张量 生成新 token 时不用重算历史
Prompt Caching 多次请求之间 相同 prompt 前缀对应的内部状态,通常包含 KV 表示 多轮请求不用重复处理相同长上下文
Response Cache 应用层 最终回答文本 相同问题直接返回旧答案

3.3 Prompt Caching机制

一个简化版 Prompt Caching 实现流程如下:

  1. 接收 prompt
  2. tokenizer 把 prompt 转成 token IDs
  3. 从开头开始把 token 切成若干 block
  4. 对 block 计算 hash
  5. 查询缓存表,看这些 block 是否出现过
  6. 找到最长可复用前缀
  7. 命中部分:加载已有 KV Cache
  8. 未命中部分:正常执行 Transformer prefill
  9. 进入 decode 阶段,逐 token 生成答案
  10. 把新计算出的 KV Cache 写回缓存

这里最关键的是"最长可复用前缀"。

因为 Transformer 是因果模型,后面的 token 依赖前面的 token。如果前面某个位置变了,后面即使文字相同,内部状态也可能不同。

Prompt Caching 整体架构图如下:

3.4 Prompt Caching 是谁在做

一个常见误解是:模型自己记住了上次的 prompt。

实际上不是。

模型本身,比如 Qwen、Llama、DeepSeek、Claude、GPT,主要负责根据 token 计算下一个 token 的概率分布。

Prompt Caching 通常是模型外层的推理服务系统做的。

可以理解为:

prompt Caching 不是模型权重本身做的,也不是用户应用直接做的,而是 API 服务商或推理框架 在做。

例如:

  • 使用 Claude API:Anthropic 服务端负责缓存机制。
  • 使用 OpenAI API:OpenAI 服务端负责缓存机制。
  • 使用 DeepSeek API:DeepSeek 服务端负责 Context Caching。
  • 自己部署模型:vLLM / SGLang / TensorRT-LLM / LMCache 等推理框架负责类似机制。

Anthropic 文档明确说 Prompt Caching 会缓存 KV cache representations 和 cryptographic hashes,不是原始 prompt 或回答文本:https://platform.claude.com/docs/en/build-with-claude/prompt-caching

DeepSeek 官方文档也说,它的 Context Caching 是 API 侧默认启用的硬盘缓存技术,后续请求如果和之前请求有重叠前缀,就可以从缓存取出对应部分:https://api-docs.deepseek.com/guides/kv_cache

3.5 Agent 负责"让 prompt 更容易被缓存"

当我们使用Claude Code 这样的 Agent时,Claude Code作为客户端,自己不负责真正保存 KV Cache。它主要负责:

  1. 组织 prompt
  2. 保持系统提示稳定
  3. 保持工具定义稳定
  4. 把动态内容放到后面
  5. 必要时使用 cache_control / breakpoint
  6. 记录 usage 中的缓存命中情况

也就是说,Claude Code 做的是 cache-friendly prompt design

例如 Claude Code 会尽量做到:

  1. 静态 system prompt 放前面
  2. 工具定义放前面且保持稳定
  3. CLAUDE.md 放在稳定区域
  4. 动态状态放到后面的 message 或 tool result
  5. 不要中途乱改工具列表
  6. 不要中途乱切模型
  7. compaction 也沿用父会话前缀

这些是 Agent Harness 层的设计。

所以说:

Claude Code作用客户端: 负责组织 cache-friendly prompt。

Anthropic API作为api模型商:负责真正执行 Prompt Caching。

Claude系列大模型:负责推理。、

Prompt Caching 的底层计算和存储是由大模型 API 厂商(如 Anthropic、DeepSeek)处理的;但能不能高效"命中"缓存,完全取决于 Agent(如 Claude Code)的 Prompt 编排架构,这也是agent harness设计的一个重要思考。

因此,看到这一小节就可以回答这个问题了:

"既然 Claude Code 的架构是深度适配 Anthropic 的 Prompt Caching 机制的,那如果我通过修改配置或使用代理,把底层模型换成 DeepSeek(比如 DeepSeek-V4),这种缓存机制会不会失效?性能会不会暴跌?"

咳咳:我没有实验验证所以无法给出确定结论,但是个人想法是也许有些差别,但是不至于暴跌。毕竟:

deepseek不会继承 Anthropic 的缓存;

不会天然共享 Claude 的 KV Cache;

Anthropic cache_control 在 DeepSeek 兼容层会被忽略;
但 DeepSeek 有自己的 Context Caching;
所以不是"必然失效",而是"需要按 DeepSeek 的缓存规则重新命中"。


四、Claude Code 的 Prompt Caching 技术脉络

4.1 Claude Code 为什么特别依赖 Prompt Caching

Claude Code 是一个长时间运行的编程 Agent。它每一轮请求都可能携带大量上下文:

text 复制代码
系统提示
工具定义
项目 CLAUDE.md
当前任务状态
历史对话
读取过的文件内容
工具调用结果
最新用户输入

如果每一轮都重新处理这些内容,成本和延迟都会很高。

所以 Claude Code 的重要经验不是简单"启用了 Prompt Caching",而是:

整个 Agent Harness 的 prompt 组织、工具设计、模式切换和上下文压缩,都围绕 Prompt Caching 设计。

4.2 五个技术脉络

  1. 前缀匹配是第一性原理
  • Prompt caching 是 prefix matching。只要前缀中任何位置发生变化,后面的缓存都可能失效;

  • 因此 Claude Code 把 prompt 组织成从稳定到动态的顺序:静态系统提示与工具定义、项目级 CLAUDE.md、会话上下文、最后才是对话消息

  • 这个顺序的目标是让更多请求共享同一个开头。

  1. 动态信息尽量放到消息,而不是改系统提示

    • system prompt 被改,稳定前缀就变了;
    • Claude Code 的做法是把这类更新包进下一条 user message 或 tool result,例如 <system-reminder>,让主前缀保持稳定。
  2. 不要在会话中途切换模型

    • 缓存与模型绑定,即使 prompt 字节完全相同,Opus 和 Haiku 的内部 KV 表示也不同;
    • 原文博客指出,在一个已经有 100k token 的 Opus 会话中,为了"便宜地问一个简单问题"切到 Haiku,反而可能更贵;
    • 因为 Haiku 需要从零构建自己的缓存,更合理的模式是让父 agent 准备简短 hand-off,再启动子 agent。
  3. 不要在会话中途增删工具

    • 工具定义属于缓存前缀。增删工具看似节约 prompt,实际会破坏整段前缀;
    • Claude Code 的 Plan Mode 没有切换成"只读工具集",而是把 EnterPlanMode / ExitPlanMode 设计成工具本身;
    • 工具集合保持稳定,状态变化通过消息和工具调用表达。
  4. Compaction 也要 cache-safe

    • 当上下文快满时,系统需要压缩历史
    • 如果单独发一个"请总结这段对话"的新请求,并换掉系统提示和工具定义,缓存从第一个 token 就失效
    • Claude Code 的做法是"fork 父会话":保留父会话完全相同的系统提示、工具、上下文和历史前缀,只在末尾追加 compaction prompt;
    • 这样 compaction 也能复用父会话的缓存;
    • Anthropic 的 compaction 文档也强调,服务端 compaction 会在接近阈值时总结旧上下文,并可与 prompt caching 配合使用:https://platform.claude.com/docs/en/build-with-claude/compaction

五、Prompt Caching 的应用场景

Prompt Caching 最直接解决的是长上下文、多轮 agent 的经济性问题。它尤其适合:

  • AI 编程助手:代码仓库说明、工具定义、项目约束、历史编辑轨迹会反复出现在每一轮请求中。缓存命中后,模型不用每次重新处理这些稳定上下文。
  • 企业知识库问答 / RAG:公司政策、产品手册、合同模板、医学指南等大段上下文可能被许多请求复用。缓存能降低 prefill 延迟。
  • 多 agent 调度系统:主 agent、探索 agent、审阅 agent、执行 agent 往往共享相同规则和任务背景。通过 cache-safe hand-off,可以避免每个子 agent 重建巨型上下文。
  • 长时任务与会话记忆:研究写作、代码迁移、数据分析、客服工单连续处理都需要长历史。Prompt caching 与 compaction 结合,可以在保留连续性的同时压低成本。
  • 边缘设备和 IoT 命令系统:大量自然语言命令只有参数不同,例如"把卧室灯打开""把客厅灯打开"。语义级或代码片段级缓存可以绕开重复 LLM 调用。
  • 推理平台调度:服务端可以基于 prefix-aware routing,把请求路由到已经持有对应 KV cache 的 GPU 或推理引擎,减少重复 prefill。

六、参考资料

  1. Anthropic Claude Code 博客:https://claude.com/blog/lessons-from-building-claude-code-prompt-caching-is-everything
  2. Anthropic Prompt Caching 文档:https://platform.claude.com/docs/en/build-with-claude/prompt-caching
  3. Anthropic Compaction 文档:https://platform.claude.com/docs/en/build-with-claude/compaction
  4. OpenAI Prompt Caching 文档:https://platform.openai.com/docs/guides/prompt-caching
  5. OpenAI Prompt Caching 介绍:https://openai.com/index/api-prompt-caching/

总结

Prompt Caching 的核心并不复杂:复用相同 prompt 前缀的计算结果,减少长上下文重复 prefill 的成本和延迟。

要理解它,需要先分清几层关系:

  1. LLM 的输入输出本质上是 token 序列,模型通过自回归方式逐 token 生成答案。
  2. 一次推理分为 prefill 和 decode 两个阶段,长上下文 Agent 的主要压力往往来自反复处理庞大的输入前缀。
  3. KV Cache 是单次请求内部的底层缓存,避免生成每个新 token 时重复计算历史 token 的 Key/Value。
  4. Prompt Caching 是跨请求的工程机制,通过最长相同前缀匹配,把已经计算过的内部状态复用到后续请求中。
  5. Claude Code 的关键不是"用了缓存",而是整个 Agent Harness 都在围绕缓存命中率设计:稳定系统提示、稳定工具定义、动态内容后置、避免中途切模型或工具集、让 compaction 也尽量复用父会话前缀。

因此,Prompt Caching 不是模型"记住了上次对话",也不是应用层直接返回旧答案,而是 API 服务商或推理框架在模型外层做的推理优化。

对于 Claude Code 来说,Anthropic 负责真正的缓存计算与存储,Claude Code 负责组织更容易命中的 prompt。换成其他底层模型或兼容 API 后,Anthropic 的缓存不会被继承,cache_control 也可能失效;但如果目标服务本身支持类似 Context Caching,仍然有机会通过相同的前缀组织方式获得收益。

最终结论是:

Prompt Caching 是长上下文 Agent 可扩展性的关键基础设施之一。它真正优化的不是"回答",而是反复出现的上下文前缀;而 Agent 的工程能力,很大一部分体现在如何让这些前缀稳定、可复用、容易命中缓存。

相关推荐
组合缺一2 小时前
agentscope-harness vs solon-ai-harness:Java 智能体「马具引擎」的双雄对决
java·人工智能·ai·llm·agent·solon·agentscope
counterxing5 小时前
我整理了一个免费开发资源目录,还做成了 CLI 和 MCP
前端·agent·ai编程
SharpCJ9 小时前
当 AI 开始写代码,谁来保证它不会翻车?
aigc·agent·harness
爱吃芒果的蘑菇13 小时前
给 Codex 加一只像素宠物:阿梓 Azi
agent·宠物·codex
askxiaozhang15 小时前
MCP 协议从入门到实战:让大模型拥有调用本地工具的能力
agent·mcp
阿里云大数据AI技术15 小时前
PAI部署Hermes Agent全攻略,打造越用越懂你的AI助手
人工智能·agent
DigitalOcean15 小时前
如何在无服务器推理上运行 Hermes Agent?
agent
老码观察17 小时前
数环通iPaaS知识库选型实践:从技术评估到RAGFlow深度调优
人工智能·agent·知识库
DigitalOcean17 小时前
AI 推理产品省钱指南:如何通过基建优化降低 80% 推理成本?
aigc·agent·vibecoding