提示词缓存

wescode 中的 per-conversation prompt caching——降低成本的关键机制。


缓存概念

Prompt 缓存允许 LLM provider 在对话中复用不变的前缀,显著降低 token 费用:

第 1 轮:[系统提示词 + 工具 + 技能 + 记忆] + [用户消息]
         ├──── 缓存前缀 ────────────────────┤  ├─ 新增 ─┤
         → 全量计费

第 2 轮:[系统提示词 + 工具 + 技能 + 记忆] + [历史消息] + [用户消息]
         ├──── 缓存命中(减免)────────────┤  ├───── 新增 ─────┤
         → 前缀按缓存价格计费(通常 ~10%)

第 N 轮:前缀越长 → 缓存节省越多

缓存条件

缓存前缀必须逐字节相同。任何改变——即使是一个空格——都会使缓存失效。


什么会打破缓存

以下操作会使缓存失效:

操作影响严重性
修改过去上下文前缀字节变化🔴 全量重计费
切换工具集工具 schema 变化🔴 全量重计费
重建系统提示词前缀变化🔴 全量重计费
加载/卸载技能系统提示词变化🔴 全量重计费
修改记忆系统提示词变化🔴 全量重计费

唯一允许的失效场景

上下文压缩是唯一允许的缓存失效场景——当 token 接近上限时,压缩是必要的。


系统提示词 byte-stable 保证

在整个对话生命周期内,系统提示词保持字节稳定:

对话开始时构建系统提示词(一次性):
├── Agent 角色描述
├── 工具 schema(所有启用的工具)
├── 技能内容(所有启用的技能)
├── Convention 快照
└── Eager Memory(环境/约束/指令等)

此后整个对话期间不改变
  → 字节稳定
  → 缓存持续命中

Slash 命令的缓存感知

默认行为:延迟失效

大多数修改状态的 Slash 命令默认在下一个会话生效:

/skills install code-review
  → 技能安装成功
  → 当前对话:不加载(保持缓存)
  → 下一个新对话:自动加载

即时失效:--now 标志

/skills install code-review --now
  → 技能立即加载
  → 系统提示词重建
  → 缓存失效 ⚠️
  → 当前对话费用增加

缓存感知设计

操作默认--now
安装技能下次生效立即生效 + 缓存失效
卸载技能下次生效立即生效 + 缓存失效
修改记忆下次生效立即生效 + 缓存失效
切换工具下次生效立即生效 + 缓存失效

不在对话中途切换工具集

禁止在对话中途切换工具集(强制缓存失效 + 模型困惑):

❌ 对话进行中 → 启用 "browser" 工具集
   → 工具 schema 变化
   → 缓存失效
   → 模型可能对新工具产生幻觉

✅ 开新对话 → 新对话自动包含"browser"工具集

技能/记忆/工具变更生效时机

变更类型即时生效下次对话生效
安装技能/skills install X --now/skills install X
卸载技能/skills uninstall X --now/skills uninstall X
修改工具集不推荐默认
Memory 写入Eager ❌ / Lazy ✅Eager ✅
Convention 变化❌(下次扫描)✅

Lazy Memory 的特殊性

Lazy Memory 不影响 prompt cache 前缀:

系统提示词(缓存前缀):
├── Agent 描述
├── 工具 schema
├── 技能
├── Eager Memory  ← 对话期间固定
└── Convention    ← 对话期间固定

用户消息旁边(不在前缀中):
└── Lazy Memory overlay  ← 每轮动态变化,不影响缓存

确定性排序

为了确保缓存命中,以下数据源在注入前必须确定性排序:

数据源排序方式
工具 schema按名称排序
技能内容按名称排序
Eager Memory按 scope + namespace + id 排序
环境信息按字段名排序
Plugin 注册按名称排序

如果排序不确定(如 map 遍历),即使内容相同,字节顺序不同也会导致缓存失效。


成本影响估算

假设系统提示词 = 10K tokens,对话历史 = 每轮增加 ~2K tokens:

轮次无缓存费用(相对)有缓存费用(相对)节省
110K10K0%
550K14K + 36K × 10%~70%
10100K19K + 81K × 10%~80%
20200K29K + 171K × 10%~85%

长对话中缓存节省显著——保护缓存直接降低费用。


最佳实践

  1. 不要在对话中途切换工具/技能:开新对话替代
  2. 使用延迟失效:除非必须立即生效
  3. 理解 Lazy Memory:它是缓存安全的
  4. 长对话更受益:缓存节省随对话长度增加
  5. 关注变更时机:大多数变更在下次对话自动生效