Claude中提示词自动缓存机制
深入解析Claude提示词自动缓存机制:大语言模型多轮对话中,Agent框架需重复发送上下文与工具描述,造成高额token开销。通过cache_control实现预填充计算复用,缓存token费用仅为基础输入的10%。本文详解缓存工作原理、自动缓存块跟随策略,并探讨多模型Agent开发的适配建议。
为什么需要缓存
绝大多数的AI应用是使用多个上下文进行多轮交互。而正如我们所知道的大语言模型是无状态的,这意味着它不会记住过去的操作。Agent 框架需要在每一轮对话中,将新的上下文连同历史操作、工具描述和通用指令一起打包发送。
这意味着大部分上下文在每轮对话中都是相同的。但如果不使用缓存,我们每轮都要为整个上下文窗口付费。为什么不复用这些共享的上下文呢?这就是 Prompt 缓存的作用。从定价页面可以看到,缓存token 的价格只有基础输入token 的 10%。使用缓存后,只有新的上下文才会支付昂贵的费用,而缓存了的数据的价格则非常低廉。
他是如何工作的
一般来说,LLM 推理流程通常包含一个处理提示词的预填充(prefill)阶段和一个生成输出token 的解码(decode)阶段。
缓存背后的直觉是:预填充计算只需执行一次,然后保存(即缓存),如果后续提示词(的部分内容)相同,就可以直接复用。vLLM 和 SGLang 等推理库/框架采用了不同的方法来实现这一核心思想。
在Claude中的使用
在 Claude Messages API 中使用缓存时,需要设置一cache_control 这一参数,它可以放置在的任意的提示词块上。这会告诉 Claude 下面两件事情。
首先,它是一个"write point",告诉 Claude 缓存截至并包含该内容在内的所有块。系统会对该内容之前的所有内容块生成一个哈希值。这个缓存的作用域限定在你的工作区内 。
"messages": [
{ "role": "user", "content": "A" },
{ "role": "assistant", "content": "B" },
{
"role": "user",
"content": "C",
"cache_control": {"type": "ephemeral"}
}
]其次,它告诉 Claude 从该块向前搜索最多20个块,查找之前是否有匹配的缓存写入(即"命中")。哈希要求内容完全一致,哪怕一个字符的差异都会产生不同的哈希值,从而导致缓存未命中。如果匹配成功,缓存内容将在预填充阶段被复用。
不过,缓存仍然存在一些挑战。对于多轮对话的应用(例如 Agent),随着对话的推进,你需要不断将缓存位置移动到最新的块上。Claude的API 现在通过自动缓存(auto-caching)解决了这个问题。你只需在调用Claude Messages API 的请求中设置一cache_control参数即可。
{
"cache_control": {"type": "ephemeral"}
"messages": [
{ "role": "user", "content": "A" },
{ "role": "assistant", "content": "B" },
{ "role": "user", "content": "C", }
]
}使用自动缓存时,缓存块会自动移动到请求中最后一个可缓存的块。随着对话的增长,缓存块会自动跟随移动。如果你想手动设置缓存(例如在系统提示词或其他上下文块上),它仍然可以与块级缓存配合使用。
另一个挑战是如何设计提示词以最大化缓存命中率。例如,如果你编辑了对话历史(见下文),就可能导致缓存失效。
译者评注
这个文章很短,主要想强调Claude的提示词自动缓存机制是如何工作的。但是在看完这个小短文之后,自己还是想说那句话,LLM只是整个智能体应用的一部分。LLM是大脑,没有好的Agent配合依然是很难充分发挥其能力。
同时这也揭示了为什么智能体应用看似简单,但是开发却困难重重。因为不单单的是LLM本身在进化,LLM的供应商也在进化,这就导致了一个模型上可用的方案在另外一个模型上可能就不好用的。同LLM供应商提供的LLM模型在某些Agent表现异常的好,但是在另外的一些Agent表现的却非常差。
因此我们在开发Agent的时候,要首先选中几个能力相近的LLM作为我们的备选,并且集中在一个LLM上实现自己的Agent行为,再为备选进行适配,甚至必要的时候根据的模型的不同切换提示词。