Claude Code 上下文窗口由选型对比(详解容量逼近时的自动压缩机制)

上下文窗口由系统提示、项目级 CLAUDE.md、会话记忆、用户消息、工具调用与工具返回结果、模型输出六部分共同组成,按”固定层 + 动态层”两层模型拼接;容量逼近时主循环触发自动压缩(compaction),把历史折叠成结构化摘要并腾出空间,让长任务得以继续跑。理解组成与压缩触发点,是控制 token 成本与避免”context rot”的前提。

一、上下文窗口的两层结构

Claude Code 沿用 Anthropic 主流大模型的”固定系统段 + 动态对话段”拼接模型。每次发往 API 的请求都包含两段,固定段由系统提示、CLAUDE.md、Hooks 注入内容、会话记忆等组成,每轮开销几乎一致;动态段随对话轮次线性增长,最终会触顶。

组成部分 类别 大致 token 量级 能否压缩
系统提示与工具定义 固定 约 3K 否
CLAUDE.md(项目级) 固定 数百到 8K 否(可手动瘦身)
Hooks 注入与 Memory 固定 数百到 2K 否
会话历史(用户+助手) 动态 随轮次线性增长 是
工具调用与返回结果 动态 单次可达数千 是(压缩时折叠)
当前用户消息 动态 单次数十到数百 否

固定段每轮相同、靠 Prompt Cache 复用计费,动态段才是真正吃光窗口的主因。读一个大文件、跑一次 npm test、让子代理返回一段总结,都会把上千 token 塞进动态段。

二、容量在什么阈值会触发自动压缩

Claude Code 主循环(Master Loop)持续监控当前上下文占比,到达阈值后会执行一次自动压缩,把旧的会话历史折叠成摘要,丢弃冗长的工具返回,保留任务进度、关键决策、已读文件路径等结构化要点。

  1. 监控阶段:每次请求前后,主循环对比当前 token 数与窗口上限;
  2. 触发阶段:达到容量阈值时,调度一次额外的模型调用做”自摘要”;
  3. 替换阶段:原始对话历史被摘要覆盖,文件读取与命令输出细节丢失;
  4. 续跑阶段:下一轮请求基于摘要继续,工具结果按需重新读取。

2.1 容量阈值的分级参考

业界对长上下文窗口的容量管理有共识的分级:0–50% 推理最稳;50–70% 出现轻微精度损失;70–90% 注意力被稀释、模型开始遗忘早期规则;90% 以上出现幻觉、规则被忽略。Claude Code 遵循类似分级,自动压缩落在后段触发。

2.2 一次会话的 token 累积形态

把上下文当作”可花钱的预算”会更直观:第 1 条消息 5K,第 3 条 4K(累计约 18K),第 5 条 3.5K(累计 35K),第 8 条 4K(累计 65K)……每条新消息都要把历史全部重发一次,token 增长呈典型累积曲线。

三、压缩触达后会发生什么

自动压缩不是”扩窗口”,而是”换摘要”,因此有可见代价。

  • 缓存失效:压缩改变了消息前缀,Prompt Cache 必须重新生成,下一轮成本上升;
  • 信息不可逆:被压缩的旧文件内容、命令输出、调试日志永久消失,需要时只能重新读;
  • 工具结果被截断:长 bash 输出、测试日志往往最先被折叠成几行总结。

需要让压缩保留”前情提要”时,可用 /compact 手动触发并附指令,例如 /compact focus on the auth refactor, drop the test debugging,把摘要聚焦到主题上。

四、四种主流的容量管理动作

压缩只是兜底,更稳的做法是把窗口管理前移到工作流里:

  1. /clear:彻底重置对话历史到 0 字节,切换任务或模型开始胡言乱语时使用;
  2. /compact:触发结构化摘要,保留关键决策与文件路径;
  3. 子代理(Subagent):把读大文件、跑日志分析等重活外包给独立上下文,主体只接收摘要;
  4. 渐进式披露:通过 Skills、MCP、路径作用域规则按需加载,避免一次性塞满。

实战中常见组合是”主会话压缩 + 子代理隔离 + 路径作用域规则”,三者叠加能把一次长任务稳稳控制在安全水位。

五、把容量控制在安全水位的具体做法

把窗口管理拆成可执行步骤,比靠”感觉”省事:

  1. 启用 /status 与 /context 实时观察 Ctx(u) 占比与 token 分布;
  2. 命中黄色区间(50–70%)后,改用 Grep 精确定位文件行号,避免整文件读取;
  3. 进入橙色区间(70–90%)立即 /compact 一次,给摘要加上”保留哪些决策、丢弃哪些调试”的指令;
  4. 触及红色区间(90% 以上)执行 /clear 并写一份交接简报给新一轮会话;
  5. 重型读取(架构总览、依赖图)通过 Task 工具交给子代理,主会话只拿结论。

六、压缩机制的局限与替代

压缩对”事实性回忆”很弱,对”决策与方向”很强。如果一项关键决策(接口约定、命名约束、模块边界)被压缩丢掉,下一轮模型会从摘要里”再发明”一套,造成隐性偏移。生产环境里,更稳的姿势是把它写进 CLAUDE.md 这样的固定层——固定段即使压缩也不会被覆盖。

子代理是另一个常被低估的方案:把”读懂这个 50 万行仓库”这种重活丢给子代理,主体只接收结构化结论,相当于把预算压力转嫁出去。

七、用脚本预估上下文是否装得下

写一段粗略的 token 估算脚本,能在执行大批量文件读取前预警。下面这段 Python 用字符/4 估算 token 数,能识别”快要装不下了”的批操作。

# estimate_tokens.py —— 粗略 token 预算检查(字符/4 近似)
import os, sys, pathlib

def est_tokens(text: str) -> int:
    # 中英文混合按字符数 / 4 估算;实际请用 tiktoken
    return max(1, len(text) // 4)

def scan(root: str) -> dict:
    total = 0
    by_file = []
    for p in pathlib.Path(root).rglob("*"):
        if not p.is_file():
            continue
        # 跳过二进制与大文件
        if p.suffix in {".png", ".jpg", ".pdf", ".zip"}:
            continue
        try:
            content = p.read_text(encoding="utf-8", errors="ignore")
        except Exception:
            continue
        t = est_tokens(content)
        total += t
        by_file.append((str(p), t))
    by_file.sort(key=lambda x: -x[1])
    return {"total": total, "top": by_file[:10]}

if __name__ == "__main__":
    root = sys.argv[1] if len(sys.argv) > 1 else "."
    budget = int(sys.argv[2]) if len(sys.argv) > 2 else 200_000
    r = scan(root)
    print(f"总 token 估算: {r['total']:,}")
    print(f"窗口预算:      {budget:,}")
    print(f"占比:          {r['total']/budget:.1%}")
    print("Top 10 大文件:")
    for path, t in r["top"]:
        print(f"  {t:>8,}  {path}")

跑法示例:python3 estimate_tokens.py ./src 200000。占比超过 70% 就该考虑分批读取或交给子代理,避免一次性把上下文塞爆。

常见问题(FAQ)

Q1:上下文窗口到底指什么?

模型生成下一条回复时能”看见”的所有 token,包含系统提示、会话历史、工具输入与结果。

Q2:自动压缩会丢东西吗?

会。被压缩的旧消息、工具返回细节永久丢失,只保留结构化摘要与关键决策。

Q3:怎么判断该不该手动 /clear?

当模型开始忽略 CLAUDE.md 规则、重复犯同样错误或要求重读已读文件时,立刻 /clear。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
小码农的头像小码农认证作者

相关推荐

返回顶部