提示词缓存命中取决于前缀布局
文章解释提示词缓存如何复用相同前缀的处理结果,降低重复输入的成本和延迟。时间戳、用户名或工具列表顺序变化若出现在开头,会使后续内容无法复用缓存。
AI 深度解读
提示词缓存能省下多少成本,往往取决于你怎样拼接提示词。原文的核心主张是:服务商按完全一致的前缀复用计算结果,稳定内容排在前面,用户信息和问题放在后面,才容易命中缓存。
这对带大量工具定义、产品文档和示例的 AI 功能尤其有用。不过,文中的降本数字是条件明确的算例,并非团队实测;模型门槛、计费与缓存有效期,也要分开看。
为什么改一行用户信息,就可能让缓存失效
提示词缓存(Prompt Caching)保存的是模型处理提示词开头部分后的状态。下次请求从相同的 token 序列开始,就能复用这部分计算,减少重复输入的处理成本。
缓存匹配的是从头开始的连续前缀,内容相同但顺序不同,也不能照样复用。
例如,系统指令、工具定义、十二个示例和产品文档都保持不变,只有末尾的问题不同,这适合缓存。可如果第一行先写客户姓名,不同客户的前缀就会从这里分叉,后面的公共文档也无法跨客户复用。时间戳、重新排序的工具列表,同样会造成这种问题。
按原文,Anthropic 的 Messages API 用 cache_control 启用缓存。可以在顶层设置,让 API 把断点放到最后一个可缓存块;也可以手动指定,最多四个断点。它按 tools、system、messages 的固定顺序构建前缀:修改工具定义会影响整个缓存,修改消息则影响消息层。
OpenAI 的方式不同。原文称,GPT-5.6 及之后的模型在前缀达到 1,024 tokens 后自动缓存,prompt_cache_key 可以改善路由,让相似请求更容易到达已有缓存的位置;较新的模型也支持显式断点。这些是原文给出的产品信息,文内没有展开具体支持范围,接入时应按目标模型核对。
在 TypeScript 里,把稳定内容放到断点前
下面这段支持助手代码解决的是公共文档跨请求复用的问题:工具和系统内容稳定,客户信息随请求变化。
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
export async function answer(
question: string,
user: { name: string; plan: string },
) {
const response = await client.messages.create({
model: "claude-sonnet-5-5",
max_tokens: 1024,
tools: SUPPORT_TOOLS, // stable, same order every request
system: [
{
type: "text",
text: SUPPORT_INSTRUCTIONS + PRODUCT_DOCS, // thousands of static tokens
cache_control: { type: "ephemeral" },
},
],
messages: [
{
role: "user",
// per-request context lives AFTER the breakpoint
content: `Customer: ${user.name} (${user.plan} plan)\n\n${question}`,
},
],
});
const { cache_creation_input_tokens, cache_read_input_tokens, input_tokens } =
response.usage;
console.log({
cache_creation_input_tokens,
cache_read_input_tokens,
input_tokens,
});
return response;
}
要看的是 cache_control 所在位置,以及 Customer 出现在后面的 messages 中。SUPPORT_TOOLS 也必须保持顺序稳定。示例保留了原文的 claude-sonnet-5-5 和 max_tokens: 1024;后者限制输出长度,不能用来判断输入是否达到缓存门槛。
原文给了一笔账:静态内容为 6,000 tokens,在有效期内收到 10 次请求。不缓存时,这部分按 60,000 输入 tokens 计费;缓存首次写入按 1.25 倍计算,是 7,500,随后九次读取按 0.1 倍计算,共 5,400。合计 12,900,约为原成本的 21%。
这里算的只是静态部分,不含每次变化的输入和模型输出。原文还认为首 token 延迟会下降,但没有提供延迟测试数据。
请求成功,不代表缓存正在省钱
缓存未命中通常不会让请求报错,功能照常运行,账单却按正常输入计算。因此,作者最有用的建议是先记录一天用量。
Anthropic 要看 cache_creation_input_tokens 和 cache_read_input_tokens,两者都为 0,表示没有内容被缓存。OpenAI 则查看 cached_tokens:Responses API 位于 usage.input_tokens_details,Chat Completions 位于 usage.prompt_tokens_details。
还要排查几类容易漏掉的问题:
- 提示词太短。原文给出的 Anthropic 最低门槛从较新模型的 512 tokens 到部分旧模型的 4,096 tokens;不足时,
cache_control会被忽略且不报错。 - 序列化不稳定。工具 schema 的键顺序变化,或文档按「最近更新」重新排列,都会改变前缀。
- 请求配置变化。Anthropic 的
tool_choice、图片或 thinking 设置变化,可能使部分缓存失效。 - 请求间隔太长。每小时一次的功能,很难利用 5 分钟缓存有效期。
原文列出的 Anthropic 写入价格是:默认 5 分钟 TTL 为正常输入的 1.25 倍,1 小时为 2 倍;多数模型读取为基础输入价格的 0.1 倍,部分较新模型更低。这些费率不能直接套给所有平台和模型。
我的判断
我认同把提示词顺序当成工程约束。它不仅影响可读性,还会影响重复计算量。对长工具列表、稳定语料的 RAG 和重复指令的批处理,这个思路有明确用途。
但「读取接近零,几乎总是顺序问题」说得过满。原文自己也列出了长度不足、TTL 过期和配置变化。排查时应先区分没有创建缓存,还是创建后没有被复用。
文中没有给出真实流量、对照实验或延迟分布,因此 21% 应视为理想条件下的算例。相比直接缩短提示词,缓存保留了公共上下文,但依赖重复请求;如果提示词短、请求稀疏,写入溢价反而可能增加成本。
能拿来做什么
- 在 Node 服务的模型调用封装里记录缓存创建量、读取量和输入量,先观察一天,再决定是否调整提示词。
- 把公共指令、工具定义和稳定文档放在前面,将客户信息、日期和当前问题放在后面,并固定工具与文档的排列顺序。
- 为聊天、Agent 和批处理分别检查请求间隔及静态输入长度,再选择 TTL;用实际账单验证收益,别把静态部分的节省比例当成整次调用的降幅。