---
title: "避免大上下文反复重建缓存"
description: "全面详细介绍破坏上下文缓存的常见因素与实用规避方法，以及保持缓存命中的实践守则，有效降低大上下文重建的高额成本"
---

[缓存原理篇](/guide/prompt-caching)讲过:**前缀一致才命中,变一个字节全重建**。上下文越大,一次重建越昂贵——200K 前缀重建一次相当于几十轮命中的费用;1M 模式下更是灾难。本篇讲实践中最常见的"缓存杀手"和对策。

## 缓存杀手清单

### 1. 把动态内容放进了前缀

时间戳、随机数、每轮变化的状态,只要出现在系统提示或早期消息里,每一轮的前缀都不一样,缓存**永远无法命中**。

```text
❌ system: "当前时间:2026-08-22 21:35:07。你是..."   ← 每轮都变,缓存全废
✅ system: "你是..."(稳定)
✅ 时间等动态信息放到最新一条 user 消息末尾,或让模型调工具查询
```

自己搭 Agent 时这是头号陷阱。检查方法:打印相邻两轮请求体做 diff,前缀必须逐字节一致。

### 2. 中途修改系统提示 / CLAUDE.md / 工具集

`tools` 和 `system` 排在最前面,改动它们等于把整条缓存链从头炸掉:

- 会话中途编辑 `CLAUDE.md`、`/memory`、更换 output style ⇒ 前缀变化;
- **中途接入或断开 MCP 服务器**、增删工具 ⇒ `tools` 段变化,全量重建;
- 切换模型 ⇒ 缓存按模型隔离,等于从零开始。

对策:**把配置变更放在会话边界**。要改 CLAUDE.md、要挂新的 MCP,先改完、`/clear` 或重启会话再开始干活;不要在一个 50 轮的长任务中间做这些事。

### 3. 修改、删除历史消息

一些自制 Agent 框架喜欢"整理"历史:把旧的工具输出截断、给旧消息瘦身、滑动窗口丢掉最早的消息。每次整理都改变了前缀 ⇒ 全量重建。

对策:

- 对话保持**只追加**(append-only);
- 确实需要瘦身时,**一次性大幅压缩**(比如把前 80% 历史换成一段摘要),而不是每轮小修小补——压缩一次付一次重建成本,之后在新前缀上继续累积命中;
- 这正是 Claude Code `/compact` 的做法:不到阈值不动历史,一旦压缩就是一次到位。

### 4. TTL 过期

默认缓存 5 分钟不访问就过期。开发时被打断 10 分钟,回来第一轮必然是全额写入。

对策:

- 高频交互期不用管,每轮命中都会刷新 TTL;
- 可预期的长间隔(批处理、低频定时任务)用 **1 小时 TTL**(`ttl: "1h"`);
- 别为了"保温"去空转请求——5 分钟一次的心跳请求本身也要花钱,算一下通常不划算。

:::warning[订阅账号的 1h TTL 是个"薛定谔的开关"]
`ttl: "1h"` 对 **API 计费用户**是明确可用的(按 2× 写入价)。但对**订阅账号**(Pro/Max 计划下的 Claude Code),Anthropic 目前的策略并不透明:有的账号能享受到 1 小时级的缓存保温,有的只有默认 5 分钟,官方没有公开的开放条件,也没有地方能查询自己属于哪种。实际影响是:同样中断 20 分钟回来,有人的会话还热着,有人就要全量重建。别把工作流押在"我的缓存能活 1 小时"上——以 5 分钟 TTL 为基准安排工作节奏,能享受更长的算赚到。
:::

### 5. 并发分叉

同一个前缀同时开多个分支请求,缓存写入尚未完成时,后到的请求会各自重建。自制多分支/并行采样系统时,先发一轮把缓存建好,再放并发。

## Claude Code / Codex 用户的实用守则

官方 CLI 已自动管理断点,你的职责是**别破坏前缀**:

1. **改配置在会话边界做**:CLAUDE.md、MCP、模型切换,改完再开新会话;
2. **一个任务一个会话**:跑长任务别中途切模型、切风格;新任务用 `/clear` 重开,既清上下文又从干净前缀重建缓存;
3. **控制单次输出物大小**:一条 20 万 token 的命令输出不但吃窗口,还会把后续每轮的增量计算变贵——用 `| tail`、`--quiet`、写入文件后局部读取;
4. **长任务优先交给子代理**:子代理的高噪音探索不进主窗口,主窗口前缀保持小而稳(见[工具爆炸篇](/guide/tool-explosion));
5. **观察指标**:API 用户看 `cache_read_input_tokens` 占比,健康的长会话应在 90% 以上;Claude Code 用户可用 `/cost`(API 计费时)和 `/context` 观察。

## 自建 Agent 的检查清单

```text
□ tools / system / 早期消息中没有任何每轮变化的内容
□ 对话 append-only,不回头改历史
□ 断点打在稳定层级末尾(tools 末、system 末、倒数第二条消息)
□ 相邻两轮请求 diff,前缀逐字节一致
□ usage.cache_read_input_tokens > 0 且占比随轮次上升
□ 长间隔场景用 1h TTL;压缩历史一次到位而非每轮微调
```
