draft · 仅 crs13 预览环境显示,正式站不会发布

04 Mid-conversation system messages,为什么它和缓存有关

Claude 最近新增的 mid-conversation system messages,看起来像是一个系统提示词能力,实际和缓存关系很直接。

传统写法里,系统指令放在请求最前面的 top-level system 字段。这个位置适合放长期稳定的规则,比如角色设定、工具使用原则、安全边界、项目级约束。它靠前、稳定,后续多轮请求容易复用缓存。

问题出现在会话中途。

Agent 跑了一段时间后,经常会出现新的系统级约束:用户临时切换权限模式,工具可用性发生变化,剩余 token budget 降到某个阈值,应用发现磁盘文件已经变化,或者需要追加一条新的执行策略。

如果把这些新规则直接追加到 top-level system 字段,整个 system prompt 就变了。按照 Claude 的缓存顺序:

tools → system → messages

system 位于很靠前的位置。它一变,后面的 messages 缓存也会受到影响。对长会话和 Agent 来说,这意味着前面已经缓存好的历史上下文可能要重新处理。

Mid-conversation system messages 解决的是这个具体问题。

它允许在 messages 里追加一条 role: "system" 的消息,把中途新增的系统级指令放到它真正出现的位置,避免回头改最前面的 top-level system

一个简化结构是这样:

{
  "system": [
    {
      "type": "text",
      "text": "Initial stable system instructions...",
      "cache_control": { "type": "ephemeral" }
    }
  ],
  "messages": [
    { "role": "user", "content": "Start working on the repository." },
    { "role": "assistant", "content": "I will inspect the code." },
    {
      "role": "system",
      "content": "The user has switched to review-only mode. Do not edit files."
    },
    { "role": "user", "content": "Continue from here." }
  ]
}

这里的关键点是:前面的 tools、top-level system、已有 messages 都不用改。新增规则出现在消息历史后面,前面已经缓存的 prefix 仍然保持一致。

官方文档也明确提到:prompt caching 会按 toolssystemmessages 的顺序 hash 请求前缀;命中需要到 cache breakpoint 为止精确一致。修改 top-level system 会改变很靠前的前缀,导致 system prompt 和后续 cached messages miss。把新指令放到消息末尾,前面的缓存可以继续命中,只有新消息按 fresh input 处理。

这对 Agent 很有用。

比如 Claude Code 这类工具,运行过程中会不断接收新的运行状态:

这些信息如果都写回最前面的 system prompt,会让缓存很不稳定。放到 mid-conversation system message 里,至少不会破坏它之前已经稳定的那段前缀。

不过这个功能现在限制很明确。

根据 Anthropic 文档,它目前只支持 Claude Opus 4.8,不需要 beta header。平台侧也有限制:Claude API 可用,部分云平台还没跟上。

所以它现在仍然有明确适用边界。这里更适合作为缓存机制的一个新方向来看,不能直接当成所有 Claude 调用都可用的通用能力。

还有一个安全边界也要提。

Mid-conversation system message 依然是 system 级别指令。它适合放应用或操作员确认过的状态变化,不适合塞未经验证的工具结果、网页内容、检索文档或用户粘贴的大段文本。否则就相当于把不可信内容抬高成系统指令,提示注入风险会更高。

从缓存角度看,这个功能的价值很清楚:它让中途新增的系统级信息留在中途,避免回头改动最前面的稳定前缀。

这也是 Agent 上下文工程里很重要的一条原则:长期稳定的规则放前面,临时变化的信息放后面。Claude 把 mid-conversation system messages 做成一个独立能力,本质上是在给长会话和 Agent 一个更细的上下文更新位置。