一个错位的模块,让每条消息重写19000个缓存Token

一个错位的动态块导致每条消息重写约1.9万缓存Token,修复后成本降低约15倍。
Atlarix团队在QA中发现,Build模式下每条消息都在重写整个Prompt缓存而非读取缓存,根源是一个模块位置错误:本应放在缓存断点之后的每轮动态内容(当前日期与用户请求)被合并进了携带断点的稳定系统提示块中。由于Claude缓存基于精确前缀匹配,断点前字节一旦变化,后续内容全部失效并以更贵的价格重写。该问题因单条消息内多次工具调用共享相同系统提示而被日志掩盖,最终通过对比两条连续真实请求的请求体定位。修复仅调整动态块位置、不改动提示词文字,使固定部分从第二条消息起以约十分之一价格读取缓存,成本降低约15倍,并新增了跨消息字节级对比测试。
引言:缓存优化中的隐形陷阱
在AI编程智能体中,Prompt缓存本是最具性价比的优化手段:系统提示和工具定义在每次请求中固定不变,服务商可将其缓存,并以极低价格回读。然而,Atlarix团队的一次QA检查发现,Build模式下每条消息都在重写整个缓存,而非读取缓存。问题根源竟是一个模块的位置错误。本文将深入剖析这个缓存bug的发现、修复过程及关键教训。

KV Cache 指模型在自回归生成过程中,为已处理的 token 保存的 Key 和 Value 张量,避免每生成一个新 token 都重新计算整个上下文。对于长系统提示(动辄上万 token),这部分计算量相当可观。
Prompt 缓存本质上就是把 KV Cache 持久化到存储中,并在后续请求命中相同前缀时直接加载。这也解释了为什么写入缓存比普通输入更贵——写入意味着要额外存储这些张量;而读取缓存之所以便宜,是因为省去了前缀的完整前向计算,只需从存储中加载。缓存的生命周期(5 分钟或 1 小时)对应存储保留时长,过期后需重新写入。
缓存机制简述:精确前缀匹配是关键
Claude的缓存基于精确的前缀匹配:从工具定义、系统提示到对话内容,直到标记的断点。若断点前的任一字节发生变化,从该字节起的所有内容都会缓存未命中,并重新写入缓存。根据Anthropic的定价,写入缓存比普通输入更贵(5分钟条目1.25倍,1小时条目2倍),而读取缓存仅需约十分之一的价格。因此,每次都写入的缓存比没有缓存更糟糕。
前缀缓存(Prefix Caching) 是大模型推理服务中一种以空间换时间和成本的优化技术。其原理是:当多个请求共享相同的前缀(如系统提示、工具定义、few-shot 示例)时,服务端可以复用之前计算好的 KV Cache(键值缓存),跳过对相同 token 序列的重复前向计算。
主流实现包括 Anthropic 的 Prompt Caching、OpenAI 的自动缓存以及 vLLM 等推理框架的 RadixAttention。它们的共同前提是前缀必须逐 token 完全一致——哪怕只改动一个字符,从该位置起的所有缓存都会失效。因此,工程上通常将提示拆分为「稳定前缀 + 动态后缀」,并为稳定前缀显式标记缓存断点。理解这一点,是判断缓存是否生效的基础。
我们发送了什么:稳定头与每轮尾的错位
Atlarix的系统提示分为两部分:稳定头包含智能体身份、工具规则和模式指令,在整个对话中不变,因此携带缓存断点,生命周期为1小时;每轮尾包含当前日期和本次消息的请求,每条消息都会变化,本应放在断点之后,作为独立块发送。
Ask模式正确实现了这一点,但Build模式却将两部分合并为一个字符串,然后在其后追加上下文、指南和项目笔记。结果,请求文本位于携带断点的同一个块中间,导致断点后的所有内容每次都被重写。
为什么问题未被发现:单消息检查的盲区
在单条消息内部,智能体会进行多次模型调用以处理工具结果,这些调用共享相同的系统提示。因此日志显示健康的缓存读取:在消息的第二步,缓存读取了19,379个Token。但缓存未命中只出现在消息之间,因为请求文本发生了变化。逐条检查消息的测试总是通过,从而掩盖了问题。

智能体循环(Agent Loop) 指 AI 智能体为完成一次用户请求而进行的多轮模型调用:模型先输出工具调用,系统执行工具后将结果回传,模型再继续推理,如此往复直到给出最终答案。同一用户消息触发的所有模型调用共享完全相同的系统提示和对话历史前缀,因此它们之间的缓存命中率天然很高。
这正是问题被掩盖的机制:单条消息内的多次调用会显示大量缓存读取,日志看起来完全健康;只有跨用户消息比较时,才会暴露系统提示中动态部分导致的缓存未命中。调试缓存问题时,必须区分「消息内调用」和「消息间调用」两个层面。
如何发现:对比两个真实请求
在对Anthropic格式提供商进行QA时,团队捕获了同一对话中连续两个请求体并进行对比。第一个差异出现在24,000字符系统块的第22,966个字符处:包含用户请求的<user_context>。之前和之后的内容完全相同,只有这一个块不同。正是这个错位的块导致了整个缓存的重写。
修复方案:拆分缓存块与每轮尾
修复方法是将Build提示在发送前重新拆分为两部分:缓存部分不再包含任何每条消息变化的内容,每轮尾作为独立的系统块在其后发送。提示词本身没有任何文字改动,只是调整了尾部的位置。应用中其他读取提示的部分仍然完整读取。
新增的测试模拟了QA过程:运行两条消息,要求缓存块逐字节相同,且请求位于后续块中。旧代码测试失败,新代码通过。
前后对比:数据说话
在Amazon Bedrock上使用Claude Haiku 4.5,同一对话的三条消息,Build模式下的缓存读写数据如下:
| 阶段 | 缓存读取 | 缓存写入 |
|---|---|---|
| 修复前,消息2和3 | 0 | 每条约19,600 |
| 修复后,消息1 | 0 | 19,348 |
| 修复后,消息2 | 18,767 | 597 |
| 修复后,消息3 | 18,767 | 620 |
从第二条消息开始,固定部分的提示现在以约十分之一输入价格进行缓存读取,而此前是以两倍输入价格进行一小时缓存写入。对于每条消息的固定部分,在Claude上便宜了约15倍,且相同的布局让任何基于前缀缓存的提供商都能复用。

核心教训:变化内容必须在断点之后
从这次事件中得出的规则是:任何每条消息变化的内容都必须放在最后一个缓存断点之后,且唯一可靠的检查是对比两个真实请求,而非单个请求。该修复已随Atlarix 15.9版本发布。
对于构建AI智能体的开发者而言,这个案例警示我们:缓存优化不仅需要正确标记断点,还需确保动态内容的位置正确,并通过跨消息的字节级对比来验证。忽视这一点,可能导致成本不降反升。
相关推荐

Workbuddy零基础入门:桌面AI智能体如何落地工作流
Workbuddy桌面AI智能体零基础教程解读:从安装、积分领取到文件管理与自动化工作流搭建,对比CodeX的适用场景与成本差异,帮助职场人完成从AI提问者到AI管理者的思维转变。

OpenAI智能体新栈:计算机操作、决策API与超速工作流
OpenAI Dev Day发布智能体新栈:Computer Use操作速度超越普通人,Decisions API基于Luna实现极低延迟分类,Agents API开放同源计算机操作能力,GPT-6.1 Sol成本仅为Astra七分之一。本文梳理核心更新、实测数据与开发者落地要点。

梁文峰开源推理框架DeepInfo,硬刚美国禁令
DeepSeek在开源模型后再开源推理框架DeepInfo,包含GPU/CPU交叉流水线、小模型预判大模型复核、华为昇腾与英伟达芯片全面适配等技术,直面美国联邦禁令。本文解析其对AI产业落地的意义与开源策略。