上下文、压缩与缓存:大模型使用者必须搞懂的三个概念
内容提要
本文面向重度使用Claude Code/Codex的工程师,解析上下文窗口、压缩与缓存三概念及其因果链。上下文是模型单次可见的输入输出总和,有硬上限且随token增多质量下降;压缩在窗口将满时用摘要替换历史,会永久丢失细节;缓存通过精确前缀匹配复用计算,失效仅增加成本与延迟,不影响正确性。实践建议:会话开头定好模型,中途只追加不修改,任务间用/clear,压缩趁缓存热时进行。
延伸解读
缓存失效与压缩:代价不同,别混淆
缓存失效只是让下一轮请求变贵、变慢,模型看到的内容完全一致,不影响正确性;而压缩会用摘要替换历史,细节永久丢失,可能损害任务质量。理解这一区别是优化长会话的关键:缓存失效是成本问题,压缩是信息问题。
上下文窗口的隐性成本:输出也占空间
上下文窗口是输入与输出 token 的总和,输出(包括思考过程)同样占用空间。缓存过的内容依然计入窗口,只是计费不同。因此,即使有 1M 窗口,也要注意输出长度,避免因输出过多导致窗口提前耗尽。
压缩的时机与成本:趁缓存热时进行
压缩会触发一次额外的模型调用,消耗 token 并计费。在缓存热时压缩,成本仅为缓存读取价;若隔夜后缓存失效,压缩将按未缓存输入全价计费,成本显著上升。因此,建议在任务间隙、缓存仍有效时主动压缩,而非等到第二天。
缓存命中的关键:前缀稳定,避免中途改动
缓存基于精确前缀匹配,任何前缀改动都会导致后续全部重算。因此,会话中应避免切换模型、修改工具定义或编辑 CLAUDE.md(后者不生效且可能打断缓存)。保持前缀稳定,才能最大化缓存命中率,降低成本和延迟。
Q&A
上下文窗口、压缩和缓存之间是什么关系?
它们是一条因果链:上下文窗口是模型单次能看到的全部内容,有硬上限;当窗口快满时,压缩会用摘要替换历史来腾出空间;而缓存则是为了复用每轮重复发送的前缀,避免重复计算。压缩会打断缓存,因为摘要改变了前缀。
上下文窗口具体包含哪些内容?缓存过的内容是否占用窗口?
上下文窗口包含输入侧(系统提示、工具定义、历史消息、工具结果、图片/PDF等)和输出侧(思考过程、文本回复、工具调用请求)。缓存过的内容仍然占用上下文窗口,缓存只改变计费方式,不改变占用空间。
什么是上下文腐烂(context rot)?它有什么影响?
上下文腐烂是指随着上下文窗口中的token数量增长,模型的准确率和召回率会下降的现象。这意味着塞满上下文并不总是好事,主动筛选放入的内容和保持窗口精简同样重要。
压缩和缓存失效有什么区别?哪个对任务质量影响更大?
压缩会用摘要替换历史,导致细节永久丢失,影响任务质量;缓存失效只是重新计算前缀,模型看到的内容完全一致,只增加成本和延迟,不影响正确性。因此压缩对任务质量影响更大。
在Claude Code中,什么时候应该使用/compact,什么时候应该使用/clear?
应该在任务之间的自然断点使用/compact,此时压缩几乎零损失;在开始新任务时应该使用/clear,避免旧任务的摘要干扰新任务。避免在任务中途或调试细节时压缩。
缓存命中率如何判断?如果cache_creation持续很高说明什么?
缓存命中率可以通过usage中的cache_read_input_tokens和cache_creation_input_tokens判断,高读取/写入比说明缓存工作良好。如果cache_creation持续很高,说明前缀中有内容每轮都在变化,需要排查。
在Claude Code中,哪些操作会打断缓存?切换模型会有什么代价?
切换模型、改变effort level、打开fast mode、连接/断开MCP server(在特定模式下)、启用/禁用插件(提供MCP时)、deny整个工具、执行压缩、升级Claude Code等都会打断缓存。切换模型会导致整个历史重算,成本很高。
Claude Code中压缩后哪些内容会保留?哪些会丢失?
压缩后系统提示、输出风格、项目根CLAUDE.md、auto memory等会保留;带paths: frontmatter的rules、子目录嵌套的CLAUDE.md会丢失;已调用的Skill正文会重新注入但有token上限。
如何降低长会话的成本?缓存能节省多少?
通过保持缓存命中可以大幅降低成本。例如,300K token的上下文,20轮对话,无缓存成本约$30,缓存全部命中成本约$4.73,节省约六分之五。中途切换模型会增加额外成本。
Claude Code中缓存的作用域是什么?不同目录的会话能共享缓存吗?
缓存作用域是机器和目录,不同目录的会话互不命中,包括同一仓库的不同worktree。同一目录下并行的多个session可以共享缓存,但顺序启动的session只有在git状态快照一致时才共享。