提示词缓存。
同一段两万令牌的系统提示词,会在一次对话的每一轮里被重新读取、重新计费——除非你把它缓存起来,那样这一段的花费大约只剩十分之一,而且到达得更快。本条目讲清支配提示词缓存的那一条规则(它是前缀匹配)、为何一个不起眼的时间戳就能悄无声息地毁掉它,以及你怎么判断自己的缓存到底有没有生效。
被缓存的究竟是什么。
在模型生成任何内容之前,它要把你的整个提示词——每条指令、每份检索到的文档、每一轮历史——处理成内部状态。这一步是实打实的算力,你要为它付出输入令牌和延迟,每一次请求都是如此。
提示词缓存让提供方把这份内部状态留存下来,当下一次请求以相同的文本开头时直接复用。模型本身没有任何改变;也没有任何数据被"学到"。这是一个算力缓存,它只有一条规则,其余一切都由此推出:
缓存是前缀匹配。缓存的键,是你的提示词从开头到某个标记点之间的确切字节。在位置 N 上有一个字节不同,就会让从 N 往后的一切缓存失效。变化之前的内容仍可复用;之后的一切都不行。
所以设计上的问题从来不是"我该不该开缓存",而是:我的提示词是否被排成了"稳定部分在前"的顺序?提供方会按固定次序拼装提示词——通常是工具定义、然后系统提示词、然后对话——而这个次序,就是前缀被构建出来的次序。
经济账,以及什么时候不划算。
被缓存的令牌并非免费,而这份不对称就是全部要点:
- 写入缓存比一次普通请求更贵——短存活期的条目通常在基础输入价的 1.25 倍上下,存活期更长的则大约是 2 倍。
- 从缓存读取则便宜得多——通常在基础输入价十分之一的量级。
由此得出一个盈亏平衡点:在较短的存活期(TTL)下,大致第二次请求就已经把第一次的写入溢价赚了回来;在较长的 TTL 下,你需要大约三次。条目会过期——短 TTL 以分钟计——所以问题在于你的流量能否在条目失效之前再次命中同一前缀。更长的 TTL 能挺过安静的间隙,但写入更贵,因此它是对"突发式流量"下的一个赌注,而非一次免费升级。
以下情形里,缓存是用错了工具:
- 提示词从第一个令牌起就不同。没有共享前缀,就没有什么可复用——你会付出写入溢价却换不来任何一次读取。
- 前缀太短。提供方设有最小可缓存长度,且因模型而异——常在几百到几千令牌之间。低于这个门槛就不会缓存,而且不会报任何错。这是"我开了缓存却什么也没发生"最常见的原因。
- 流量太稀疏。如果请求之间的间隔比 TTL 还长,那么每一次都是一次缓存写入。
那些无声的失效源。
缓存失效时没有任何响动——你只是继续在付全价。下面每一项,都是把某个易变的东西放进了前缀的靠前位置,从而让其后的一切统统失效:
- 系统提示词里的时间戳或请求 ID。在提示词顶部写"当前日期与时间:…",会让每一次请求都成为独一无二的前缀。如果模型确实需要日期,把它放进最新的那条消息里,而不是系统提示词。
- 不确定的序列化。序列化字典时不排序键、或遍历一个无序集合,都会让同样的逻辑内容在不同运行中产生不同的字节。
- 把逐用户或逐会话的值拼进共享指令。把用户 ID 插值进系统提示词,会让每个用户各有一份私有前缀,跨用户的共享就此归零。
- 会变动的工具清单。工具定义渲染在最前面。会话中途增删或重排一个工具,会让整个缓存失效——请确定性地排序工具,并保持这个集合稳定。
- 条件性段落。
if flag: system += …会把每一种标志组合都变成一份独立前缀,各自都要冷启动一次。 - 切换模型。缓存是按模型隔离的。"用便宜模型做简单子任务"这类优化,一旦把两边的冷缓存都算进去,可能比省下的还贵。
每种情形的修法都是同一个形状:稳定的内容在前,易变的内容在后。冻结系统提示词、让序列化具备确定性,并把任何逐请求变化的东西注入到被缓存那一段之后,而不是之前。
去验证它,以及为何智能体最在意这件事。
提供方会在响应的用量数据里报告缓存活动——通常是写入缓存的令牌数、从缓存读取的令牌数,以及按全价处理的令牌数。那就是你的仪表:
- 前缀相同的重复请求,应当显示出非零的缓存读取数。如果它一直是零,就有一个无声的失效源在作祟——把相邻两次请求渲染出的提示词字节做个 diff,看看是什么动了。
- 不要把"全价令牌数"当成"提示词总长"。它只是未被缓存的那部分余量。一个跑了一小时的智能体,其未缓存数字可能很小,恰恰因为其余部分都由缓存供给。
智能体是缓存从"优化项"变成"结构性问题"的地方。智能体循环在每一步都会重发整份不断增长的对话记录,所以一个 30 步的任务,会把同一批指令与工具定义重新处理三十遍。不加缓存,成本大致随步数的平方增长。这正是为何上下文工程与缓存设计其实是同一门工程:你把一段内容放在哪里,不只决定模型是否注意到它,也决定这次运行要花多少钱。
结论是:缓存不是一个你拨动的开关,而是你如何排列提示词的一种属性。把冻结的指令与工具定义放最前,把检索到的文档与对话历史放中间,把逐请求的那个问题放最后——然后去看用量数字,确认缓存真的在被读取。上下文缓存经济学深入解析为真实负载算清了盈亏平衡账,而循环内的成本控制与单位经济两章,则把它与成本、质量与延迟的其他杠杆并置。