章节字数:8,000+
阅读时间:约 25 分钟
///
PART 01
开篇:一场令人崩溃的对话
你一定有过这样的经历——
你和 AI 开始一个新的任务。你描述了一大段背景,它说「明白了」。你继续深入,给了更多细节,它又说「没问题」。然后你问了一个后续问题,它突然说:「抱歉,我不清楚你刚才说的 X……」
你内心 OS:「我明明说过了啊?!」
这种「AI 失忆症」比真正的失忆症还让人抓狂——因为 AI 不是真的忘记了,而是它的「记忆容量」被塞满了。
本章将揭示 AI 听不懂人话的根本原因:不是 AI 笨,而是你的上下文超出了它的处理能力。
///
PART 02
2.1 鱼的记忆:AI 上下文窗口的秘密
2.1.1 什么是「鱼的记忆」?
俗话说「鱼的记忆只有 7 秒」。虽然这在生物学上并不准确,但它形象地描述了短时记忆的局限性。
AI 的「记忆」同样有限。这个限制叫做 Context Window(上下文窗口)——它指的是 AI 一次对话中能「看到」的最大信息量。
鱼的记忆 ≈ 7 秒
AI 的记忆 ≈ 取决于模型(10 万到 200 万 Token 不等)
但请注意:这里的「看到」和「记住」是两回事。
AI 并不是真的像人类一样「记住」了所有内容,而是它的一次推理只能处理这么多信息。如果信息超过了这个容量,超出的部分就会被「遗忘」——或者更准确地说,被丢弃或压缩。
2.1.2 上下文窗口的类比:会议室的大小
让我们用一个会议室来类比上下文窗口:
想象你有一个会议室,里面只能坐 10 个人。
场景 1:小型会议(正常上下文)
- 你邀请 5 个人进来
- 每个人都能听到其他人的发言
- 讨论完整、有连贯性
场景 2:大型会议(上下文溢出)
- 你硬塞了 20 个人进来
- 只能让 10 个人先进去
- 后面进来的人不知道前面说了什么
- 于是你问:「刚才张总说的方案是什么?」
- AI:「抱歉,我不知道张总说了什么,因为我不在场。」
这就是上下文窗口的本质:它决定了 AI 一次能处理多少信息。
2.1.3 为什么 AI 看起来「记不住」?
你(第 1 分钟):「我的项目叫 Alpha,用户数据库在 PostgreSQL,用的 Express.js...」
你(第 5 分钟):「帮我写一个 API 来查询用户数据」
你(第 10 分钟):「等等,我用的是 MongoDB,不是 PostgreSQL」
AI 内心:「你到底用的什么数据库???」
这不是 AI 的记忆力问题,而是:
AI 的处理方式:
┌─────────────────────────────────────────┐
│ 输入:前 10 分钟的所有对话 │
│ 输出:基于这个「切片」的回答 │
└─────────────────────────────────────────┘
问题:如果对话太长,早期的内容会被「挤出」窗口
///
PART 03
2.2 Token 是什么?一顿饭吃了多少「口」
2.2.1 什么是 Token?
Token 是 AI 处理文本的基本单位。你可以把它理解为文字的「一口」。
当我们说「吃一顿饭」
- 不是按「粒」计算米饭
- 而是说「吃了几口」
当我们说「AI 处理文本」
- 不是按「字」计算
- 而是说「消耗了多少 Token」
Token 和字的关系:
| 语言 | 每个 Token 约等于 |
|---|---|
| 英文 | 0.75 个单词(一个单词约 1.3 个 Token) |
| 中文 | 0.5-1 个汉字(取决于复杂度) |
| 代码 | 差异很大(简单符号 0.25 Token,复杂关键字 2+ Token) |
2.2.2 Token 的实际计算
让我们看几个实际例子:
英文 Token 计算:
"The quick brown fox"
= 4 个单词
≈ 5 个 Token(每个单词 1-1.3 Token + 标点符号)
中文 Token 计算:
"人工智能"
= 4 个字符
≈ 4 个 Token(汉字通常 1:1)
代码 Token 计算:
"function calculateSum(arr) { return arr.reduce((a,b) => a+b, 0); }"
= 1 行代码
≈ 25 个 Token(每个符号、关键字都是独立 Token)
2.2.3 Token 消耗的「饭量」比喻
想象你每吃一口饭,餐厅就收费一次。Token 就是 AI 的「饭量计费器」。
一顿标准对话的 Token 消耗:
┌─────────────────────────────────────────────────┐
│ 你的输入(「帮我写一个函数」) │
│ → 约 10-50 Token │
├─────────────────────────────────────────────────┤
│ AI 的思考过程(内部推理,不显示) │
│ → 隐藏 Token:可能比你输入多 5-20 倍 │
├─────────────────────────────────────────────────┤
│ AI 的输出(「好的,以下是代码...」) │
│ → 约 200-2000 Token(取决于输出长度) │
└─────────────────────────────────────────────────┘
一顿对话 = 吃的 + 嚼的 + 消化的 + 吐出来的
Token 限制 = 胃的容量(装不下了就呕吐/截断)
2.2.4 Token 成本的经济账
AI 服务是按 Token 计费的。理解 Token 能帮你省下真金白银:
| 模型 | 输入成本 | 输出成本 | 上下文上限 |
|---|---|---|---|
| Haiku(轻量) | $0.80 / 1M | $3.20 / 1M | 200K Token |
| Sonnet(均衡) | $3.00 / 1M | $15.00 / 1M | 200K Token |
| Opus(旗舰) | $15.00 / 1M | $75.00 / 1M | 200K Token |
成本对比示例:写一个 500 字的代码解释
Haiku:约 0.002 美元(几厘钱)
Sonnet:约 0.01 美元(1 分钱)
Opus:约 0.05 美元(5 分钱)
差距:25 倍!
但 Haiku 便宜≠最好用——它处理复杂逻辑的能力也最弱。
///
PART 04
2.3 上下文窗口的硬性限制
2.3.1 主要模型的上下文窗口
不同 AI 模型有不同的「胃容量」:
上下文窗口容量对比(单位:Token)
Opus 4: ████████████████████████████████████ 200,000
Sonnet 4: ████████████████████████████████████ 200,000
Haiku 4: ████████████████████████████████████ 200,000
Gemini 1.5: ████████████████████████████████████████████████ 2,000,000
Claude 3.5: ████████████████████████████████████ 200,000
GPT-4o: ████████████████████████████████████ 128,000
Llama 3.1: ████████████████████████████████ 128,000
关键发现:主流模型的上下文窗口普遍在 10 万到 20 万 Token 之间。
2.3.2 上下文窗口消耗的实时计算
上下文窗口不是只有「满了」和「没满」两种状态——它是一个持续消耗的游泳池。
上下文消耗公式:
Context % = (输入 + 输出 + 推理 + 缓存读取 + 缓存写入) / 模型限制 × 100%
实际消耗场景演示:
场景:你在分析一个代码库
时间点 1:刚打开项目
├─ 系统提示词:3,000 Token
├─ 你的第一条指令:「帮我分析这个项目」
│ └─ 500 Token
└─ 上下文占用:1.75%
时间点 2:看完 20 个文件
├─ AI 读取了 20 个源代码文件
│ └─ 80,000 Token
├─ AI 输出了详细分析
│ └─ 3,000 Token
└─ 上下文占用:43%
时间点 3:追问 10 轮后
├─ 历史消息累积
│ └─ 120,000 Token
├─ 最新文件读取
│ └─ 15,000 Token
└─ 上下文占用:68%
时间点 4:继续深入
├─ 接近上限
│ └─ 175,000 Token
└─ 上下文占用:87.5%
⚠️ 超过 90% 后,AI 可能会开始「遗忘」早期上下文
2.3.3 为什么「给 AI 10 万字代码」是个幻觉
很多人天真地以为:上下文窗口是 20 万 Token,那我可以一次性给 AI 看 10 万行代码,让它帮我分析。
这是一个严重的误解。
10 万行代码的 Token 消耗:
平均每行代码:约 30 Token
10 万行 × 30 Token = 3,000,000 Token
20 万 Token 的上下文窗口
问题:10 万行代码就已经超过了 20 万 Token 的上限!
而且:
├─ 10 万行代码 ≈ 3M Token
├─ 你的问题 ≈ 500 Token
├─ AI 的思考过程 ≈ 未知(可能 50K+)
├─ AI 的回答 ≈ 未知(可能 10K+)
└─ 总计:远超 20 万 Token 上限
结论:你永远不可能一次性给 AI 完整的 10 万行代码。
///
PART 05
2.4 压缩机制:Prune + Summarize 的底层原理
2.4.1 AI 的两种「失忆」模式
当上下文窗口快满时,AI 有两种主要的应对策略:
┌─────────────────────────────────────────────────┐
│ 上下文压缩策略 │
├─────────────────────┬───────────────────────────┤
│ Prune(剪枝) │ Summarize(摘要) │
│ │ │
│ 保留最近的内容 │ 把旧内容压缩成摘要 │
│ 丢弃更早的内容 │ 用更少的 Token 表达 │
│ │ │
│ 「我记不清了」 │ 「我记得大概是这样的」 │
└─────────────────────┴───────────────────────────┘
2.4.2 Prune(剪枝):直接丢弃
Prune 的工作原理:
原始上下文(时间顺序):
[第1分钟] → [第2分钟] → [第3分钟] → [第4分钟] → [第5分钟]
500T 500T 500T 500T 500T
─────────────────────────────────────────────────────
总计:2,500 Token
Prune 后(保留最近的):
[第3分钟] → [第4分钟] → [第5分钟]
500T 500T 500T
─────────────────────────────
总计:1,500 Token(压缩了 40%)
Prune 的特点:
- 简单粗暴,直接丢弃旧内容
- 优点:速度快,几乎无额外成本
- 缺点:可能丢失关键信息(比如第 1 分钟提到的变量名,在第 5 分钟仍然需要)
2.4.3 Summarize(摘要):压缩提炼
Summarize 的工作原理:
原始上下文(时间顺序):
[第1分钟] → [第2分钟] → [第3分钟] → [第4分钟] → [第5分钟]
500T 500T 500T 500T 500T
─────────────────────────────────────────────────────
总计:2,500 Token
Summarize 后:
┌─────────────────────────────────────┐
│ [摘要:用户讨论了一个用户认证系统, │
│ 包括登录、注册、密码重置功能。 │
│ 技术栈:Express.js + PostgreSQL。] │
│ │
│ ≈ 80 Token │
└─────────────────────────────────────┘
↓
↓ 合并
↓
[摘要] + [第4分钟] + [第5分钟]
80T 500T 500T
─────────────────────────────
总计:1,080 Token(压缩了 57%)
Summarize 的特点:
- 智能压缩,保留核心信息
- 优点:信息密度高,不容易丢失关键上下文
- 缺点:需要额外的 AI 调用来生成摘要(有成本)
2.4.4 两种策略的实际效果对比
原始对话(约 2,500 Token):
「我的项目用的是 Express.js,用户数据存在 PostgreSQL。」
「密码要 bcrypt 加密。」
「登录用 JWT token。」
「注册需要邮箱验证。」
「帮我实现用户认证模块。」
Prune 后(可能丢失早期信息):
[丢失了 PostgreSQL 和 bcrypt 的描述]
「帮我实现用户认证模块。」
Summarize 后(保留核心):
[摘要:技术栈 Express.js + PostgreSQL,密码用 bcrypt,登录用 JWT,需要邮箱验证]
「帮我实现用户认证模块。」
结果:Summarize 的版本更可能生成正确的代码!
///
PART 06
2.5 Context Mode 的 98% 压缩原理
2.5.1 原始工具输出的代价
在 AI Coding Agent 中,工具输出是上下文消耗的大户:
典型工具输出的 Token 消耗:
Playwright 页面快照:56 KB ≈ 14,000 Token
20 个 GitHub Issues:59 KB ≈ 14,750 Token
1 个访问日志:45 KB ≈ 11,250 Token
30 分钟后的状态:
- 40% 的上下文窗口被工具输出消耗
- 真正的「对话」内容反而被挤压
- AI 开始「遗忘」你正在修改的文件
2.5.2 Context Mode 的解决方案
Context Mode 的核心创新:沙箱化工具输出。
传统模式(直接放入上下文):
┌─────────────────────────────────────────┐
│ 原始工具输出:56 KB (14,000 Token) │
│ → 直接放入上下文窗口 │
│ → 占用大量空间 │
└─────────────────────────────────────────┘
Context Mode(沙箱化):
┌─────────────────────────────────────────┐
│ 原始工具输出:56 KB │
│ → 存入外部沙箱(SQLite) │
│ → 上下文只放引用:~200 Token │
│ → 节省:14,000 - 200 = 13,800 Token │
│ → 压缩率:98.6% │
└─────────────────────────────────────────┘
2.5.3 沙箱 vs 原始输出的对比
场景:使用 Playwright 读取一个网页
原始模式:
┌─────────────────────────────────────────┐
│ 工具输出(56 KB): │
│ ┌─────────────────────────────────┐ │
│ │ HTML 标签、样式、脚本... │ │
│ │ 全部原始内容 │ │
│ │ │ │
│ │ 56 KB = 14,000 Token │ │
│ │ 每次快照都消耗这么多 │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
Context Mode:
┌─────────────────────────────────────────┐
│ 工具输出(56 KB): │
│ ┌─────────────────────────────────┐ │
│ │ 存入 SQLite 数据库 │ │
│ │ 生成唯一引用 ID │ │
│ └─────────────────────────────────┘ │
│ │
│ 上下文引用(200 Token): │
│ ┌─────────────────────────────────┐ │
│ │ [ctx_123] 页面快照已保存 │ │
│ │ URL: https://example.com │ │
│ │ 标题: Example Page │ │
│ │ 元素数: 156 │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
Token 节省:14,000 → 200 = 节省 98.6%
2.5.4 上下文模式的核心功能
| 功能 | 效果 | 适用场景 |
|---|---|---|
| Context Saving | 98% 压缩工具输出 | 大量文件读取、日志分析 |
| Session Continuity | SQLite + BM25 检索 | 断点续接、跨会话搜索 |
| Think in Code | LLM 生成脚本执行 | 大批量文件分析 |
| Output Compression | 65-75% token 节省 | 技术内容精简 |
///
PART 07
2.6 为什么让 AI 一次性看完 10 万字是个幻觉
2.6.1 数学永远不会骗人
让我们做一个简单的数学题:
假设:
- 上下文窗口:200,000 Token
- 每行代码平均:30 Token
- 代码文件大小:10 万行
计算:
10 万行 × 30 Token = 3,000,000 Token
问题:
3,000,000 Token >> 200,000 Token
结论:
10 万行代码需要 15 个「上下文窗口」才能装下!
2.6.2 实际操作中的其他消耗
即使你能把 10 万行代码塞进去,还有其他消耗:
完整分析还需要:
├─ 系统提示词:3,000 Token
├─ 你的问题描述:500 Token
├─ AI 的思考过程:未知(可能 50K+)
├─ AI 的回答:未知(可能 10K+)
└─ 其他上下文:可能 20K+
总计:远超 200,000 Token 上限
2.6.3 正确的做法:分而治之
面对大型代码库的正确策略:
❌ 错误做法:
「帮我分析这 10 万行代码库」
✅ 正确做法:
Step 1:让 AI 先了解整体结构
「帮我了解这个项目的目录结构和主要模块」
Step 2:聚焦具体模块
「帮我详细分析 src/auth 目录下的代码」
Step 3:深入具体文件
「这个 login.js 文件的实现逻辑是什么?」
Step 4:针对具体问题
「帮我找出这个函数里的 bug」
分而治之的原理:
一次只处理一个「窗口大小」的内容
├─ 第 1 个窗口:项目概览
├─ 第 2 个窗口:auth 模块
├─ 第 3 个窗口:login.js
├─ 第 4 个窗口:具体函数
└─ ...
每个窗口都保持在 200K Token 以内
///
PART 08
2.7 实用技巧:在断点压缩,在里程碑存档
2.7.1 什么时候应该压缩?
压缩的最佳时机:
✅ 规划完成后
「我们已经确定了这个功能的设计方案,现在开始实现。」
└─ 方案已确定,不需要再回顾讨论过程
✅ 调试完成后
「Bug 已修复,原因是没有处理空值。现在继续新功能。」
└─ Bug 修复过程不需要保留
✅ 里程碑完成后
「用户认证模块完成了,接下来做权限管理。」
└─ 阶段性总结比过程更重要
✅ 重大上下文切换前
「刚才在做后端 API,现在开始做前端页面。」
└─ 两种上下文关联性不强,可以分开
不该压缩的时机:
❌ 实现过程中
「我正在实现这个函数,遇到一个类型错误...」
└─ 调试过程需要上下文
❌ 多个相关任务未完成
「我还在解决这个模块的 5 个文件...」
└─ 它们是连贯的,压缩会丢失关联
❌ 复杂 Bug 排查中
「我正在追踪这个 bug 的根因...」
└─ 排查路径可能需要回溯
2.7.2 如何判断上下文消耗?
检查上下文消耗的方法:
命令:/cost
├─ 显示当前会话的总 Token 消耗
├─ 估算已用百分比
└─ 给出优化建议
经验法则:
├─ 0-50%:轻松,任意操作
├─ 50-70%:正常,注意压缩
├─ 70-85%:警戒,开始精简
├─ 85-95%:危险,必须压缩
└─ 95%+:危急,可能丢失信息
2.7.3 上下文管理的三大原则
原则 1:Token 经济
├─ 用对模型:简单任务用 Haiku,复杂推理用 Opus
├─ 用对时机:深度思考用 Sonnet,快速执行用 Haiku
└─ 善用子 Agent:用子 Agent 做探索,保护主上下文
原则 2:上下文管理
├─ 在断点压缩:规划后、调试后、里程碑后
├─ 在里程碑存档:重要的阶段产物保存到文件
└─ 避免信息冗余:不要重复同样的背景描述
原则 3:安全边界
├─ 沙箱隔离:敏感操作在沙箱中执行
├─ 最小权限:Agent 访问限制在工作目录
└─ 定期清理:无关会话及时关闭
///
PART 09
2.8 本章小结
核心知识点
┌─────────────────────────────────────────────────────────┐
│ 第2章 知识要点 │
├─────────────────────────────────────────────────────────┤
│ ✅ AI 的「记忆」= 上下文窗口,有固定容量限制 │
│ ✅ Token = AI 处理文本的基本单位,按量计费 │
│ ✅ 主流模型上下文窗口:10 万到 200 万 Token │
│ ✅ 压缩机制:Prune(丢弃)+ Summarize(摘要) │
│ ✅ Context Mode 实现 98% 压缩(沙箱化工具输出) │
│ ✅ 10 万行代码需要 15 个上下文窗口才能装下 │
│ ✅ 压缩时机:规划后、调试后、里程碑后 │
└─────────────────────────────────────────────────────────┘
关键术语
| 术语 | 定义 |
|---|---|
| Context Window | 上下文窗口,AI 一次能处理的最大信息量 |
| Token | AI 处理文本的基本单位,可理解为「一口」 |
| Prune | 剪枝策略,直接丢弃旧内容 |
| Summarize | 摘要策略,把旧内容压缩成摘要 |
| Context Mode | 沙箱化工具输出的上下文优化方案 |
| 98% 压缩 | Context Mode 将工具输出从 56KB 压缩到 200 Token |
行动建议
立即行动(5 分钟):
1. 检查当前会话的 Token 消耗:
输入 /cost 查看已用比例
2. 实践压缩:
当你完成一个阶段性任务后,输入 /compact 压缩上下文
3. 用子 Agent 做探索:
当需要分析大量文件时,使用 @Explore Agent 而不是直接读取
下一章预告:
>
///
PART 10
附录:上下文窗口自测问卷
测一测你对上下文窗口的理解:
Q1:上下文窗口的类比,哪个最准确?
A. 电脑内存——越大越好,可以同时运行更多程序
B. 会议室——只能容纳一定人数,超出的听不到讨论
C. 硬盘——可以永久存储所有对话记录
D. 浏览器缓存——读取历史记录的速度
Q2:Token 和字的关系,正确的是?
A. 1 个 Token = 1 个汉字
B. 1 个 Token ≈ 0.75 个英文单词
C. Token 和字数没有关系
D. Token 只用于中文
Q3:以下哪个是压缩上下文的正确时机?
A. 正在实现一个复杂函数的过程中
B. 调试一个 bug 还没解决
C. 完成了功能开发,准备开始测试
D. 和 AI 进行了一个小时的闲聊
Q4:Context Mode 的 98% 压缩指的是?
A. 把 10 万行代码压缩到 2,000 行
B. 把工具输出从原始内容压缩到引用摘要
C. 把中文翻译成英文减少 Token
D. 把对话历史压缩成图片
参考答案: Q1=B、Q2=B、Q3=C、Q4=B
///
*本章完。第3章:三个时代划分——手写代码 → Copilot 辅助 → Vibe Coding*
THANKS FOR READING
🦐 龙虾 · OpenClaw 技术分享
夜雨聆风