Claude Code 如何避免长会话变慢并增加成本
每轮请求都会重新发送完整上下文,长会话因此变慢且更昂贵。运行 /context 查看固定开销,清理 CLAUDE.md,并在合适时使用 clear 和 compact。
如何避免长时间 Claude Code 会话变慢并增加成本
长时间运行的 Claude Code 会话会变慢并增加成本,因为每一轮都会重新发送完整上下文,而上下文只会不断增长。解决方法是按固定顺序进行维护。运行 /context,查看哪些内容占用了上下文窗口;删除每次请求都会产生费用的内容;然后在不相关的任务之间使用 /clear,在同一个长任务中使用 /compact 并附带说明。应连续完成一段工作,因为提示缓存失效后,原本成本较低的读取操作会变成对全部历史内容的完整重写。
代理会话背后的令牌计量器解释了为什么会产生这些用量。
在修改任何内容前读取 /context
不要猜测窗口的填充情况。Claude Code 会告诉您。
/context [all]以彩色网格显示当前上下文使用情况,并为上下文占用较高的工具和内存膨胀提供优化建议;all在全屏模式下展开各项明细。将结果分为以下 5 个部分。
- 系统提示。 Claude Code 自身的运行框架指令。在整个会话中固定不变。
- 工具定义。 Agent 可调用的每个工具的架构,包括所有已连接的 MCP(Model Context Protocol)服务器。
- 内存文件。
CLAUDE.md和自动内存,在会话开始时加载。 - 文件和工具结果。 读取的每个文件,以及命令输出的全部内容。
- 消息历史。 您发送的消息和 Claude Code 的回复。
前 3 项是固定开销,在会话期间的每个请求中都会产生。后 2 项会持续增长。在开始时一次性降低固定开销;持续管理不断增长的部分。
以下两个字符串表示窗口已满:
Context exceeds the 200k-token limit by 94k tokens — run /compact or /clear to continue.
Context is 94k tokens past the 200k-token compaction window — run /compact to reduce usage.第一个表示硬限制,超过后请求会被拒绝;对应的 API(application programming interface)错误为 Prompt is too long。第二个表示压缩窗口。在 1 million token 模型上,它可能低于模型实际的上下文窗口。超过该窗口后请求仍可成功,因此它表示警告,而不是拒绝。
在付费套餐中,/usage会增加另一部分信息:标记长上下文或缓存未命中等行为,并将近期使用量归因到具体技能、子 Agent 和 MCP 服务器。如果它提示配额已经用尽,您正在等待哪个限制窗口将决定现在缩减上下文是否有帮助,还是需要通过其他方式恢复工作。
CLAUDE.md 是一项永久成本,因此应保持精简
您的 CLAUDE.md 会在会话开始时加载,并一直保留在上下文中。如果其中包含详细的部署流程,那么即使您只是在测试文件中修正拼写错误,这些 token 也会一直占用上下文。Anthropic 建议只保留必要内容,并将文件控制在 200 行以内。
将流程移到 skills 中。skill 只有在调用时才会加载,因此每周运行两次的工作流在其他时间不会产生开销。压缩后,skill 有独立的预算:每个 skill 最多重新注入 5,000 个 token,总计最多 25,000 个 token,最早加载的内容会优先被丢弃。截断会保留文件开头,因此应将最重要的指令放在 SKILL.md 的顶部附近。
压缩后仍能保留的内容决定了指令应放置的位置。
- 系统提示词和输出样式不会改变,因为它们不属于消息历史记录。
- 项目根目录中的
CLAUDE.md、未限定范围的规则和自动记忆会从磁盘重新注入。 - 带有
paths:frontmatter 的规则会丢失,直到再次读取匹配的文件。 - 子目录中的嵌套
CLAUDE.md会丢失,直到再次读取该子目录中的文件。 - Hooks 不受影响,因为 hook 以代码形式运行,不会进入上下文。
因此,依赖的规则应放在项目根目录的 CLAUDE.md 中:Claude Code 会先清除较早的工具输出,然后进行摘要,因此对话早期的指令可能会丢失。使用 /memory 编辑记忆。Claude Code 会保留会话开始时加载的副本,因此会话中途的精简会保留 prompt cache,直到下一次 /clear、/compact 或重启后才会生效。上下文丢失只是规则停止遵循的一个原因。因此,如果规则显然仍在上下文窗口中,却仍然被忽略,请先排查其他原因,再重写规则。
在任务之间使用 /clear,在同一任务内使用 /compact
这两个命令看起来可以互换,但成本相差很大。
/clear [name] 会在没有上下文的情况下启动新会话。它不会发送请求,因此不产生费用。传入名称后,可以在 /resume 选择器中标记上一个会话;/reset 和 /new 是别名。切换到无关任务时应立即使用它,否则旧任务会在新任务的每条消息中再次发送并再次计费。
/compact [instructions] 会在继续同一会话的同时释放上下文:它会总结目前的历史记录并用摘要替换历史记录。在一个较长的任务中,如果仍需要保持连续性,请在任务内部使用它。
始终为 /compact 提供指令。 单独使用 /compact 时,它会根据默认提示词进行总结,而默认提示词不知道你还需要保留哪部分工作。提供指令后,它会保留以下内容:
/compact focus on the auth bug fix
/compact keep only the plan and the diff如果每次压缩的原因都相同,可以在项目的 CLAUDE.md 中添加固定指令,并放在 # Compact instructions 标题下。在新会话中,/compact 会输出 Not enough messages to compact.,这只表示当前还没有历史记录。
这里有两个成本容易混淆。总结请求会共享前缀,因此它读取现有缓存,而不是重新处理历史记录;其大部分耗时用于生成摘要。压缩较大的上下文仍然是大型请求,因为要总结的会话内容就是输入。压缩后的下一轮并不是耗时部分:它只需为更短的提示词重建缓存。
还有两个成本更低的命令。/rewind [description] 会将代码和会话回滚到检查点;如果要完全放弃某条路径,它比压缩更合适,因为它会截断回已经缓存的前缀。/recap 会将摘要作为命令输出追加,而不是替换历史记录,因此缓存的前缀保持不变。
自动压缩反复触发时,会输出以下内容:
Autocompact is thrashing: the context refilled to the limit...压缩已成功,但文件或工具输出连续多次重新填满了上下文窗口,因此 Claude Code 停止重试。可以通过按行范围读取过大的文件、使用能够排除大段输出的重点说明运行 /compact、将这部分工作交给子代理,或者在不再需要早期会话时使用 /clear 来恢复。
MCP 服务器会产生固定开销
您连接的每个 MCP 服务器都会在整个会话的每次请求中增加开销。无论是否调用该服务器,您都需要承担这部分开销。
Claude Code 会缓解这一问题。默认情况下,MCP 工具定义会延迟加载,因此在 Claude 使用某个具体工具之前,只有工具名称会进入上下文。运行 /context 可查看服务器的实际开销,运行 /mcp disable <name> 可移除当天不会使用的服务器。如果您在 VPS 上运行自己的 MCP 服务器,同样的计算方式也会限制单个服务器应暴露的工具数量。
请在会话开始时执行此操作。在工具定义保持延迟加载的情况下,连接或断开服务器只会追加到对话中,缓存仍然有效。如果工具定义会加载到前缀中,例如工具搜索已关闭,或某个服务器不适用延迟加载,则同样的变更会使下一次请求重新读取全部内容。
在进入上下文前过滤详细的工具输出
工具结果属于输入内容,并会在后续每一轮中重新发送。一次测试运行如果输出 20,000 个 token,这并不是一次性成本:在它离开上下文窗口前,每一轮都会再次产生成本。
在源头进行过滤。通过 hook 在 Claude 看到测试结果前只保留失败项,可以将大量输出压缩为几百个 token;当前轮次和后续每次重新发送时都能节省上下文空间:
npm test 2>&1 | grep -E "FAIL|Error:" | head -40hook 本身不会进入上下文,因为它们以代码形式运行。对于输出超过一屏的任何工具,都应采用相同方法。3,000 行的文件也是如此:只请求所需的行范围,因为完整文件进入上下文后会一直占用窗口。
限定代理读取的范围,并委派高噪声任务
明确指定文件和症状的提示只会读取该文件。要求整理项目的开放式请求会读取代理认为相关的所有内容,而且每次读取都会保留在当前上下文中。
将高输出量的任务委派给子代理。测试运行和日志处理都会消耗实际上下文;子代理会在自己的上下文中保留这些输出,只返回摘要。代价是:子代理需要建立自己的缓存,首次调用不会命中缓存;即使使用订阅,也仍采用 5 分钟的缓存生命周期。委派任务可以稳定地保护主上下文,但不一定会减少总 token 数。
缓存时钟:分段连续工作
提示缓存让重复发送变得经济:读取前缀按基础输入费率的 0.1x 计费,写入前缀按 1.25x 计费;如果使用一小时的生命周期,写入则按 2x 计费。每次使用都会免费刷新缓存条目,因此计时从上次使用开始。这些倍数能说明费用的构成,但不能说明具体金额,因此还要结合100万个 token 的实际费用,才能将完整上下文窗口换算成美元金额。
缓存生命周期取决于身份验证方式,因此笼统地说“缓存 5 分钟后过期”并不准确。
- 使用 Claude 订阅时,Claude Code 会自动请求一小时的生命周期。
- 超过套餐限制并开始使用用量额度后,这部分用量会单独计费,因此生命周期会恢复为 5 分钟。
- 使用 API key 或云服务提供商时,生命周期保持为 5 分钟。
ENABLE_PROMPT_CACHING_1H=1会启用一小时的生命周期,FORCE_PROMPT_CACHING_5M=1会强制将其恢复为 5 分钟。
无论使用哪种方式,节奏建议都相同:应连续工作,因为空闲时间超过生命周期后,下一轮请求会重新写入此前累积的整个前缀。在 tmux 中运行分离的 Claude Code 会话在空闲时不会产生费用,但缓存也会在这段空闲时间后失效。
有些操作会在工作过程中丢弃缓存:切换模型、更改 effort level、启用 fast mode、连接或断开 MCP server、启用或禁用插件、拒绝整个工具、执行 compact,以及升级 Claude Code。/model通常最容易造成意外,因为每个模型都有自己的缓存;因此,即使内容完全相同,下一次请求也会在没有缓存命中的情况下读取完整历史记录。这次重新读取会按目标模型的费率计费,因此在会话中途切换到 Fable 时,累积的全部历史记录都会按Fable 5 的公开输入费率计费。
编辑文件、编辑 CLAUDE.md、调用 skills 和 commands、运行 /recap、回退以及生成 subagent 都会保留缓存。缓存的作用域限定为一台机器上的一个目录,因此不同目录中的两个会话无法命中彼此的缓存。该作用域跟随 CLI,而不是跟随账户,因此缓存不会延续到 Claude 桌面应用;在 Linux 上,后者是与 CLI 并行安装的独立 beta 版本。
要确认缓存是否生效,请读取 current_usage。cache_creation_input_tokens按缓存写入费率写入;cache_read_input_tokens按约为标准输入费率十分之一的费率提供。读取次数与创建次数的比例较高,说明缓存状态正常。如果每一轮的创建次数都很高,说明前缀中的某些内容一直在变化。
更大的上下文窗口能解决这个问题吗?
只能部分解决。目前有几种模型支持 1 million token 的上下文窗口。在更大的上限下,压缩机制仍以相同方式工作。成本不会改变,因为每轮仍会重新发送完整提示词,并按每轮计费。更大的窗口决定您何时被迫采取行动;上下文管理决定成本。如果问题在于费用,而不是上下文上限,那么哪种 Claude 方案适合您的工作方式将决定您消耗的是现金还是方案额度。
API 中的上下文编辑和压缩是不同的功能
如果您在使用 Messages API 构建自己的代理,则不存在斜杠命令,需要自行实现这些功能。请从一开始就为这项工作预留预算,因为除少量注册赠金外,API 没有免费层级,因此未裁剪历史记录中的每一轮内容都会按完整用量计费。您选择的服务提供商会在执行任何裁剪前决定这部分成本,因此如果尚未确定提供商,请按相同工作负载核算两个 API 的成本,不要只比较标称的每 token 价格。服务器端有两个功能可以完成这项工作,但它们并不相同。
上下文编辑会在对话历史增长时,有选择地清除其中的特定内容,并将每个已清除的结果替换为占位文本,以便 Claude 知道有内容被移除。这是一项 beta 功能:发送 anthropic-beta: context-management-2025-06-27,并在 context_management.edits 下配置策略。clear_tool_uses_20250919 会清除工具结果,clear_thinking_20251015 管理思考块。其 trigger 默认为 100,000 个输入 token,keep 默认为最近 3 次工具调用,clear_tool_inputs 默认为 false,因此输入内容会保留,只清除结果。
压缩会生成摘要,并用摘要替换完整的对话历史。这同样是一项 beta 功能:发送 anthropic-beta: compact-2026-01-12,并使用编辑类型 compact_20260112。触发条件默认为 {"type": "input_tokens", "value": 150000},该值必须至少为 50,000。
压缩有一条容易被忽视的交接规则,违反它会导致代理运行异常。响应会以一个包含摘要的 compaction 内容块开头,后面是普通文本块。后续请求必须传回该内容块,API 随后会丢弃它之前的所有内容块。实际操作中,应附加完整的 response.content,而不仅是其中的文本。
Anthropic 的文档将服务器端压缩称为管理长时间运行对话上下文的主要策略,并将上下文编辑作为更精细控制清除内容的选项。请先确认模型支持情况。目前的 Opus、Sonnet 和 Fable 模型支持压缩;claude-haiku-4-5 不支持,压缩页面提供实时支持列表。两个 beta 功能都不会驱动 Claude Code 自身的 /compact;其文档将该功能描述为客户端发送的一次性摘要请求。
FAQ
为什么 Claude Code 会话运行时间越长,速度越慢、费用越高?
因为每一轮都会再次发送完整对话。因此,一个已经运行一整天的会话即使只提一个问题,也会携带当天的全部内容。提示缓存处于有效状态时,可以将这部分读取成本降至基础输入费率的 0.1x;一旦某一轮未命中缓存,相同的前缀会按 1.25x 的费率重新写入。运行 /context 查看哪些内容占用了上下文窗口,并阅读Claude Code 会话的计费内容了解其机制。
Claude Code 中的 /clear 和 /compact 有什么区别?
/clear 会在空白上下文中启动新会话。它不会发送请求,因此不产生费用,适合在无关任务之间使用。/compact 会保留同一会话,并将历史记录替换为摘要,因此适合在同一项长期任务中使用。请像 /compact keep only the plan and the diff 一样指定重点,因为该指令决定哪些内容会被保留。
如何查看哪些内容占用了 Claude Code 的上下文窗口?
运行 /context;如需查看完整的逐项明细,请运行 /context all。它会以彩色网格显示系统提示、工具定义、MCP 服务器、记忆文件和历史记录,并针对占用大量上下文的工具及过大的记忆文件提供建议。在付费套餐中,/usage 还会将近期用量归因到各个技能、子代理和 MCP 服务器。
应该使用 1 million token 的上下文窗口,而不是进行压缩吗?
更大的窗口只能延后问题,不能解决问题。目前有多个模型支持 1 million token 的上下文窗口,其中包括 Opus 4.8 和 Sonnet 5;在这些模型中,压缩的工作方式也相同。每一轮仍会重新发送完整提示,并继续按其计费。因此,无论是否能够容纳,包含 400,000 token 的对话都很昂贵。
Claude API 中的上下文编辑和压缩有什么区别?
上下文编辑会选择性地清除旧内容,主要是工具结果,并在每个被清除的位置保留占位文本,以便 Claude 知道这些内容已被移除。压缩会生成摘要,并用摘要替换完整历史记录。Anthropic 的文档将压缩称为长期运行对话的主要策略,并将上下文编辑定位为更精细的选项。两者目前都是 beta 功能,各自使用不同的请求头,并且都与 Claude Code 的 /compact 分开。