我最近跟 ChatGPT 聊了一下午,来回二十几轮。它突然管我叫“小明”——我明明叫“阿强”。那一刻我意识到,它不是记性不好,它是压根不记得我。这件事让我开始琢磨:AI 到底是怎么“记住”对话的?又为什么总会忘?

答案藏在一个叫上下文窗口的东西里。你每输入一句话,模型不是真的在跟你聊天,而是把你从对话开始到现在的所有文字打包成一个超长的文本块,重新读一遍,然后猜下一个字。这个能容纳的最大文本长度,就是上下文窗口。
比如 GPT-4 Turbo 的窗口是 128k tokens(约 10 万汉字),Claude 3 是 200k。窗口一旦塞满,模型就会把最早的内容直接截断扔掉——不是慢慢模糊,而是“啪”一下,永远消失。你之前说的名字、需求、背景,全都灰飞烟灭。
猜词游戏是怎么骗过你的?
要理解为什么窗口这么小气,得先看 Transformer 是怎么处理文字的。2017 年那篇著名的论文Attention Is All You Need引入了自注意力机制:模型让句子里的每个词都跟其他所有词两两“打招呼”,计算出一个“你对我有多重要”的分数。比如“银行”这个词,在看到“河”和“存款”时,注意力分数会完全不同,从而理解是“河边”还是“存钱”。
这个机制有个致命问题——计算量随长度平方级增长。你给模型 100 个词,它要算 100×100 = 10,000 次;给 1,000 个词,就是 1,000,000 次;给 10,000 个词,变成 1 亿次。显存和算力根本扛不住。所以,上下文窗口的大小本质上是成本与收益的妥协。
我最早以为,只要把窗口无限扩大不就完了?后来才想通,不仅算力不允许,连位置编码都会崩。
位置编码:模型怎么知道“我”在哪儿
Transformer 本身是“位置盲”——它同时看所有词,分不清谁先谁后。为了让模型知道顺序,原始论文给每个词加了一个正弦波位置信号。但这种方法有个毛病:训练时没见过那么长的序列,它根本不知道怎么外推。比如训练时只见过 2,048 长度的文本,你让它推理 4,096 长度,位置编码就乱了,模型会原地发疯。
后来出现了 RoPE(旋转位置编码)RoFormer: Enhanced Transformer with Rotary Position Embedding,通过旋转向量来编码相对位置,让位置信息只和相对距离有关,而不是绝对位置。这就像不记“第 5 个词”,只记“它前面 3 个词”。RoPE 让模型有能力外推到比训练时更长的序列,成为现在绝大多数大模型的基础。
但 RoPE 也只是缓解,不是根治。窗口一长,高频位置信息还是会衰减,导致模型对远距离依赖变弱。于是有人搞出了位置插值:把长序列的位置编码“压缩”回训练时的范围内,比如把 8k 的序列映射到 4k 的位置上,用少量微调就能让模型适应更长的上下文。这就是为什么 GPT-4 能从 8k 快速扩展到 128kGPT-4 Turbo。
窗口大了,模型就真的“看”得见吗?
答案令人沮丧:看得见,不代表用得上。2023 年一篇论文Lost in the Middle: How Language Models Use Long Contexts发现,当把重要信息放在长文本的开头或结尾时,模型答得很好;一旦放在中间,正确率断崖式下跌。就像你读一本 500 页的书,只记得前言和结语,中间全忘了。
这个现象揭示了上下文窗口的另一个残酷真相:模型对位置的注意力分布极度不均。开头的位置因为“首因效应”被记住,结尾因为“近因效应”被记住,中间则成了注意力黑洞。
| 信息位置 | 检索准确率(大致) | 原因 |
|---|---|---|
| 开头 (0-10%) | 高 | 首因效应,训练时开头常包含重要指令 |
| 中间 (10-90%) | 低,甚至接近随机 | 注意力分散,无特别位置偏置 |
| 结尾 (90-100%) | 最高 | 近因效应,最近的输入权重最大 |
所以,即使你用的模型标称 200k 窗口,也千万别把关键信息塞在对话中间——那无异于把便签贴在冰箱背面。
那怎么跟 AI 聊天才能让它记住?
既然知道了原理,就可以对症下药:
- 把最重要的信息放在最后一条消息。比如在提问前,先粘贴关键文档,然后立刻提问。模型会优先关注最近的输入。
- 定期“重置”上下文。长对话中,每隔几轮把还不能丢的关键信息重新总结一遍,放在新消息的开头或结尾,手动强化记忆。
- 用结构化提示把信息锁定在开头。比如 system prompt 里写“用户叫阿强,喜欢猫”,模型会一直带着,因为 system prompt 总是排在对话最前面,永远不会被挤出窗口。
- 别迷信超长窗口模型。200k 窗口听起来很厉害,但你得明白,它只是“允许你看 200k”,不保证你认真看了 200k。重要任务还是得靠 RAG(检索增强生成)把相关文档切碎,只把最相关的片段喂给模型,而不是把整本书塞进去。
有没有办法让模型不遗忘?
目前还没有完美的“无限记忆”。推理阶段的记忆扩展技术仍在探索中,比如 ALiBiTrain Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation 通过给注意力分数加一个线性偏置,让模型天然偏好近期信息,从而能外推到更长序列,但同样逃不过 Lost in the Middle。再比如 MemGPT 之类的项目试图用操作系统式分层记忆(主存、硬盘)来模拟长程记忆,但那是在应用层打补丁,不是模型本身的能力。
我最大的感受是:人类对 AI 记忆的期待,和 AI 实际的工作机制之间,有一道巨大的鸿沟。我们以为它像人一样,有个“记住”的动作,然后随着时间慢慢遗忘。实际上,它只是每次推理时读一遍历史记录,窗口限制就是那张纸的大小。纸被写满了,就得撕掉最上面的一行。
FAQ
为什么不能把上下文窗口无限扩大?
因为注意力计算复杂度 O(n²),显存和算力撑不住。即使硬件能撑住,位置编码也会失效,导致模型无法正确理解长距离依赖。而且扩大窗口后,模型在中间段的注意力会进一步稀释,能用的部分反而更少。
上下文窗口和参数量有什么关系?
没有直接关系。参数量决定模型的“知识容量”,窗口决定“一次能看多少字”。7B 模型也可以有 128k 窗口,但可能因为容量不足,长文本理解能力不如大模型。
“token”和“上下文窗口”里的 token 是什么?
token 是模型处理文本的最小单元,英文约 3/4 个单词,中文约 1-2 个字。上下文窗口限制的是 token 数量,不是字符数。所以同样字数的中文,消耗的 token 通常比英文少。
RAG 能解决遗忘问题吗?
RAG 不是让模型“记住”,而是把需要的信息从外部知识库检索出来,临时塞进上下文窗口。它绕开了窗口长度限制,但本质上还是依赖窗口内的临时记忆。如果检索到的文档太长,同样会触发 Lost in the Middle。
说到底,上下文窗口是当前大语言模型最根本的物理限制之一——它决定了模型能同时处理多少信息,也决定了你的对话能持续多久而不跑偏。理解它,不是为了原谅 AI 的健忘,而是为了学会绕过它的生理缺陷,让它在你需要的时候,恰好记得你。
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/150.html