你让 Claude Code 写一份详尽的总结、一个长计划、或者一份多章节报告。它写到一半就停了——没报错、没提示继续、看不出原因。或者下一轮带着一个「Context low · run /compact」的提示(自动 compaction)出现、原来的细节没了。
最快的修法(约 80% 情况有效):直接输入 continue from the last sentence 回车。半截答案还在 context 里,所以 Claude Code 会接着写、而不是从头来。如果它每次都卡在同一个地方,那真正的原因就是下面几个桶之一——最常见的是某一次巨大的工具结果把回复的空间挤没了。
为什么会发生:Claude Code 跑在一个固定大小的 context window 里(截至 2026 年 6 月,Opus 4.7 和 Sonnet 4.6 都是 1,000,000 token)。工具结果、文件读取、之前的轮次、system prompt 全都和你这次回复挤在同一个 window 里。能切断回复的其实是两个独立的上限——单轮输出上限(模型给单次回答设的天花板)和 context window(总预算,快满时触发 auto-compaction)。截断几乎都能追到这两者之一。
你属于哪个桶
| 症状 | 大概率原因 | 跳到 |
|---|---|---|
| 每次都停在一个整数附近(Sonnet 约 64K、Opus 约 128K) | 单轮输出上限 | 原因 1 |
截断前刚跑过一个超大的 Bash/Read | 单次工具结果吃光窗口 | 原因 2 |
看到过 /compact 或「Context low」横幅 | auto-compaction | 原因 3 |
还没发第一条 prompt,/context 就显示 40K+ token | system block 臃肿(MCP/skill) | 原因 4 |
| 会话很长、堆满旧代码 dump | history 太啰嗦 | 原因 5 |
| 回复就这么结束了、看着也还算完整 | 模型自己写完了(end_turn) | 原因 6 |
常见原因
按命中率从高到低。
1. Assistant 回复撞单轮输出上限
这个和 context window 是两码事:每一次单独的回复都有一个由模型设定的最大输出长度。截至 2026 年 6 月,Claude Code 单轮最多能吐 Sonnet 4.6 的 64K 输出 token、Opus 4.7 最高 128K。你的 prompt 邀请的是 20 万 token 的回答,那不管 context window 还剩多少空,回复都会在这个天花板处断掉。
怎么判断:回复很长,而且每次重发同一条 prompt 都停在差不多的体积。截断后跑 /context——如果总 context 离满还远、回复却照样停了,那就是撞单轮输出上限、不是窗口满了。
2. 单次工具结果把窗口吃光
一次 Bash 调用吐出 20 万字符、或者 Read 一个超大文件,留给 assistant 思考和回复的空间就没了。
怎么判断:看截断之前最近那次 tool_result,如果体积巨大,就是它。
3. auto-compaction 中途启动了
窗口用量越过 auto-compact 阈值(截至 2026 年 6 月默认 95%)时,Claude Code 会把旧轮总结成一段压缩 recap、再从那里接着写。compact 之后那一轮可能丢了它原本依赖的细节,所以一个长答案明明是从摘要重建出来的、读起来却像「被截断」。Claude Code 还会在窗口顶部留一段 buffer(大约 33K token、约 10%),所以可用预算比标称的 1M 略低一点。
怎么判断:你看到过「Context low · run /compact」横幅或一行 checkpoint,或者 transcript JSON 里截断那一轮前面有一条 summary record。
4. System prompt + skills + tools 不知不觉膨胀了
每个插件、Skill、MCP server 在你打字之前就往 system block 里加 token。原本不大的 prompt 现在前面可能顶着 40K+ token 的 overhead,留给回复的更少、也更快把你推向 compaction 阈值。
怎么判断:跑 /context(或一开始就 claude --debug),看 system / tools / MCP 的 token 拆分。那里数字意外高的话能解释很多事。
5. 之前的 assistant 轮太啰嗦、一直占着 context
早先几轮要是吐了大段代码,那些都还留在 context window 里。几轮下来就把你预算占完了。
怎么判断:往上翻。会话里全是几千行的代码 dump,预算就没了。
6. 模型确实没更多东西要说
有时候看着像被截、其实模型本来就想停在那。「半句话」的感觉可能是个该有却没产生的句号。
怎么判断:打开 transcript JSONL 里那条 assistant record,看它的 stop_reason。end_turn 是模型自己选择停下;max_tokens 是撞到了单轮输出上限。
开始前
- 大致记下被截断回复的长度(行数或字符数)。
- 能访问
~/.claude/projects/下最近的 transcript 文件。 - 想清楚你是只要一次完整输出、还是反复都要长输出。
- 必要时准备把 prompt 拆小。
需要收集的信息
- Claude Code 版本:
claude --version。 - 触发截断的那条 prompt 原文。
- 截断后立刻拍一张
/context快照(system、tools、MCP、messages 的拆分)。 - 截断点前最后几条 tool result。
- transcript JSON 里的
summary/ compaction record。 - 当前模型(
/model),因为 Sonnet 4.6 和 Opus 4.7 的单轮输出上限不一样。
一步一步修复
Step 1:用 /context 看预算
在会话里跑:
/context
它会把当前装进来的东西显示出来——system prompt、tools、MCP server、消息历史——以及各占窗口的比例。总用量接近 95% 就快 auto-compact 了;用量很低、长回复却照样停了,那就是撞了单轮输出上限。要看原始 transcript,JSONL session 文件在 ~/.claude/projects/ 下:
ls -lt ~/.claude/projects/*/*.jsonl | head -3
每一行是一条 record;一次 compaction 会在被重建那一轮的前面显示为一条 summary record。
Step 2:缩小前面那次工具输出
截断前的 Bash 或 Read 结果太大,就改用更窄的范围重跑:
# 不要 dump 整个文件,改成:
sed -n '100,200p' big-file.log
或者写到磁盘、让模型读一份摘要。
Step 3:让模型从断点继续
简单一句「从最后一句话继续」通常就行,因为之前的 context 还留着半截答案。别让它从头重来,那是双倍 token 开销。
Step 4:把任务拆章节
要长结构化输出,每次只要一段:
只写第 1 节:架构概览。这一节写完就停。
下一轮再要第 2 节。每一轮都舒舒服服地装在上限以内。
Step 5:在长回复之前主动 compact
会话里堆了一堆无关的工具调用,在要那个大答案之前先自己跑一下 /compact 把它们总结掉、给接下来的回复腾出 token。可能会丢细节,所以 recap 要看一眼。如果意外的 auto-compaction 才是真问题,可以调高触发点或干脆关掉:
# 把 auto-compact 触发点压低、让它更早触发(默认 95):
export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=80
# 或者彻底关掉 auto-compaction(会写进 ~/.claude.json):
claude config set -g autoCompactEnabled false
也可以在 /config 里切换「Auto-compact」开关。关掉之后,你会撞到一个硬性的「Context low」停止、而不是一次静默重建,这往往更好判断。
Step 6:关掉用不到的 MCP server 和 skill
每个 MCP server 和 skill 都往 system prompt 里加 token,/context 会把这笔账显示给你。这次会话用不到的就关掉:
claude --strict-mcp-config --mcp-config '{}' # 启动时一个 MCP server 都不加载
--strict-mcp-config 会忽略你的配置文件、只加载 --mcp-config 传进来的东西;空对象就是一个都不加载。或者临时从 .mcp.json / 设置里把 server 挪掉。连着的 server 越少,system block 越小、留给回复的空间越大。
Step 7:反复要长输出,就写到文件
让 agent 把长输出用 Write 写进 markdown 文件,对话里只回路径加摘要:
把完整报告写到 /tmp/report.md,回复时只给路径加 5 条 bullet 的总结。
这样根本不会撞对话里的 token 上限。
怎么验证修好了
- 用修好的方式再发一次同样的 prompt,能拿到一份停在完整句子上的回复。
- 回复后跑
/context,用量稳稳低于 95% 的 auto-compact 线。 - 后面几轮不再蹦出意外的「Context low · run /compact」横幅。
- 写文件那条路下,磁盘上的目标文件是完整的、就算对话里回复短——打开看一眼最后一行。
长期预防
- 工具输出尽量小,多用
head、tail、sedrange、grep,少用全量 dump。 - 长结果一律写盘、用路径引用,别贴进对话。
- 盯着
/context,会话过了窗口约 70% 时自己跑/compact,别等 auto-compact 在 95% 处把答案写一半时触发。 - 审一下当前激活的 skill 和 MCP server,平时不用的关掉,让 system block 保持小。
- 反复要的报告,用一个每次只要一章的 prompt 模板。
容易踩的坑
- 截断后让模型「从头再生成一遍」——token 直接翻倍、同一个上限照样可能撞。
- 读整个 log 文件、而不是
grep出相关行。 - 让 auto-compaction 静默丢掉之前重要的决策;它产生的 recap 要看一眼。
- 五个 MCP server 都连着、其实只用一个;用
/context查查这笔开销。 - 把每个短回复都当成截断,其实模型只是写完了这一轮。
常见问答
- Claude Code 的 context window 多大? 截至 2026 年 6 月,Opus 4.7 和 Sonnet 4.6 都是 1,000,000 token(从原来的 200K 涨上来的)。扣掉 system prompt、tools、history 和约 33K token 的预留之后,实际可用预算略低一点。
- 为啥
/context显示还剩很多空间、我的长答案还是停了? 你撞的是单轮输出上限,它和窗口是两码事。Sonnet 4.6 单轮最多吐 64K 输出 token、Opus 4.7 最高 128K。把答案拆成几节就能绕过。 - 为啥对话自己 compact 了我没让它做? Claude Code 在窗口用量到默认 95% 时会自动 compact。可以用
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE调低触发点、自己更早跑/compact、或者用claude config set -g autoCompactEnabled false关掉。 - 怎么直接让一段被截断的答案接着写? 输入
continue from the last sentence。半截文字还在 context 里,所以 Claude Code 会从断点接上、不用为重启再花 token。 - 写文件算 context 用量吗?
Write这个工具调用本身占一些 token,但文件内容不会留在窗口里——这正是把长输出导到磁盘的全部意义。 - 要不要总把没用的 MCP server 关掉? 长会话该关,每个连着的 server 都在撑大 system block;临时的一次性小活儿一般无所谓。
相关
- Claude Code 到一半因 usage limit 停下
- Claude Code token 预算开太大
- Claude Code subagent 结果回传不到主会话
- Claude Code 上下文断裂
- Claude Code 输出和 prompt 对不上
- Claude Code 半执行后卡住
标签: #Claude Code #排查 #agent #排查