在扣子里搭工作流时会注意到一个现象:两段长度接近的提示,有的调用又快又省,有的明显更慢,差别常在提示缓存有没有命中。缓存命中并非玄学,它按前缀匹配,写法上有明确的章法可循。
提示缓存按什么规则命中
主流大模型服务会把提示的公共前缀暂存起来,下一次请求如果开头部分逐字一致,就直接复用这部分已算好的中间结果,只处理变化的后段。命中的前提是逐字匹配,哪怕开头只差一个空格,匹配就可能从那里断开。在 DeepSeek 的用量明细里,命中部分通常单独计价,省不省一眼可见。
前缀稳定为什么是第一位
把系统设定、任务说明、示例这些不变的内容全部放在提示开头,把会变的内容放到末尾,前缀才可能长期一致。示例的位置也要固定:同一组示例每次顺序打乱着放,前缀每次都断在示例区,缓存等于白配。
动态内容该放在哪一层
- 第一层(开头):系统角色、固定规则、静态示例——永不变动。
- 第二层(中段):任务模板、字段说明——低频变动。
- 第三层(末尾):用户消息、当次数据——每次都变。
三层各放什么、多久变一次,决定断点落在哪。
| 层级 | 放什么 | 变动频率 | 断点落在哪 |
|---|---|---|---|
| 第一层(开头) | 系统角色、固定规则、静态示例 | 永不变动 | 前缀长期一致,命中面最大 |
| 第二层(中段) | 任务模板、字段说明 | 低频变动 | 一改就断在前缀中段 |
| 第三层(末尾) | 用户消息、当次数据 | 每次都变 | 断在末尾,前面的前缀照常复用 |
| 公共头(跨场景) | 多场景共用的那部分前缀 | 稳定 | 公共头越长,跨场景命中面越大 |
命中失败的常见原因
- 时间戳、随机编号混进了开头。
- 多轮对话里历史消息被截断或重排。
- 不同请求间系统提示用了不同措辞。
示例区对前缀的影响见few-shot 数量多少合适?边际效应;符号与固定前缀的关系见提示里的标点和符号有用吗?过程拆开看;命中后输出怎么接解析,见结构化输出和后处理解析怎么配合?;JSON 场景的前缀写法见JSON 模式下还能自然表达吗?。
工程实践里,缓存还有一套分层治理的做法。先审计:把线上提示按出现频次排序,前两成的高频提示覆盖八成调用量,优先治理它们;再固化:给高频提示建版本号,改动走变更而不是随手编辑,前缀的稳定性才有制度保证;后监控:观察命中曲线,突然下滑往往对应一次无心的小改动,比如有人在开头补了个空格。多场景共用前缀时还有个技巧:把公共部分抽成公共头,各场景的专属设定接在后面,公共头越长、跨场景命中面越大,但也别矫枉过正——为凑前缀把当次数据塞进开头,命中上去了,输出质量却掉下来,缓存永远不该绑架提示质量。公共头多长算合适,看调用频次和单价一起定。缓存命中的前提也可以归纳成一句话:连续且逐字,从同一个字节开始,这两个条件缺一不可。
缓存命中检查单
- 开头三段是否逐字不变?——时间戳和编号全部后置。
- 示例顺序是否每次一致?——定序后不要打乱。
- 变量是否都压到末尾?——动态内容离开头越远越好。
缓存认死理:前缀逐字相同才算数。
多租户或多人协作的团队里,前缀治理还要加一条公约:任何人不得手改线上提示模板,改动走评审与发布,发布后自动对比新旧前缀并输出差异报告。制度看似繁琐,却能挡住九成的无意破坏;命中率是团队的公共资产,散养必掉。另外,命中率的统计口径也要对齐:按请求数还是按 token 数算,团队内部先统一,否则各自汇报的数字对不上,治理动作也会变形。
换个问法再问缓存命中三句
- 命中缓存会改变输出内容吗?:不会,它只是复用中间计算,结果与不命中时一致,变的只有速度和消耗。
- 对话式场景还能命中吗?:能,历史消息原样保留、只追加新消息时,前缀持续命中。
- 改一个错别字也要全部重来吗?:改动点之后的部分要重算,改动点之前的前缀不受影响。
一条原则收尾:把不变的钉在前面,把善变的赶去后面。


