前两篇分别拆了缓存怎么算钱(《同一份材料,为什么第二次交给AI只收1/10?缓存计费拆解》)和这笔钱到底省在哪张显存上(《KV Cache:每读1个token,就要交一笔“显存税”》)。这一篇把两条线合到一起——问题往往不出在缓存机制本身,而出在你喂给缓存的那份提示词,正在悄悄变胖。

一、系统提示词正在膨胀

很多团队的系统提示词,都是这样长起来的。

一开始可能只有一句话:你是一个专业助手,请按用户要求完成任务。后来慢慢补角色设定、输出格式、禁用事项、工具说明、异常处理、合规边界、历史经验、项目背景、风格要求。半年下来,这句话变成了一份几千字的说明书。

系统提示词是怎么变胖的
系统提示词是怎么变胖的

看起来很专业,像是把模型管住了。问题是,这些字每一轮都要进上下文,每一轮都可能被计费,每一轮也都可能影响缓存命中。

这不是错觉,而且不是哪一家的孤例。

Anthropic在2026年4月30日发过一篇官方博客《Lessons from building Claude Code: Prompt caching is everything》,作者Thariq Shihipar是Claude Code团队成员。他复盘了几个具体翻车案例:曾经把一个很详细的时间戳放进静态系统提示词,曾经让工具定义的排序变得不稳定,还改过工具参数(比如Agent工具可以调用哪些子Agent)——这些看似很小的改动,都破坏过缓存。这条材料很硬,因为不是外部用户猜测,而是做Claude Code的人自己说的。

用户侧也能看到类似现象。anthropics/claude-code的一个GitHub issue(#45188)里,有用户报告Claude Code在2.1.89到2.1.96版本之间,首次缓存创建量从约38-52K token涨到112-119K token,5天左右涨了约7万token。作者说这让可用上下文明显变小,多步任务还没跑完就要频繁手动/compact。他还做过排除法:关掉自定义hook、拔掉候选MCP、删掉过期插件,重新测量体积都没变——说明这次膨胀来自版本本身的迭代。这是一条用户实测个案,不是Anthropic官方确认的数字,引用时需要标清楚。

OpenAI Codex的用户也报告过类似现象(issue #19212):只问一句“2+2等于几”,就消耗了约1.3万token。他让Codex自己估算这些开销来自哪里,得到的拆解是:系统指令、网页浏览策略、编码风格开发指令、工具schema、以及AGENTS.md和环境上下文。这同样是用户观察,不是官方统计,但说明一件事:Agent类产品的系统开销,很大一部分发生在用户输入第一个字之前。

这不是单一厂商的问题,而是Agent工作流的共同代价。OpenRouter联合a16z在2025年12月发布的实证研究《State of AI: An Empirical 100 Trillion Token Study with OpenRouter》(Aubakirova等人,arXiv:2601.10088)分析了平台上超过100万亿token的真实调用数据,其中一个发现是:平均提示词长度从约1,500token涨到超过6,000token,涨幅接近4倍,驱动因素是工具调用和多步推理这类智能体工作流的兴起。这条数据来自OpenRouter平台的真实流量,是一手实证研究,但样本边界是“OpenRouter平台”,不代表全行业所有调用场景,引用时应保留这个限定。

膨胀本身不一定是错误。真正的问题是,很多膨胀不是因为任务变复杂了,而是因为大家习惯把所有东西都塞进同一份不断变化的系统提示词里。

二、膨胀为什么会拖累缓存

要理解膨胀为什么烧钱,得先理解Prompt Caching到底在缓存什么。

Claude官方文档写得很清楚:缓存层级是tools→system→messages,某一层发生变化,这一层以及它后面的所有层都会一起失效。也就是说,工具定义一变,系统提示词和后面的对话历史都可能要重算;系统提示词一变,后面的对话历史缓存也会被连带打掉。

缓存不认“差不多一样”,只认前缀是否逐字节一致。前面动一个地方,后面内容再长也要重新处理一遍。这时候,系统提示词越胖,一次失效的代价就越大:如果你把当前时间、随机trace、用户ID这类临时信息塞进了本该稳定的前缀里,这个前缀每一轮都不一样,缓存自然吃不到,模型还要反复处理这段越来越胖的上下文。

Prompt Caching 只认稳定前缀
Prompt Caching 只认稳定前缀

更麻烦的是,缓存写入本身也不是免费的,而且这件事正在变得更贵。Anthropic的写入计费是:5分钟有效期收标准输入价的1.25倍,1小时有效期收2倍,只有命中读取才是0.1倍。而OpenAI在2026年7月9日GA的GPT-5.6系列上,第一次对缓存写入收费——同样是标准输入价的1.25倍,最短缓存生命周期30分钟。更准确地说,OpenAI在GPT-5.6系列开始把缓存写入单独计价;Anthropic侧则早已把5分钟写入、1小时写入和缓存读取分成不同倍率。两边的共同信号是:缓存失效不再只是性能问题,而是可以在账单字段里被直接看见的成本问题。

膨胀还会拖慢响应。前一篇《KV Cache》讲过,模型处理请求分Prefill和Decode两个阶段:Prefill阶段要把完整输入过一遍、把每个token的K和V算出来存好,这一步耗时随输入长度增长;命中缓存时,这一整段Prefill会被直接跳过。NVIDIA NIM的官方基准测试文档里也确认了同一个规律:提示词越长,首字延迟(TTFT)通常越高,因为注意力机制要先处理完整输入、建立好KV缓存,才能开始生成第一个token。用户看到第一个字之前,模型已经先读了一大堆前文——这笔延迟账,跟token计费账是并行发生的两笔账。

一个量级参照:Claude Code官方博客提到,一次100轮的Opus长会话,不靠缓存要花50-100美元输入token费用,靠缓存能压到10-19美元,差距接近5倍。这个量级基本就是“膨胀又频繁失效”和“精简且稳定命中”之间的现实落差。

长上下文还有一重更隐蔽的代价:不一定让模型变聪明。Chroma Research 2025年7月发布的论文《Context Rot: How Increasing Input Tokens Impacts LLM Performance》测试了18个主流模型(含GPT-4.1、Claude 4、Gemini 2.5、Qwen3等),发现即便是很简单的任务,模型表现也会随输入变长而下降,而且这种下降不均匀、因模型而异,跟“待检索信息在上下文里的位置”“是否存在语义相似的干扰内容”这些因素都有关系。换句话说,“模型看得到”和“模型能稳定用好”不是一回事——这也是很多Agent跑到后半程会变得犹豫、绕路、反复确认的原因之一:上下文还在,有效上下文已经被稀释了。

三、怎么写“缓存友好”的提示词

原理和坑都清楚了,落地按优先级排。

第一,稳定内容前置,动态内容殿后。工具定义、系统指令、长期规则放最前面,项目背景和少量示例次之,用户当前问题和临时参数放最后。这条前两篇已经讲过具体操作,这里不重复展开。

第二,会过期的信息不要写回系统提示词本身。Claude Code的做法是:日期变了、文件改了,这类信息不去改静态前缀,而是作为一次性的旁路提示(<system-reminder>标签)插进当轮用户消息,静态前缀保持不动。很多团队的问题就出在这里——把“当前时间是几点”“用户在哪个页面”“本轮任务ID是什么”都拼进了系统提示词,结果每次请求的系统提示词都不一样,缓存自然命不中。

第三,不要中途增删工具,用工具表达状态,而不是换工具集。Anthropic官方明确说过,改变工具集是最常见的缓存破坏方式之一——因为工具定义本身就在被缓存的前缀里。Claude Code给了一个具体解法:不为了切换Plan Mode就换一套工具,而是让模式切换只追加对话内容、不改动工具定义,缓存就不会因为模式切换而失效(Claude Code官方文档里唯一的例外是opusplan这种会在Plan Mode切换时连带切换模型的设置,因为模型本身也是缓存key的一部分,这种情况下确实会重建缓存,值得在配置时留意)。如果工具本身很多(比如挂了几十个MCP工具),Claude Code的做法是用defer_loading:先只发一个只有名字和一句话描述的轻量占位(stub),模型需要时再通过工具搜索去加载完整schema。这样任何用户配置了多少MCP工具,前缀里的stub都是同一套、同一个顺序,缓存不受影响——这套机制目前是官方文档里“受支持模型”的默认行为,不用额外配置。这是一条可以直接照抄的工程实践,在Anthropic的官方工具文档和Claude Code官方文档里都有单独说明。

第四,系统提示词要定期“体检”,别只加不减。很多系统提示词变长,是因为每遇到一个坏case就往里面补一条规则,补到最后规则互相重叠甚至冲突——这既增加了缓存成本,也增加了模型要消化的负担。关于“Claude Code系统提示词从约800token砍到164token”这个具体案例,目前只查到几家科技媒体的二手报道(称2026年7月2日在AI Engineer World’s Fair上宣布),另外还有报道提到Thariq Shihipar在7月24日发布过一篇更完整的说明,讲的是围绕Claude 5系列做的六项系统提示词精简(规则改判断、示例改交互设计、前置上下文改按需加载的技能、去重、自动记忆替代手动CLAUDE.md、简单文本改用代码和评测集这类更丰富的规范),两处报道的时间和细节对不太上,没有找到Anthropic自己发布的原始页面核实。这条建议只作为方向性旁证使用——该精简就精简,不一定掉性能——不当作正文的核心证据。可以做的具体检查是:这条规则是否还在解决真实问题、是否和别的规则重复、是否只适用于极少数临时场景、能不能挪到用户消息或检索结果里去。

第五,监控缓存命中率,而不是只看总账单。Claude Code团队会监控自己的prompt cache hit rate,命中率过低会触发SEV级别的故障报警。这个态度值得搬到自己的项目里:命中率是一个需要报警的运维指标,不是上线后就不用管的数字。具体可以盯这几个字段:cache_read_input_tokens(缓存读取量)、cache_creation_input_tokens(缓存写入量)、input_tokens/total_input_tokens(总输入量),以及TTFT(首字延迟)。只看总token不够,你需要知道这些token里有多少是缓存读取、有多少是新写入、有多少完全没进缓存。

第六,长对话定期折叠成状态摘要,不留寒暄和流水账。这条上一篇《KV Cache》详细讲过操作方法:总结当前进展、带着总结开新会话,而不是让草稿纸和缓存前缀一起无限膨胀。这里再强调一次:折叠不只是省显存,同时也是保住缓存命中率、避开context rot的一举三得动作。

第七,知识库不要全塞进提示词。大段背景资料优先做检索,只把和当前问题相关的少量片段放进提示词。这属于检索增强这条线的范畴,本文不展开,一句话带过。

缓存友好的提示词结构
缓存友好的提示词结构

把以上几条落到一张表里,可以按“变化频率”给提示词分层:

层级内容变化频率缓存策略
稳定层角色设定、工具定义(含defer_loading占位)、长期规则、输出格式几乎不变独立缓存断点,长期复用
半稳定层项目背景、业务口径、少量高质量示例偶尔变单独断点,更新时只重建这一层
动态层当前用户问题、临时参数、时间戳、system-reminder旁路信息每次都变不进入缓存前缀,放在末尾
结果层本轮希望返回的格式和长度要求按需变视稳定程度归入前面对应层

写在最后

回到标题:提示词越写越长,到底是在帮AI,还是在烧钱?

答案不取决于长度,取决于这些字有没有还在工作。帮AI理解任务的字该写——任务边界、输出格式、关键约束、必要示例,这些内容短了反而容易出错。但只是为了让AI记住上一次没变过的东西,就应该放进能被缓存接住的稳定前缀里;已经过期的时间戳、临时状态、被换掉的工具集、流水账式的历史对话,不该继续霸占系统提示词。

而现在,这件事已经不只是工程师之间口口相传的经验了。Anthropic和OpenAI几乎在同一时间段,都开始对“重新建立一份缓存”这件事明码标价。膨胀不再是一种只有细心的人才会注意到的隐性浪费,它正在变成账单上一条越来越清楚的费用。

好Prompt不是最厚的说明书,而是每一个字都知道自己为什么还留在上下文里的那一版。


资料边界说明

强可信,一手官方:

中强可信,一手研究:

  • Chroma Research《Context Rot: How Increasing Input Tokens Impacts LLM Performance》(Kelly Hong, Anton Troynikov, Jeff Huber,2025年7月)。trychroma.com/research/context-rot
  • OpenRouter × a16z《State of AI: An Empirical 100 Trillion Token Study with OpenRouter》(Aubakirova等,arXiv:2601.10088,2025年12月):提示词平均长度4倍增长的数据来源,样本边界为OpenRouter平台。arxiv.org/abs/2601.10088

中可信,用户实测个案:

谨慎使用,二手报道且细节不一致: