Claude 官方 API 缓存机制深度指南:打开一个开关,直接为你的 Agent 省掉 70%+ 的 API 开销
Claude 官方 API 缓存机制深度指南:打开一个开关,直接为你的 Agent 省掉 70%+ 的 API 开销
这可能是 2025 年以来,Anthropic 推出的最有价值,但是也最被低估的一个功能。
Prompt Caching(提示词缓存)。
绝大多数 Agent 开发者到现在都还没用上这个功能。 还有很多人听说过,但是不知道怎么正确开启,不知道它到底能省多少钱,不知道有什么坑。
但是只要你正确地把它用上,你的 Claude API 账单,可能会直接砍掉 50%、70%,甚至 90%。
毫不夸张地说,这是目前你能为你的 Agent 做的,投入产出比最高的成本优化。 没有之一。
今天这篇文章,我就把这个功能从里到外讲透。 从工作原理,到如何启用,到命中率怎么算,到能省多少钱,到最佳实践,到所有的坑。
看完这篇,你今天就能把它用上,明天就能看到你的账单降下来。
先搞清楚:它到底是怎么工作的
在讲怎么用之前,我们先把底层原理搞明白。
传统 API 的计费方式
在没有缓存之前,每次 API 调用,所有的输入 token 都是全价计费。
你第一次调用,发了 100k token 的系统提示词,收你 100k 的钱。 一分钟之后第二次调用,系统提示词完全没变,只是多了两句对话,还是收你 100k+ 的钱。 第三次,第四次,第一百次,每次都全价收。
这对于 Agent 场景来说,简直就是抢钱。 因为 Agent 的系统提示词、工具定义、技能说明,90% 的内容在整个会话过程中都是完全不变的。 每次调用都把同样的东西发一遍,每次都收同样的钱。
有了缓存之后的计费方式
有了 Prompt Caching 之后,一切都不一样了。
Anthropic 会在它们那边,自动缓存你发过去的内容。 如果两次调用之间,有内容是完全一样的,那么这部分内容就不会重复计费。 缓存命中的部分,计费直接打 九折。 是的,你没看错:原来的价格乘以 0.1。
| 项目 | 原价 | 缓存命中价 | 折扣 |
|---|---|---|---|
| Claude 3.7 Sonnet 输入 | $3.00 / 百万 token | $0.30 / 百万 token | 90% OFF |
| Claude 3.7 Sonnet 输出 | $15.00 / 百万 token | $15.00 / 百万 token | 不打折 |
这意味着什么? 如果你的输入里,有 90% 的内容是重复的、可以被缓存的。 那么你的输入成本,直接从原来的 100%,变成了: 10% × 100% 原价 + 90% × 10% 缓存价 = 19% 的原价。
相当于直接打了个一九折。 这不是省一点钱,这是直接把成本砍到了原来的五分之一。
如何启用?真的只需要加一个参数
好消息是:启用这个功能,简单到离谱。 你不需要做任何架构上的改动,不需要改你的提示词,不需要任何复杂的设置。
你只需要在 API 调用的参数里,加一行:
{
"extra_headers": {
"anthropic-beta": "prompt-caching-2024-07-31"
}
}仅此而已。
加完这个头之后,缓存机制就自动生效了。 Anthropic 会自动处理后面所有的事情:自动识别重复内容,自动缓存,自动计费打折。 你什么都不用管。
如果你用的是官方的 Python SDK,那就更简单了:
from anthropic import Anthropic
client = Anthropic(
api_key="your-api-key",
# 加这一行就行
default_headers={"anthropic-beta": "prompt-caching-2024-07-31"}
)然后所有的调用自动就用上缓存了。
就是这么简单。 简单到离谱,简单到很多人甚至不敢相信这真的能省那么多钱。
缓存的匹配规则:什么会被命中,什么不会
当然,它也不是魔法,不是所有东西都能被缓存。 它有一套非常明确的匹配规则。
缓存是怎么匹配的?
缓存的匹配单位是 消息块。 不是整段文本的模糊匹配,是精确的、结构化的匹配。
举个例子,你的消息结构是这样的:
{
"messages": [
{"role": "system", "content": "非常长的系统提示词,100k token"},
{"role": "user", "content": "用户的第一个问题"}
]
}第一次调用,这两个消息块都会被缓存。
第二次调用,你加了一轮对话:
{
"messages": [
{"role": "system", "content": "完全一样的系统提示词,100k token"},
{"role": "user", "content": "用户的第一个问题"},
{"role": "assistant", "content": "我的回答"},
{"role": "user", "content": "用户的第二个问题"}
]
}这个时候,前面三个消息块都是完全一样的,所以这三个都会命中缓存。 只有最后新加的那个用户问题,是新的内容,全价计费。
就是这么简单。
什么会导致缓存失效?
有几种情况会导致缓存不命中:
- 内容变了一个字符都不行:必须是完全精确的匹配,多一个空格,少一个换行,都会失效。
- 顺序变了也不行:哪怕内容完全一样,但是顺序调换了,也不会命中。
- 超过了缓存时间:默认的缓存时间是 5 分钟。从最后一次使用这个缓存块开始算,5 分钟之内没有再用,就会被清掉。
- 深度限制:最多只能缓存前 1024 个消息块。绝大多数场景下你永远也碰不到这个限制。
一个非常重要的注意点
缓存是按照 前缀连续匹配 的。 也就是说,它会从第一个消息块开始,一个一个往下匹配,直到遇到第一个不一样的为止。 前面所有一样的都会命中,后面的都不会。
举个反例: 如果你在中间插入了一个新的消息块,那么哪怕后面所有的内容都完全一样,也全部都不会命中。 因为匹配在中间就断了。
这是绝大多数人用了缓存但是省不下钱的最主要原因。
到底能省多少钱?我们来算笔账
光说折扣太抽象了,我们来算笔真实的账。 我给你们算几个典型的 Agent 场景,你们就知道有多夸张了。
场景 1:简单的工具调用 Agent
- 系统提示词 + 工具定义:20k token
- 每轮对话新增:~200 token
- 平均每个会话:10 轮对话
没有缓存的总成本: (20k + 200 × 平均 5 轮) × 10 次 = 300k token = $0.9
有缓存的总成本: 第一次:20.2k × 原价 = $0.0606 后面 9 次:20k × 0.1 缓存价 + 200 × 原价 = $0.006 + $0.0006 = $0.0066 / 次 总计:$0.0606 + 9 × $0.0066 = $0.12
节省幅度:(0.9 - 0.12) / 0.9 = 87%
场景 2:复杂的技能型 Agent(比如 Claude Code)
- 系统提示词 + 技能 + 工具定义:80k token
- 每轮对话新增:~500 token
- 平均每个会话:20 轮对话
没有缓存的总成本: (80k + 500 × 平均 10 轮) × 20 次 = 2600k token = $7.8
有缓存的总成本: 第一次:80.5k × 原价 = $0.2415 后面 19 次:80k × 0.1 缓存价 + 500 × 原价 = $0.024 + $0.0015 = $0.0255 / 次 总计:$0.2415 + 19 × $0.0255 = $0.726
节省幅度:(7.8 - 0.726) / 7.8 = 90.7%
是的,你没看错。 一个典型的 Claude Code 会话,用上缓存之后,API 成本是原来的十分之一不到。
场景 3:企业内部 Agent,带大量知识库上下文
- 系统提示词 + 知识库 RAG 上下文:200k token
- 每轮对话新增:~300 token
- 平均每个会话:5 轮对话
没有缓存的总成本: (200k + 300 × 平均 2.5 轮) × 5 次 = 1037.5k token = $3.11
有缓存的总成本: 第一次:200.3k × 原价 = $0.6009 后面 4 次:200k × 0.1 缓存价 + 300 × 原价 = $0.06 + $0.0009 = $0.0609 / 次 总计:$0.6009 + 4 × $0.0609 = $0.8445
节省幅度:(3.11 - 0.8445) / 3.11 = 73%
我就问你: 还有什么优化,能让你加一行代码,就把成本砍掉 70%-90%? 没有。 这是整个行业里,投入产出比最高的优化,没有之一。
如何知道缓存有没有命中?看返回的这些字段
很多人加了缓存头之后,心里一直在打鼓: 到底生效了没有?到底命中了没有?到底省了多少钱?
别慌,Anthropic 在返回结果里,把所有信息都给你了。
每次 API 调用返回的时候,在 usage 字段里,会多出来这几个字段:
{
"usage": {
"input_tokens": 102050,
"cache_creation_input_tokens": 102000,
"cache_read_input_tokens": 0,
"output_tokens": 500
}
}这几个字段是什么意思?
input_tokens:总的输入 token 数,和以前一样cache_creation_input_tokens:这次调用里,没有命中缓存,被创建成新缓存的 token 数。这部分是全价计费的。cache_read_input_tokens:这次调用里,命中了缓存的 token 数。这部分是一折计费的。
第一次调用的时候,因为还没有缓存,所以你会看到:
cache_creation_input_tokens 很大,cache_read_input_tokens 是 0。
第二次调用,内容大部分重复的时候,你就会看到:
cache_read_input_tokens 很大,cache_creation_input_tokens 很小。
这个时候你就知道:缓存生效了,钱已经省下来了。
实际计费的计算公式
你每次调用实际要付的输入费用是:
输入费用 = (cache_creation_input_tokens × 原价) + (cache_read_input_tokens × 0.1 × 原价)自己算一下,你就知道这次调用省了多少钱。
最佳实践:把缓存的效果发挥到极致
知道了基本原理之后,有几个非常简单的最佳实践,可以帮你把命中率拉到最高,把成本降到最低。
1. 把不变的内容尽量放在最前面
这个是最重要的一条。
因为缓存是前缀匹配的,前面的内容越稳定,命中率就越高。 所以:
- 系统提示词永远放在最前面
- 工具定义、技能说明,永远放在系统提示词后面
- 尽量不要在前面插入任何会变化的内容
- 所有动态的、每轮都会变的内容,尽量放在最后面
就这么简单的一个调整,可能就能让你的命中率从 30% 变成 90%。
2. 不要动那些不变的内容
一旦你的系统提示词和工具定义稳定了之后,就不要随便改了。 哪怕是改一个标点符号,改一个换行,都会导致整个缓存失效。 如果要改,尽量攒多了一起改,而不是一点一点改。
3. 对于长会话,可以考虑定期截断
非常长的会话,比如超过 50 轮的会话,其实大部分前面的内容都已经不重要了。 你可以定期把前面的旧的对话历史做个摘要,替换掉原来的详细历史。 这样既可以降低总的 token 数,又不会太影响缓存命中率。
4. 不要为了缓存牺牲效果
最后也是最重要的一条: 缓存是为了省钱,但是不要为了省钱,牺牲 Agent 的效果。 如果某个改动确实能大幅提升 Agent 的效果,哪怕会导致缓存失效也是值得的。 永远是效果第一,成本第二。
常见的坑和误区
最后说几个常见的坑,很多人踩过,你不要再踩了。
坑 1:以为加了头就一定能省很多钱
很多人加了头之后,跑了两天,发现账单没怎么降,就说缓存没用。 99% 的情况是:你的消息顺序不对,前面有经常变化的内容,导致匹配在最开始就断了。 把不变的内容移到最前面,立刻就好了。
坑 2:以为缓存时间很长
默认的缓存时间只有 5 分钟。 不是 1 小时,不是 1 天,是 5 分钟。 超过 5 分钟没有被访问的缓存块,就会被清掉,下次就要重新缓存。 所以这个机制对于活跃的会话效果非常好,但是对于间隔很长的调用效果一般。
坑 3:输出 token 也能打折
别想了。 缓存只对输入 token 有效,输出 token 永远是全价。 能打折的只有输入的部分。
坑 4:所有模型都支持
目前不是所有模型都支持缓存。 支持的模型:
- Claude 3.7 Sonnet ✅
- Claude 3.5 Sonnet v2 ✅
- Claude 3 Opus ✅
不支持的模型:
- Claude 3 Haiku ❌
- 旧版本的 Claude 3.5 Sonnet ❌
用之前先确认你的模型在列表里。
写在最后
Prompt Caching 这个功能,我认为是 Anthropic 做过的最厚道的一件事。
绝大多数公司做这种优化,都是自己偷偷用了,然后价格不变,利润率提高。 但是 Anthropic 把这个能力直接开放给了所有开发者,而且把 90% 的好处都让给了用户。 要知道,这可是直接砍了他们自己一大块的收入。
这种格局,在现在的 LLM 厂商里,真的不多见。
而且更棒的是,这个功能不是什么实验性的 Beta 功能。 它已经非常稳定,非常成熟,已经在生产环境跑了大半年了。 无数公司已经靠它省了几十万、上百万美元的 API 费用。
如果你今天之前还没有用上这个功能。 那么看完这篇文章之后,现在,立刻,马上去加上那一行参数。 明天去看你的账单,你会回来感谢我的。
相信我,这会是你今年做过的,最值的五分钟。
作者: itech001 来源: 公众号:AI人工智能时代 网站: https://www.theaiera.cn/ 每日分享最前沿的AI新闻资讯和技术研究。
本文首发于 AI人工智能时代,转载请注明出处。