AI 编程教程中文版
从原理到实战

02 · 一次能看多少代码

上下文窗口不是记忆,是一张会满的工作台。100 万 token 听起来巨大,但用了 78% 你就会觉察 Claude 变笨——理解这张桌子怎么运作、怎么管,操作上的困惑就全解开了。

📖 本篇术语速查表
英文 / 缩写中文一句话解释
context window上下文窗口AI 一次会话中同时能看到的信息总量,本篇主角
token词元模型读 / 写文本的最小单位,1 个中文字大约 2 token
1M / 100 万 token100 万词元Sonnet 4.6 / Opus 4.6 / Opus 4.7 当前的最大上下文
/compact压缩命令把当前对话提炼成精简摘要替换原内容,腾出桌面空间
/clear清空命令直接清空整个对话历史,回到干净桌子
CLAUDE.md项目记忆文件写给 Claude 的长期指令,会话开始自动上桌(详见 03 篇)
Auto Memory自动记忆Claude 自动维护的项目学习笔记,存在 MEMORY.md(详见 03 篇)
MEMORY.md自动记忆主文件启动时只加载前 200 行或 25KB(取较小)
prompt caching提示缓存重复前缀缓存机制,省 token 不省桌面空间

不想读完?把下面这段提示词丢给 AI 帮你跑完——帮你搞懂 Claude Code 的上下文窗口,知道它一次能看多少、何时会满。

你是 Claude Code 上下文顾问。

【角色】
Claude Code 上下文顾问,按最小够用、安全优先的原则给可落地方案,每条结论都落到能照做的具体步骤或示例,不停留在「建议」「考虑一下」这类空泛表述。

【输入】
- 我做的项目规模:___
- 常遇到的上下文问题:___
- 是否长会话:___
- 对 token 的理解:___
- 经验水平:___

【工作流程】
1. 讲清上下文窗口是什么
2. 说明它和记忆的区别
3. 诊断我的上下文压力
4. 给管理上下文的方法
5. 给验证

【输出规范】
▌一、上下文窗口
▌二、和记忆的区别
▌三、压力诊断
▌四、管理方法 + 验证

【硬约束】
- 上下文是工作台不是记忆
- 长会话适时收敛
- 结论落到可操作步骤
- 不要替我臆测情况或编造不存在的功能,信息不全先问清
- 不确定的配置或接口一律以官方文档为准,禁止照搬过时写法

翔宇用 Claude Code 的头一个月,有时候它分析得头头是道,有时候聊着聊着就变笨了。翻了文档才发现,这不是智力波动,是工作台被堆满了。搞清楚这张工作台的运作方式之后,很多操作上的困惑就全解开了。——翔宇

这一篇用 13 分钟换什么:上一篇 01 我们理解了 Claude Code 的核心是位置——AI 住在你电脑里。这一篇拆它怎么你的项目:通过上下文窗口,把代码摊在一张大桌子上。理解了桌子怎么满、怎么管,后面的 CLAUDE.md、Skills、SubAgents 才有清晰的位置感。

1. 从最简单的情况开始

想象你面前有一张桌子。你和 Claude 在这张桌子上协作——你把文件摊开,它看了之后给你建议。

这张桌子就是上下文窗口(context window,会话工作台)

最简单的情况是这样的:桌子是空的,你问了一个问题,Claude 回答了。桌上放了两样东西——你的问题和它的回答。很轻松,空间绰绰有余。

这是所有人最开始用 Claude Code 的体验:反应快、回答精准、感觉什么都能搞定。

但随着工作推进,事情会发生变化。我们用一个具体的会话场景往下走——今天你要修一个支付回调的 bug

👤 你:账户充值后金额没到账,支付回调日志在 /logs/payment.log,可能跟 webhook 重试有关,帮我查一下。

🤖 Claude:好,我先看 payment.log 和 webhook 处理代码 (读 8 个文件:logs/payment.log 最近 200 行、controllers/webhook.tsservices/payment.tsmodels/transaction.tsqueue/retry.ts ……)

这个场景会贯穿整篇——从干净的桌子,一路跑到桌子被堆满,再到我们决定怎么处理。

2. 桌子上的东西越来越多

刚才那个支付 bug 调查继续推进:你让 Claude 看了 8 个文件,每个几百行;它跑了一次 webhook 重试测试,输出了 600 行日志;你和它来回讨论了十几轮,每轮分析至少 200 字……桌上已经堆了不少。

还有一些你看不到但确实存在的东西也在桌上:Claude Code 自身的系统提示(大约 50 条内置指令)、你的 CLAUDE.md 配置文件、Auto Memory(自动记忆)的 MEMORY.md 前 200 行。这些在每次会话开始时就自动上桌了。

flowchart TB
    Desk["📋 上下文窗口<br/>(你的工作台)"]

    System["🧠 系统级内容<br/>会话开始自动上桌"]
    User["💬 你说的话<br/>每条消息、每个追问"]
    AI["🤖 Claude 的回答<br/>通常比你的提问更长"]
    Files["📁 读取的文件<br/>500 行 ≈ 5000-7000 token"]
    Cmd["⚡ 命令执行输出<br/>测试 / 编译 / 安装日志"]

    System --> Desk
    User --> Desk
    AI --> Desk
    Files --> Desk
    Cmd --> Desk

    Desk -.->|持续累积| Full["⚠️ 桌子被堆满<br/>表现开始下降"]

    style Desk fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
    style Full fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
    style AI fill:#fee2e2,stroke:#ef4444

通俗讲:想象你在开一个长会。每个人说的话都在往白板上写——你说的、对方说的、中途查的资料、打开的文件。白板很大,但不是无限大。如果会开得够久,白板总会写满。

回到支付 bug 的会话。10 轮对话后,桌上已经堆了:

  • 8 个源文件 ≈ 4 万 token
  • 600 行日志 ≈ 8000 token
  • Claude 的 10 段分析 ≈ 1.5 万 token
  • 你的提问 + 系统提示 + CLAUDE.md ≈ 3000 token

加起来 7 万 token——感觉写满了?还差得远。继续往下读。

3. 这张桌子有多大

现在给桌子加一个数字:100 万 token(1 million token,词元)。

1 个 token 大约是 4 个英文字符(约 0.75 个英文单词),中文大约 2 个 token 对应 1 个汉字。所以 100 万 token 约等于 50 万中文字——5 到 6 本长篇小说的篇幅。

换算到代码场景:

单位大约 token实际大小直觉对照
1 行代码10-151 个完整语句
1 个中型源文件3000-7000200-500 行一个 controller / service
20 万 token(旧版上限)200,0001.5 万行代码能看一个模块的几个文件
100 万 token(Sonnet 4.6 / Opus 4.7 当前)1,000,0007-8 万行代码能看完一个中型项目全部源码

事实基准:Opus 4.7、Opus 4.6、Sonnet 4.6 都支持 1M context window(官方说明)。Max / Team / Enterprise 套餐 Opus 自动启用 1M。其它套餐 / Sonnet 1M 可能需要额外用量。模型别名加 [1m] 后缀显式启用:/model opus[1m]

回到支付 bug 的场景。我们刚才算了 7 万 token——这张桌子用了 7%。剩下 93 万 token 还能装很多东西。

能装很多东西不等于应该装很多东西。这就引出了下一个问题。

100 万 token 和 20 万 token 的区别不只是大了 5 倍。当你能同时看到整条链路时,你能发现的问题类型发生了质变——路由传了 userId 但控制器期望 user_id 这种跨文件的字段不匹配,只看一个文件永远发现不了。100 万 token 让一类原本不可能发现的问题变得可以发现

20 万 token 像是只能透过钥匙孔看房间——你能看清某个角落,但看不到全貌。100 万 token 像是打开了房门走进去——你能同时看到家具之间的空间关系。找一件东西的效率完全不同,不是快了 5 倍,而是从碰运气变成了一眼看到

4. 桌子一定会满

下一个自然的问题:它会满吗?

答案是:看你怎么用。如果你只做简单问答——问个问题、得到回答、再问一个——100 万 token 可以聊很久很久。

但实际工作中不是这样。继续支付 bug 的故事——你越查越深,桌子从 7% 一路膨胀到 78%:

第 1-10 轮:7% 占用

读 8 文件 + 跑测试 + 讨论。桌上:源码 + 日志 + Claude 的初步分析。

第 11-25 轮:18% 占用

让 Claude 重读相关 controller 全部测试。又加了 12 个文件 + 测试输出。

第 26-40 轮:28% 占用

检查支付网关 SDK 源码。SDK 整个 src/ 目录 ≈ 6 万 token 进入工作台。

第 41-60 轮:55% 占用

让 Claude 写修复代码 + 跑全量测试。大量长 diff + 测试日志。

第 61-80 轮:78% 占用

反复改 + 验证 + 联调。所有历史持续累加,没东西被释放。

第 81+ 轮:接近上限

你开始觉察 Claude 回答变慢变笨——它需要扫描的桌面太大了。

关键点:上下文窗口不是一个装东西的桶——东西放进去就静静待着。它更像一个每轮都要翻一遍的工作台。每一轮交互,Claude 都要把桌上所有东西扫一遍才能回答。桌上东西越多,每轮扫描越慢、成本越高。所以能用多少就用多少不是最优策略,只放需要的东西才是。

而且有一个容易忽略的点:上下文消耗不是线性的。随着对话深入,Claude 需要回顾之前的内容来保持连贯——这意味着每轮新交互,实际处理的信息量都在增长

为什么 Claude 在 78% 时会"变笨":模型每轮都要扫一遍桌上所有内容才能决定下一步动作。桌子越满,扫描越慢、注意力越分散、关键信息越容易被淹。这跟人开会到第 4 小时记不清前面讨论一个道理——不是脑子坏了,是认知带宽被堆满。1M token ≠ 1M 都好用——经验上 60-70% 占用就开始触发降级(Anthropic 的 prompt cache 机制对前缀重读有缓存,但全局注意力代价是真实的)。

所以问题不是会不会满,而是满了怎么办

5. 满了怎么办:三种策略

Claude Code 提供了三种应对策略,它们适用场景完全不同。先用一张决策树判断该走哪条路:

flowchart TD
    Start["⚠️ 觉察上下文接近上限<br/>Claude 回答变慢 / 变笨"]
    Q1{"接下来的工作<br/>跟之前有关联吗?"}
    Q2{"任务本身能不能拆<br/>成多个独立步骤?"}
    Compact["✨ /compact<br/>压缩当前对话保留精华"]
    Clear["🧹 /clear<br/>清空重来"]
    Split["🪓 拆分任务<br/>每步用独立会话"]

    Start --> Q1
    Q1 -->|有关联,要继续| Q2
    Q1 -->|完全无关,换主题| Clear
    Q2 -->|可以拆| Split
    Q2 -->|不能拆,必须连续做| Compact

    style Compact fill:#dcfce7,stroke:#22c55e
    style Clear fill:#dbeafe,stroke:#3b82f6
    style Split fill:#fef3c7,stroke:#f59e0b
    style Start fill:#fee2e2,stroke:#ef4444

三种策略各自的细节看下面的 tab:

/compact 压缩

原理:让 Claude 回顾当前对话,把核心信息提炼成精简摘要,然后用这个摘要替代原来那一大堆内容。

比喻:开了两小时的会,有人站起来说要总结一下刚才讨论的要点,然后擦掉白板上的细节,只留下几条关键结论。白板腾出了空间,核心决策没丢。

回到支付 bug:已经查到 78%,但 bug 还没修完,正在反复联调。这时候用 /compact:Claude 把前 60 轮浓缩成一段 webhook 重试丢失幂等键、已修 4 文件、测试还缺一轮,桌子从 78 万 token 缩回 8 万。继续干活,不丢上下文

进阶用法:指定压缩重点。

/compact 保留 webhook 幂等性相关的所有讨论

自动触发:Claude Code 在上下文接近上限时会自动触发压缩,你不需要时刻盯着 token 数。但提前手动压缩 / 清空仍然更聪明。

适合:任务还在进行 + 不能丢上下文 ❌ 不适合:下一步跟前面无关

/clear 清空

原理:直接清空整个对话历史,回到一张干净的桌子。

比喻:擦掉整块白板,重新开会。

回到支付 bug:bug 修完了,你接下来要写一个新功能用户邮件订阅设置页——这两件事完全不相关。继续在同一个会话里干,前面的 webhook / 幂等性讨论就是噪音。/clear/compact 更省 token。

和 /compact 的本质区别

  • /compact = 压缩但保留核心信息
  • /clear = 全部丢弃

判断标准很简单——问自己:接下来的任务跟刚才聊的有没有关系?有关联用前者,无关联用后者。

适合:切换到完全不同的任务 ❌ 不适合:当前任务还要继续

拆分任务

原理:第三种不是命令,是工作方式。把大任务拆成多个小任务,每个用一个独立会话完成。

回到支付 bug:其实它一开始就可以拆——

  • 会话 1(30 分钟):分析 webhook + 幂等性,输出根因报告 + 修复方案,保存到 docs/bug-payment-webhook-analysis.md
  • 会话 2(20 分钟,干净桌子):读分析文件,实施第一部分修复(修 controllers/webhook.ts
  • 会话 3(30 分钟,干净桌子):读分析文件 + 修改后的 controller,写测试 + 跑全量回归

每个会话都从一张干净的桌子开始,只放当前步骤需要的东西

为什么高效:一个任务的每个阶段需要的信息是不同的。分析阶段需要看很多文件但不需要之前的对话记录;实施阶段需要方案文件和目标文件但不需要分析过程。把所有阶段塞进一个会话,大量空间被已经过时的中间信息占据。

适合:任务很大 + 阶段之间能传递文件 ❌ 不适合:必须强连续上下文的紧密任务

速记:三种策略不是互相替代——/compact 保留精华继续干,/clear 清桌子换任务,拆分任务从一开始就别让桌子堆满。

新手最常踩的坑:等 95% 才 /compact。他们盯着进度条,到 95% 才动手压缩——这时候 Claude 已经"变笨" 半小时了,前面的判断质量大打折扣。正确做法是 60-70% 主动 /compact,趁还没明显降级时把桌子腾干净;或者更早就用"拆分任务"从源头避免堆积。

另一个常见误区:以为 /compact 是免费操作。压缩本身要让 Claude 把整张桌子读一遍再总结——这一轮本身就消耗大量 token + 时间。所以 /compact 不是"想压就压",是"任务还要继续 + 上下文确实满了"才用。简单换主题直接 /clear 更省。

6. 一个容易混淆的地方

到这里你可能注意到了:我一直在说桌子,没有说记忆。这是故意的。

很多人把上下文窗口类比成记忆力——100 万 token 就是记忆力超强,能记住很多东西。这个类比有一个致命的偏差:记忆是可以长期保留的,但上下文不是

一句话理解:上下文窗口是 AI 在一次会话中同时能看到的信息总量,不是它能永久记住的东西。你一旦关掉这次会话,桌上的东西全部清空。下次打开,桌子是空的。

看到记住是两件事。你看一本书的时候,翻开的那些页面你都看到了——但合上书之后你不一定记住了。上下文窗口决定的是 Claude 能同时翻开多少页面,不是它能永久记住多少内容

那 AI 怎么记住你的习惯和项目信息?那是另一套系统——长期记忆。下一篇 03 · 怎么记住你的习惯 会拆。

7. 回头看全貌

把前面所有内容串起来,形成一个可操作的心智模型

阶段桌子状态你该做什么
开始任务空(仅 CLAUDE.md + Auto Memory 摘要)放心让 Claude 读文件、跑命令
工作进行中持续累积有意识关注趋势:Claude 回答变慢 / 变笨 = 上下文快满信号
觉察到信号接近上限走 §5 决策树:/compact / /clear / 拆分
整个过程一个会话一个主题——上下文管理最省心的方式

底层逻辑:上下文管理的核心原则——让桌子上永远只有当前最需要的东西。不是追求桌子多大,而是追求桌子多干净。

8. 检验你真懂了吗

费曼说,检验你是不是真的理解一件事,试试能不能解释给朋友听。

#试着用自己的话回答对应章节
1有人说 100 万 token 就是记忆力好——你能解释这说法错在哪?上下文和记忆的本质区别是什么?§6
2上下文从 20 万扩到 100 万,为什么是质变不是量变?举一个只有看全貌才能发现的问题类型。§3
3动手题 ⭐:在你下次 Claude Code 会话开始前,先想清楚这次任务要分几步:① 调研 ② 设计 ③ 实现 ④ 测试。每步是同一个会话连着干,还是开新会话?写下你的拆分理由。提示:如果四步会议中前一步的代码片段对后一步不直接相关,就该开新会话——这就是 §5 拆分任务的核心。§4 + §5

过关标准:能用一句话说清——上下文窗口是 AI 一次会话能同时看到的信息总量,不是永久记忆;桌子会满,所以要主动管理。

官方资料

接下来去哪

不用按顺序全读。挑你最好奇的那条线走就行。

本页目录