目录

05什么是上下文窗口

什么是上下文窗口?LLM 的“工作记忆”有多大?

你一次能记住多少句话?10 句?50 句?还是一整本书? 对 LLM 来说,这个上限就叫上下文窗口


引言:一个“健忘”的天才

大语言模型能写诗、能编程、能陪你聊天。

但它有一个你意想不到的弱点:它是健忘的

不是那种“过了三天就忘”的健忘,而是过了某个长度就彻底看不见的那种健忘。

上下文窗口 = 模型一次能“看到”的最大 Token 数量。 超出这个窗口的内容,模型就像从来没读过一样——完全消失。

举个例子:

你:我叫张三,我是个程序员。
(中间聊了 100 页别的)
你:你还记得我叫什么吗?

如果模型的上文窗口只有 50 页,它早就忘了。 你敢让它写小说、总结长篇报告吗?——可能它写到后面,已经忘了开头写了什么。


1. 为什么会有上下文窗口?

不是为了“故意健忘”,而是因为技术限制

原因 1:Self-Attention 的计算复杂度是 O(n²)

还记得上一篇 Self-Attention 吗?

每个词要跟所有其他词算一遍相关性。 上下文长度 n 翻倍 → 计算量翻 4 倍。

上下文长度注意力计算对数量(≈ n²/2)
1K tokens50 万
10K tokens5000 万
100K tokens50 亿

窗口越长,计算成本爆炸式增长。

原因 2:内存和显存限制

每个 Token 都要在 GPU 显存中保存它的向量表示。 窗口 100K → 仅存储 Key/Value 就需要几十 GB 显存。

graph LR A["更长的窗口"] --> B["更多计算量"] A --> C["更多显存"] B --> D["更慢的推理"] C --> D D --> E["更高的成本"]

所以所有 LLM 都有一个硬上限——不是不想记,是算不起。


2. 不同模型的上下文窗口对比

窗口大小在过去两年增长极快:

模型上下文窗口发布年份
GPT-34K (~3000 个汉字)2020
LLaMA 12K2023
GPT-3.54K → 16K2023
GPT-48K → 32K → 128K2023
Claude 2100K2023
Claude 3200K2024
Gemini 1.5 Pro1M (100 万)2024
LLaMA 38K → 128K2024

1M Token 是什么概念? 《三体》三部曲总共约 80 万字 ≈ 100 万 Token。 你可以把整部《三体》一次性喂给模型,然后问它“罗辑在哪一章提出的黑暗森林理论?”


3. 两万米 vs 两百米:用跑步来理解窗口

想象你要跑一段路,路上有各种提示牌:

  • 小窗口 (2K):只能看到眼前 200 米。跑马拉松时,你完全忘了 10 公里前的路况。
  • 大窗口 (200K):能看到前方 20 公里。你能规划路线、记住关键信息。
graph LR subgraph "小窗口 (2K)" A["第1章"] -.->|超出窗口| B["第100章"] B --> C["模型看不到第1章"] end subgraph "大窗口 (200K)" D["第1章"] -->|仍在窗口内| E["第100章"] E --> F["模型还能看到第1章"] end

窗口越大,模型越能“从头到尾”理解长文本。


4. 上下文窗口里面到底有什么?

窗口里装的是 Token 序列——从第一句话到当前位置的所有内容。

graph TD A["用户: 我叫张三"] --> Window["上下文窗口"] B["助手: 你好张三"] --> Window C["用户: 我是程序员"] --> Window D["用户: 我住在北京"] --> Window E["助手: 北京最近天气..."] --> Window F["用户: 你还记得我叫什么吗?"] --> Window Window --> G["模型看到: 完整的对话历史"]

注意:窗口包括用户输入 + 模型输出 + 系统提示词。 所以长对话会不断“吃掉”窗口空间。

一个容易被忽略的点

你给模型的那一大段文本(比如 5000 字的 PDF),模型的回复也会加入窗口。 如果对话太长,最初的 PDF 内容可能会被挤出窗口

这就是为什么长对话后,模型会“忘记”你最开始给它的文档。


5. 窗口满了怎么办?——三种常见的处理方式

方式 1:直接截断(最粗暴)

只保留窗口末尾的最新 Token,前面的全部丢掉。

优点:简单 缺点:丢失关键信息

方式 2:滑动窗口注意力

每个 Token 只关注它附近的 Token(比如前后 4K),而不是整个 128K。

优点:计算量可控 缺点:两端的 Token 无法直接交互

graph LR A["Token 5000"] -->|只能看到| B["Token 3000-7000"] C["Token 10000"] -->|只能看到| D["Token 8000-12000"] B -.->|看不到| D

方式 3:摘要 + 重写(最智能)

把窗口里的旧内容压缩成摘要,然后继续对话。

ChatGPT 的“长对话记忆”功能就是这样:

graph LR A["前 50 轮对话"] --> B["模型自动生成摘要"] B --> C["摘要占 500 Token"] C --> D["继续新对话"]

6. 上下文窗口不是越大越好——三个代价

  1. 推理延迟变高 窗口越大,生成每个 Token 时看的 Token 越多,速度越慢。
  2. 成本更高 很多 API 按输入 Token 数收费。100K 的输入比 10K 贵 10 倍。
  3. “中间遗忘”现象 OpenAI 的研究发现:即使窗口能装下全文,模型对中间部分的 recall 准确率远低于开头和结尾。
graph LR A[开头<br/>高准确率] --> B[中间<br/>低准确率] --> C[结尾<br/>高准确率] style B fill:#ffcccc

有趣的发现: 模型像人类一样,对一段话的开头和结尾印象更深,中间容易忽略。


7. 不同场景需要的窗口大小

场景建议窗口说明
日常聊天8K正常人对话不会超过几千字
RAG(检索增强)4K~8K检索出的片段 + 用户问题
代码生成16K+需要看到整个文件
长文档摘要100K+一次性读完整篇论文/报告
长篇小说分析200K+《三体》级别
多轮复杂对话16K~32K开发 Agent 时需要历史

8. 一张图总结:上下文窗口是什么

flowchart TD A["用户输入"] --> B["当前对话/文本"] B --> C["上下文窗口<br/>(长度上限 L)"] C --> D{"序列长度 > L ?"} D -- 是 --> E["超出部分被丢弃<br/>或移动到摘要中"] D -- 否 --> F["模型看到全部内容"] E --> F F --> G["生成下一个 Token"] G --> H["新 Token 加入窗口末尾"] H --> B

9. 实用建议:如何用好模型的窗口?

对普通用户

  • 长文档:尽量放在对话最开始,而不是聊到一半再塞进去
  • 重要信息:在提问时重复一遍(比如“按照我开头给你的那个 PDF……”)
  • 分治法:把超长文档拆成多段,分别问

对开发者

  • 分段 + 滑动:用 LangChain 的 MapReduce / Refine 模式
  • 优先用 RAG 而不是塞满整个窗口
  • 监控 Token 使用量(tiktoken 库可以帮你数)

写在最后

上下文窗口本质上是效率与能力之间的权衡

更大的窗口 = 更强的长文本理解能力 + 更高的计算成本 + 更慢的速度

也许不久的将来,“窗口”这个概念会消失—— 那时候的模型,可能真的能记住和你聊过的每一句话