Claude Code 任务 token 预算过大

一个任务烧穿上下文窗口、重构到一半自动压缩、把 plan 弄丢——拆成小步、把读取丢给 sub-agent、状态落盘。

**最快修复:**任务太大,整个工作集塞不进一个窗口,于是 Claude Code 自动压缩(把更早的对话摘要掉),把你的 plan 弄丢了。把活拆成 3-5 个有顺序的子任务,把读得多的调查丢给 sub-agent(Task 工具,它在自己独立的 context 窗口里跑),把 plan 写到文件,每一步开新 session。盯着 /context,在压缩触发前收尾。

你让 Claude Code “重构全应用的 auth 流程”。它读 src/auth/src/api/ 里的每个文件、把三个大配置文件塞进 context,重构做到一半就自动压缩——把你之前的几轮对话换成一份摘要、把你刚花 40K token 建好的 plan 丢掉了。下一条消息提了一个和原 plan 第 3 步矛盾的方案。

根因不是窗口太小。截至 2026 年 6 月,Claude Code 默认用 Opus 4.7、1M token 上下文窗口(2026 年 3 月 13 日起正式可用,按标准单价计费——以前超过 200K 的 2 倍长上下文溢价已经取消)。问题在于:一个不停增长工作集的单一任务,迟早还是会越过自动压缩阈值(默认窗口的 ~83.5%),而压缩是有损的。修法是把任务拆开,让每一步的工作集都稳稳压在那条线以下,步骤之间靠磁盘留状态。

你属于哪一类?

先跑 /context——它会打印出窗口里都被什么占着(消息、系统提示、MCP 工具、skills、文件、以及 autocompact 缓冲预留)。看一眼就知道下面哪一行对得上。

症状大概率原因章节
一长串 Read/Grep,还没 Edit 上下文就过 30-40%任务涉及文件太多原因 1
全新 session 一上来就显示用了不少CLAUDE.md / AGENTS.md 过大原因 2
一次 Grep 加了几万 token搜索范围太宽原因 3
每次工具失败后上下文都往上爬错误 trace 太长原因 4
一开始执行就已经用掉一大块plan mode 产出过大原因 5
几小时的长 session,出现了 “Compacting conversation”早该 restart原因 6

常见原因

1. 任务涉及的文件多到一个 context 装不下

一次重构 30 个文件意味着读 30 个、改的时候还得记得它们的内容、再写回。每文件 3-5K token,光读完就 100-150K。1M 窗口能吃得下,但每多读一个你其实不需要的文件,就把自动压缩那条线又拉近一点;一旦压缩触发,模型对你 plan 的工作记忆就被摘要掉了。

如何判断:session 开局是一长串 Read / Grep,没做任何 Edit 之前 /context 里文件就占了大头。

2. CLAUDE.md 或 AGENTS.md 太大

5000 行的 CLAUDE.md 每次 session 启动就吃 15-25K token,而且这笔开销每开一个新 session 都要再付一遍。更要命的是信噪比:臃肿的 memory 文件会把真正重要的规则埋掉。

如何判断:全新 session 在 /context 里就已经显示用掉了不小一块。wc -l CLAUDE.md 量一下、嵌套的 AGENTS.md 也量一下。

3. 搜索范围过宽

在大仓库里 Grep -r "auth" 出几千条匹配;模型”为了周全”全部装进 context。其实大部分匹配根本不相关。

如何判断:Grep 之后 context 跳了 20K+ token。看 Grep 输出——几百行就是范围太宽。

4. 长长的工具错误 trace 吃光预算

Bash 命令失败每次打 200 行栈追踪、重试 4 次——光这一项就 30-40K token、全是噪音。

如何判断:session 里有多次工具失败、每次失败后上下文指示器都往上爬。

5. plan mode 出的 plan 太大

“周全的 plan”列出每个文件、每个步骤,膨胀到 8-12K token。加上为验证 plan 做的支撑读取——还没生成代码就已经用掉一大块。

如何判断:plan mode 产出超过 200 行;session 开始执行的时候上下文已经用了不少。

6. 该重启没重启的长 session

跑了 4 小时还没 restart 的 session、plan + 决定 + 工具调用 + 错误 + 重试都堆在那里。哪怕没有单个大动作、累积负载也会装满窗口、触发压缩。

如何判断:session 跑了几小时;状态栏出现 “Compacting conversation”、或者 /context 显示用量逼近压缩阈值。

动手前先确认

  • 开始新任务前先跑 /context,看当前用量和构成。
  • 估一下任务规模:涉及多少文件、多少工具、多大输出。任何一个数字感觉大就先拆。
  • 分清哪些文件真要整文件读、哪些可以采样或 grep。

需要收集的信息

  • 当前 CLAUDE.md 和 AGENTS.md 大小(wc -l)。
  • 大概的 session 时长和最近做过的操作。
  • 任务原文和已经下过的约束。
  • 任务涉及区域文件数粗估。
  • 这个 session 里用没用过 sub-agent。
  • 有没有进度文件(.agent-progress.md 之类)。

最短修复路径

Step 1:把任务拆成”能装进一个 context”的小块

把任务改写成 3-5 个有顺序的子任务,让每个子任务的工作集都稳稳压在压缩线以下——在 1M 窗口上,每步瞄准大约 150-250K token 的活,这样一步永远碰不到 ~83.5% 那条阈值:

旧(一个任务、太大):
"重构全应用的 auth 流程"

新(四个子任务):
1. 读当前 auth 模块,把重构 plan 写到 .auth-refactor-plan.md
2. 重构 src/auth/login.ts 和 src/auth/session.ts(提交)
3. 在 src/api/* 里把调用方更新到新接口(提交)
4. 更新测试并跑(提交)

每一步都能独立提交、独立开新 context。

Step 2:读得多的调查交给 sub-agent

“去搞清楚 X 是怎么运作的”这类任务通过 Task 工具开 sub-agent。sub-agent 读 30 个文件、返回一份 500 token 的摘要——你的主上下文只看到摘要:

开 sub-agent:
"读 src/auth/ 和 src/api/auth* 下所有文件,输出一份 markdown 报告:
当前公开接口、调用方、session 存储、错误处理模式。只返回报告。"

主 session 上下文干净;sub-agent 的读取在自己窗口里。

Step 3:用定点读取替换整文件读取

不要 Read src/api/users.ts(500 行、4K token),改成:

Grep "session" src/api/users.ts  → 12 个匹配、200 token
Read src/api/users.ts:120-150    → 30 行、250 token

大部分 edit 需要的是文件里的一小块、不是整个文件。

Step 4:CLAUDE.md 瘦身、只留承重内容

CLAUDE.md 应该控制在 500 行以下(约 2K token)。把陈旧或者很少用的内容挪到限定范围的文件、按需加载:

CLAUDE.md → 留:架构决定、约定、绝对不能违反的规则
apps/web/AGENTS.md → web 特定细节(只在 apps/web/ 工作时加载)
docs/historical-decisions.md → 归档的历史理由(要用时再读)

Step 5:步骤之间把 plan 和状态落盘

把 plan 写到文件里、每步完成就提交、下一步开新 context 只输入 plan 文件:

# 重构 Step 1:
echo "## 重构 plan" > .auth-refactor-plan.md
# Claude 把 plan 写进这个文件

# Step 2(新 session):
# 跑 /clear(或开一个全新 session),然后粘:
# "读 .auth-refactor-plan.md,只执行第 2 步"

/clear 把 session 重置成空 context(这和 /compact 不一样——/compact 是摘要后接着干)。这样每一步起点都几乎是空的,不会背着上一步的读取。

Step 6:在干净边界 restart,别让它自动压缩

自动压缩默认在窗口 ~83.5% 左右触发、把更早的对话摘要掉接着干——而这正是让你丢 plan 的那个有损事件。要抢在它前面:/context 显示已经用进去不少时,收尾当前子任务、提交、然后 /clear 或开新 session。

收尾信号:  收尾当前步、提交、在压缩逼近前 /clear
手动控制:  在干净的点上用 /compact 主动摘要(时机你定)
调那条线:  设 CLAUDE_AUTOCOMPACT_PCT_OVERRIDE(1-100)挪触发阈值

在 plan 已经提交、已经落盘的干净边界 restart,永远比从一份把第 3 步丢掉的摘要里救回来便宜。

怎么确认已经修好

  • 执行到一半跑 /context:全程用量稳稳低于压缩阈值。
  • 任务中途没出现 “Compacting conversation”。
  • 如果你 /clear 或 restart 了,每个子任务都能从保存的 plan 独立重跑。
  • 最终结果和原 plan 一致、没有因为有损压缩而漂移。
  • commit 按子任务结构的逻辑增量落地。

长期预防

  • 用量逼近压缩阈值就当收尾触发、不当”还能继续”信号;提交后 /clear
  • CLAUDE.md 控制在 500 行以下;少用的内容挪到限定范围文件。
  • 默认走 Grep + 定点 Read、不要默认整文件 Read。
  • 涉及 >10 个文件的任务先拆再开始。
  • 任何需要读 >5 个文件的调查走 sub-agent——它在自己的 context 窗口里跑、只返回一份摘要。
  • 超过 20 分钟的任务都把 plan 和进度落盘——上下文 reset 或压缩也不丢。
  • 每个多文件重构做完后回顾哪些文件是真要读、哪些是防御性读。

常见坑

  • 把 2000 行的文件粘进对话”做参考”——这一粘吃掉 8K token 余量。
  • 一个 session 里把同一个文件读三次、agent 忘了自己已经有过。
  • 跑产生海量 stdout 的 Bashfind /treecat 大日志)——管道接 head 或者写到文件再 refer。
  • 上下文用量指示器过 90% 才看——这时候摘要在即、你依赖的 plan 可能就在淘汰队列里。
  • 把任务拆成”子任务”但每个还是巨大(3 个子任务各 100K)——子任务必须真的能装下。
  • 把 sub-agent 当贵——和被强制摘要毁掉 plan 比 sub-agent 便宜得多。

FAQ

Q:Claude Code 实际上下文上限是多少? A:截至 2026 年 6 月,Claude Code 默认用 Opus 4.7、1M token 上下文窗口(2026 年 3 月 13 日起正式可用;Sonnet 4.6 也支持 1M)。Claude Code 会预留一块缓冲(约 33K token)给 autocompact 预留、系统提示和工具定义,所以实际可用空间比标称数字略少。跑 /context 能看到精确构成。

Q:到哪个点会自动压缩? A:默认在窗口的 ~83.5% 左右。你可以用 CLAUDE_AUTOCOMPACT_PCT_OVERRIDE 环境变量(取值 1-100)挪这条线,或者用 /compact 按自己的节奏主动压缩。

Q:压缩一定会丢信息吗? A:会——设计如此。压缩是把更早的对话摘要掉,摘要有损。具体细节总会丢一部分。修法是把承重细节放到 CLAUDE.md 或者落盘的进度文件里,让它跨压缩、跨 /clear 存活。

Q:怎么看当前上下文用量? A:跑 /context 看详细构成,或者看状态栏 / 底栏。看到 “Compacting conversation” 提示就说明你已经越过阈值了。

Q:既然窗口有 1M,为什么还要拆? A:因为单个长任务会不停堆读取、错误、重试,迟早还是越过压缩线——而压缩正是弄丢你 plan 的那一步。拆分让每步工作集都很小、每步都能从磁盘独立重跑、commit 也更干净。更大的窗口抬高了上限,但不等于纪律可以不要。

Q:大任务用 Opus 还是 Sonnet? A:两者都支持 1M 窗口。Opus 4.7 在复杂多步 plan 上推理更好;Sonnet 4.6 在执行阶段更快更便宜。超大重构用 Opus 出 plan、用 Sonnet 子 agent 执行。

相关阅读

标签: #Claude Code #agent #排查