Token 与上下文窗口:理解 AI 模型的「记忆」与限制

Token 与上下文窗口:理解 AI 模型的「记忆」与限制

一、为什么 Token 是你必须理解的概念

如果你只用 AI 编程工具做简单的代码补全(Tab 补全),那你可能不需要太关心 Token 是什么。但如果你想要:

  • 让 AI 理解和修改一整个文件
  • 让 AI 跨多个文件做重构
  • 编写精确的 Prompt 来控制 AI 输出
  • 理解为什么 AI 有时会"忘记"你之前说的话

那你就必须理解 Token 和上下文窗口这两个核心概念。

在我使用 AI 编程的早期,遇到过一个让我困惑的问题:我给 Claude 贴了一个 1500 行的代码文件,然后在对话中讨论了前面几个函数的优化方案。但当我让它修改文件末尾的一个函数时,它好像"不记得"这个函数的内容了------它的修改建议明显是错误的。

后来我才明白,这不是 AI 的 Bug,而是上下文窗口的特性。当你理解了 Token 和上下文窗口的机制后,这种问题就是完全可以预判和避免的。

二、什么是 Token------AI 的"原子单位"

2.1 Token 的定义

Token(词元)是大语言模型理解和生成文本的最小单位。类比一下:

  • 英语中的"字母"是最小书写单位,但人类不会一个字母一个字母地读------我们会把字母组合成"词"
  • Token 就是 AI 的"词"------AI 不一个一个字符地读,也不一个一个单词地读,而是把文本切分为一定大小的"Token块"

2.2 Tokenization 的工作机制

文本转为 Token 的过程叫做 Tokenization(分词)。目前主流模型(GPT、Claude)使用的是一种叫 BPE(Byte Pair Encoding)的算法。

BPE 的工作方式是:从字符级别开始,统计最常见的"字符对",将它们合并为一个新的 Token。反复执行这个过程,直到达到预设的词汇表大小。

让我们看一个具体的例子:

复制代码
原始文本: "const userName = 'hello world';"

BPE Tokenization 过程(简化示意):
Step 1: 先按常见编程符号拆分
["const", " ", "user", "Name", " ", "=", " ", "'", "hello", " ", "world", "'", ";"]

Step 2: 高频组合合并
"user" + "Name" 经常一起出现 → 作为一个 Token
"hello" + " " + "world" → 由于"hello world"是高频短语,"hello"和"world"可能各为一个Token

最终 Token 序列(近似):
["const", " ", "userName", " ", "=", " ", "'", "hello", " ", "world", "'", ";"]
约 12 个 Token

2.3 英文 vs 中文的 Token 消耗差异

这是一个很多中文开发者没意识到的"隐性成本"。不同语言的 Token 效率差异很大:

英文的 Token 效率

复制代码
文本: "The quick brown fox jumps over the lazy dog"
Token 数: ~10
比例: 1个单词 ≈ 1.2 个 Token

中文的 Token 效率

复制代码
文本: "快速的棕色狐狸跳过了懒惰的狗"
Token 数: ~15-20
比例: 1个汉字 ≈ 1.5-2 个 Token

代码的 Token 效率

复制代码
Python: def calculate_sum(a, b): return a + b
Token 数: ~12

中文注释: # 这个函数用来计算两个数的和
Token 数: ~15-20(比代码本身还多!)

📊 各语言 Token 消耗对比表(以表达相同语义为准):

语言 相对 Token 消耗 说明
英文 1x(基准) 拉丁字母与BPE天然契合
中文 1.5-2x 每个汉字通常占1-2个Token
日文/韩文 1.5-2.5x 类似中文,字符集大
代码(英文关键词) 0.8-1.2x 常见关键字和模式Token化效率高
代码(含中文注释) 1.2-1.8x 中文注释增加额外消耗

💡 实用建议:如果使用按 Token 计费的 API(如 GPT-4 API、Claude API),用英文 Prompt 性价比更高。中文 Prompt 的效果可能同样好(甚至在某些情境下更好),但 Token 消耗明显更大。

2.4 代码的 Tokenization 示例

让我们看看一段实际的 JavaScript 代码是如何被 Token 化的:

javascript 复制代码
// 源代码
function calculateDiscount(price, userLevel) {
  if (userLevel === 'vip') {
    return price * 0.8;
  }
  return price;
}

// 大致的 Token 分解(GPT-3.5/4 的 Tokenizer)
// "function" → 1 Token(高频关键字)
// " " → 1 Token
// "calculate" → 1 Token
// "Discount" → 1 Token
// "(" → 1 Token
// "price" → 1 Token
// "," → 1 Token
// " " → 1 Token
// "user" → 1 Token
// "Level" → 1 Token
// ")" → 1 Token
// " " → 1 Token
// "{" → 1 Token
// "\n  " → 1 Token
// "if" → 1 Token
// 依此类推...

// 总计约 30-35 个 Token

💡 高频出现的关键字(functionifreturn)、常见变量名、常用模式(=> 箭头函数)在 Token 表中有自己的"专属位置",通常一个 Token 就够了。

三、上下文窗口------AI 的"工作记忆"

3.1 上下文窗口的概念

上下文窗口(Context Window)是模型在一次推理中能"看到"的 Token 最大数量。它决定了 AI 的"视野范围"。

用一个类比来理解:上下文窗口就像你在一个白板上写字。白板的大小是固定的------当白板写满后,你若要写新内容,就必须擦掉一些旧内容。同样,当 Token 数量超出上下文窗口后,模型就会"忘记"最早的内容。

复制代码
上下文窗口示意图:

[最早的内容] ... [中间的内容] ... [最新的内容]
|<-------------- 上下文窗口 --------------->|

超出窗口的内容会被"截断"------模型完全看不到了

3.2 上下文窗口的历史演进

上下文窗口的增长速度是 AI 进步最显眼的指标之一:

时间 模型 上下文窗口 约等于
2018 GPT-1 512 一段话
2019 GPT-2 1,024 一页文字
2020 GPT-3 2,048 一篇短文
2022 GPT-3.5 4,096 一篇长文
2023 GPT-4 8,192 一个章节
2023 GPT-4 Turbo 128,000 一本小说
2024 Claude 3 200,000 300页的书
2024 Gemini 1.5 Pro 1,000,000 一部《战争与和平》

从 512 到 1,000,000------增长近 2000 倍,仅用了 6 年时间。这个速度甚至超过了摩尔定律。

3.3 200K Token 意味着什么

Claude 3 的 200K Token 上下文窗口,对编程来说意味着:

复制代码
≈ 150,000 个英文单词
≈ 300 页的技术文档
≈ 50,000-80,000 行代码(取决于语言和注释密度)
≈ 可以一次性放入以下内容:
  - 一个中型 Next.js 项目的所有源文件
  - React 官方文档 + Express.js 文档 + Prisma 文档
  - 整个项目的 package.json + tsconfig + 所有组件的完整代码

3.4 "近因效应"------不是所有 Token 都同等重要

虽然模型有大的上下文窗口,但研究表明:模型"注意"得最多的是靠近末尾的内容。这被称为"近因效应"(Recency Bias)或"Lost in the Middle"现象。

复制代码
上下文中各部分的"注意权重"分布(示意):

高权重:开头部分("首因效应")
中低权重:中间部分("Lost in the Middle")
最高权重:结尾部分("近因效应")

建议:把最重要的信息放在开头或结尾,不要让核心指令"沉"在中间

💡 实用建议

  • 将核心指令和约束放在 Prompt 的最后(最新位置)
  • 将背景信息和示例放在 Prompt 的前部
  • 在长对话中,定期重申关键要求
  • 对于特别重要的约束,在对话的各个环节反复强调

四、上下文窗口对编程的影响

4.1 单文件代码理解

当你让 AI 理解一个代码文件时,首先需要确保整个文件的内容能放进上下文窗口。

复制代码
一个 1000 行的 JavaScript 文件 ≈ 10,000-15,000 Token
→ 在 GPT-4(8K)中放不下 → 在 GPT-4 Turbo(128K)和 Claude 3(200K)中完全没问题

4.2 多文件代码修改

这是上下文窗口最能体现差异的场景。假设你要做一个涉及 5 个文件的修改:

复制代码
文件1(页面组件): 200 行 ≈ 2,500 Token
文件2(API路由): 150 行 ≈ 1,800 Token
文件3(数据模型): 100 行 ≈ 1,200 Token
文件4(类型定义): 80 行 ≈ 1,000 Token
文件5(工具函数): 120 行 ≈ 1,500 Token
对话历史 + Prompt + AI响应: ≈ 4,000 Token

总计: ~12,000 Token

这个总数在 8K 的窗口(GPT-4)中已经很拥挤了------可能放不下完整的 5 个文件加上充分的对话讨论。但在 128K(GPT-4 Turbo)和 200K(Claude 3)中,还有大量空间可以添加相关文档、API 规范等额外上下文。

4.3 长对话的"记忆丧失"

当你与 AI 进行长时间的多轮对话时,早期交换的信息会逐渐被"推"出上下文窗口。

复制代码
第 1 轮对话:讨论项目架构(占 5,000 Token)
第 2 轮对话:讨论数据库设计(占 8,000 Token)
第 3 轮对话:开始写代码(累计 13,000 Token)
...
第 10 轮对话:修改 bug(累计 35,000 Token)

此时,第 1 轮讨论的架构细节可能在 GPT-4(8K)中完全消失了,
只在 GPT-4 Turbo 和 Claude 3 中还能被"记住"。

⚠️ 这就是我在文章开头提到的那个问题的原因------当我把 1500 行代码放进会话,经过多轮讨论后,文件末尾的内容虽然一开始在上下文中,但随着新内容的不断加入,AI 对较早位置的"注意力"减弱了。

五、高效管理 Token 的实用策略

5.1 文件拆分策略

不要把一个 3000 行的文件直接丢给 AI。相反,采用"分层递进"策略:

复制代码
步骤①:给 AI 项目的骨架
"这是我的项目结构:[目录树]
我要修改 [具体功能] 模块,请先帮我理解相关的文件。"

步骤②:给 AI 关键部分
"这是 [具体文件] 的核心部分(前 200 行),请分析..."

步骤③:选择性提供上下文
"这是和当前修改相关的 [类型定义/接口/配置],请参考..."

步骤④:总结代替完整代码
"文件中剩余的 800 行是 [功能描述],如果你需要某部分的具体代码,请告诉我。"

5.2 选择性上下文(Selective Context)

给 AI 的上下文不是"越多越好",而是"越相关越好":

❌ 不好的做法:

复制代码
把整个项目的 50 个文件全部放进 Prompt
→ 浪费 Token,AI 反而可能被无关信息干扰

✅ 好的做法:

复制代码
只放与当前任务直接相关的文件:
- 正在修改的文件
- 被修改文件的依赖(它 import 了什么)
- 类型定义和接口
- 相关的配置文件

5.3 Prompt 压缩技巧

一些减少 Token 消耗的实用技巧:

去掉不必要的空白和注释(仅在你发送给 AI 的代码中):

javascript 复制代码
// 原始(包含格式化空白和开发注释)
function getUserById(id) {
  // 查询用户信息
  const user = await db.user.findUnique({  // Prisma 查询
    where: { id: id },
    include: { profile: true }
  });

  return user;
}

// 压缩后(去掉注释和多余空白,AI 仍然能理解)
function getUserById(id) {
  const user = await db.user.findUnique({
    where: { id },
    include: { profile: true }
  });
  return user;
}

用简洁的描述替代完整的文件内容

复制代码
"项目的 ESLint 配置是标准配置 + React plugin + TypeScript plugin"
(而不是粘贴整个 .eslintrc.json 文件)

在大文件场景中,用 // ... (略) 标记省略部分

javascript 复制代码
function firstFunction() { /* ... */ }
function secondFunction() { /* ... */ }
// ... (此处省略 500 行业务逻辑函数)

// 以下是要修改的核心部分:
function processOrder(order) {
  // 这个函数有 150 行
  // ...
}

5.4 "分而治之"策略

对于大型任务,不要试图在一个对话中完成所有工作:

复制代码
# 错误做法:一个长对话处理一切
对话1(Token 0 → 50K):讨论需求 → 设计架构 → 生成所有代码 → 修改 → 测试
→ 后期 AI 的"记忆"已经严重过载

# 正确做法:分阶段、分对话
对话1(Token 0 → 15K):需求分析和架构设计 → 输出:设计文档
对话2(Token 0 → 20K):基于设计文档,实现模块 A → 完成并测试
对话3(Token 0 → 20K):基于设计文档,实现模块 B → 完成并测试
对话4(Token 0 → 10K):集成测试和问题修复
→ 每个对话都有充足的上下文空间

5.5 利用工具自动管理上下文

一些工具已经内置了智能的上下文管理:

  • Claude Code:自动选择相关文件放入上下文,而非全部文件
  • Cursor:通过 .cursorrules 和项目索引来优选上下文
  • GitHub Copilot:分析最近查看和编辑的文件,自动构建上下文

💡 经验法则:让工具帮你管理上下文,你只需要关注"当前这个对话中聊什么"。

六、常见 Token 管理错误与避免方法

错误一:把所有文件都放进 Prompt

复制代码
错误示范:
"我有以下文件:[粘贴了10个文件,总计5000行代码]。
帮我给所有文件的函数加错误处理。"

问题:AI 被过多的信息淹没,可能漏掉某些文件或做出不准确的修改。

✅ 改进方法:分文件逐个处理,并在需求中明确具体文件。

错误二:忽视 Token 消耗的"隐形大户"

复制代码
错误示范:
在 Prompt 中粘贴了一个 200 行的 JSON 配置文件(包含了 AI 不需要知道的
所有细节),而这个文件的"精华"信息其实只有 5 行。

✅ 改进方法:提取关键信息,而非全量粘贴。对于 JSON 配置,只给出结构或关键字段。

错误三:在长对话中依赖 AI "记住"所有内容

复制代码
错误示范:
第 1 轮:我告诉 AI 使用 async/await 风格
...(50 轮对话后)
第 51 轮:我让 AI 写一个新函数,期望它还记得 async/await 的偏好
→ AI "忘了",因为它已经被推出上下文窗口

✅ 改进方法:在关键指令被"遗忘"前,主动重申。或在工具层面设置(如 CLAUDE.md 中的规范会在每次对话开始时重新加载)。

错误四:中文 Prompt 中不必要的啰嗦

复制代码
错误示范:
"请帮我写一个能够处理用户登录请求的 Express.js 路由处理函数,
这个函数需要接受用户名和密码两个参数,然后..."

Token 数:~100(中文)+ 代码

改进版:
"写 Express.js 登录路由:接收 username + password,JWT 认证,bcrypt 加密"
Token 数:~30(中文+英文混排)+ 代码

✅ 改进方法:Prompt 中使用简洁的关键词 + 英文技术术语(API、框架名等),减少 Token 浪费。

七、总结

Token 和上下文窗口是大语言模型最基础的"物理限制",理解它们就像理解计算机的内存和硬盘------你不需要成为硬件专家,但了解基本概念能在你编程时做出更好的决策。

核心要点:

  • ✅ Token 是 AI 处理文本的最小单位,中英文的 Token 效率不同
  • ✅ 上下文窗口决定了 AI 一次能"看到"多少内容
  • ✅ 模型对靠近末尾的内容"注意"得更多(近因效应)
  • ✅ 大型上下文窗口(128K+)让理解整个项目成为可能
  • ✅ 高效管理上下文的关键是:选择性提供信息 + 分层递进 + 工具辅助
  • ✅ 避免常见错误:信息过载、忽视隐形 Token 消耗、依赖 AI 的长时记忆

掌握了 Token 和上下文窗口的知识,你就理解了为什么有时候 AI 的"记忆"好像不稳定------这不是 Bug,而是机制。下一章我们将探讨 AI 编程的三种核心模式。


下一篇:AI 编程的三种模式:代码补全、对话生成与智能体自动编程

相关推荐
Dovis(誓平步青云)1 小时前
《精讲Spring Boot后端跑另一个端口:如何解决暴露服务器问题》
服务器·人工智能·spring boot·后端·生成对抗网络
chase_my_dream1 小时前
2D-SLAM 真实数据处理与多传感器工程落地:时间同步、异常过滤、标定对齐和系统调试
c++·人工智能·2d-slam
不爱记笔记1 小时前
GPT-5.6 Sol 真实项目实测!Bug修复、UI重构与帆船游戏复刻
人工智能·gpt·ui·chatgpt·bug·openai
zhojiew1 小时前
在 OCManager 中通过 OCAI 启用 ops-mate 打通 AI 诊断路径
人工智能
慕容引刀1 小时前
告别Commit信息纠结:使用Git AI Commit插件实现规范化提交
人工智能·git·github·visual studio code·visual studio
QiLinkOS1 小时前
企业知识产权战略的“X光”透视报告:从“外包代工”到“法律军火库”的终极分野
大数据·人工智能·dna双螺旋归因模型·技术专利避坑指南·qilink·技术专利风险情报·技术专利洞察
风途科技~1 小时前
河道流量监测不用下水!雷达水流测速仪非接触测流更安全
人工智能·安全
weixin_397574091 小时前
企业认知基础设施是什么
人工智能
开发者小布1 小时前
AI 开发工具生态扫盲:中转平台、Cursor、Claude Code 如何协同
人工智能