乐于分享
好东西不私藏

AI超载 | 第2章:为什么 AI 总是「听不懂人话」?

AI超载 | 第2章:为什么 AI 总是「听不懂人话」?
章节关键词:上下文窗口、Token、记忆限制、上下文污染、鱼的记忆
章节字数: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 / 1M200K Token
Sonnet(均衡)$3.00 / 1M$15.00 / 1M200K Token
Opus(旗舰)$15.00 / 1M$75.00 / 1M200K 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 Saving98% 压缩工具输出大量文件读取、日志分析
Session ContinuitySQLite + BM25 检索断点续接、跨会话搜索
Think in CodeLLM 生成脚本执行大批量文件分析
Output Compression65-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 一次能处理的最大信息量
TokenAI 处理文本的基本单位,可理解为「一口」
Prune剪枝策略,直接丢弃旧内容
Summarize摘要策略,把旧内容压缩成摘要
Context Mode沙箱化工具输出的上下文优化方案
98% 压缩Context Mode 将工具输出从 56KB 压缩到 200 Token

行动建议

立即行动(5 分钟):

1. 检查当前会话的 Token 消耗:

   输入 /cost 查看已用比例

2. 实践压缩:

   当你完成一个阶段性任务后,输入 /compact 压缩上下文

3. 用子 Agent 做探索:

   当需要分析大量文件时,使用 @Explore Agent 而不是直接读取

下一章预告:

第3章:三个时代划分——手写代码 → Copilot 辅助 → Vibe Coding

>

理解了 AI 的局限性,下一章我们将站在历史的高度,俯瞰编程工具的进化历程。从 1960 年的手写代码,到 2021 年的 Copilot 辅助,再到 2025 年的 Vibe Coding——每一次变革都让更多人能够用代码解决问题。

///

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 技术分享