用 OpenClaw 跑 Claude,发现一个诡异的现象:明明连续对话,prompt cache 却永远是 0% 命中,每轮都在疯狂写入缓存,从来不复用。

查了 /status,果然:

🗄️ Cache: 0% hit · 0 cached, 44k new

翻了 OpenClaw 的 prompt-caching 文档,找到了根因。

问题出在哪

OpenClaw 只会在 Anthropic API-key auth profiles 下,自动给 anthropic/ 开头的 model ref 注入 cacheRetention: "short"

但如果你用的是第三方代理(比如 model ref 是 modelfamily/claude-opus-4-6),即使底层走的是 Anthropic Messages API,OpenClaw 也不会自动注入 cache_control 标记。结果就是:每轮对话都当全新请求处理,系统 prompt 反复重新处理,缓存形同虚设。

一行配置搞定

~/.openclaw/openclaw.jsonagents.defaults 下加一个 models 字段:

{
  "agents": {
    "defaults": {
      "models": {
        "modelfamily/claude-opus-4-6": {
          "params": {
            "cacheRetention": "long"
          }
        }
      }
    }
  }
}

modelfamily/claude-opus-4-6 替换成你自己的 provider/model ref 就行。cacheRetention 支持三个值:

none — 不缓存

short — 短期缓存(对应 Anthropic 的 5 分钟 TTL)

long — 长期缓存(对应 1 小时 TTL)

改完重启 gateway:

openclaw gateway restart

效果立竿见影

改之前:

🗄️ Cache: 0% hit · 0 cached, 44k new

改之后第一轮(写入缓存):

🗄️ Cache: 74% hit · 245k cached, 88k new

第二轮(几乎全命中):

🗄️ Cache: 98% hit · 44k cached, 702 new

98% 的 token 直接走缓存,只有用户新发的消息是"新"的。响应速度更快,token 成本更低。

什么时候需要关注这个

如果你满足以下任一条件,大概率需要手动配置:

• 用第三方 API 代理(baseUrl 不是 api.anthropic.com)

• model ref 不是 anthropic/ 开头

/status 显示 cache hit 始终为 0%

花 30 秒加一行配置,省下的是每轮对话几万 token 的重复处理。值。