上下文窗口与「记忆」:为什么它记不住
窗口是工作台,不是脑子
上下文窗口是模型这一次能同时看到的全部文字:你的问题、之前的对话、塞进去的资料、它要写的回答,全都算在内。超过这个范围的内容对它不存在——不是「忘了」,是根本没进房间。
关键事实:模型没有跨请求的持久状态。 每次请求都是全新的;所谓「连续对话」,是程序把历史重新拼回上下文再发一遍。窗口满了,最早的内容就被丢掉。
窗口是怎么被占掉的
一个典型请求的预算大致这样分配:
| 部分 | 常见占比 | 备注 |
|---|---|---|
| 系统提示 / 规则 | 小但固定 | 每次都要重发 |
| 对话历史 | 随轮次线性增长 | 最容易失控的部分 |
| 检索到的资料(RAG) | 一次可能占掉几分之一 | 塞得多不等于答得好 |
| 它要写的回答 | 预留 | 不预留就会被截断 |
所以「窗口有 128K」并不等于「能塞 128K 资料」:扣掉历史与输出,真正能用的常常少得多。
为什么窗口内的内容也会被忽略
两个机制,都属常识层面:
- 滑出:历史太长,早期内容被截掉。表现是「它忘了我一开始说的要求」。
- 注意力稀释:窗口越长,模型对其中每一部分的关注度越容易被摊薄,放在中间的内容比放在开头结尾的更容易被忽略。表现是「资料明明给了,它没用」。
结论很实际:重要约束要靠近提问重复,而不是只在第一轮说过。
三种「记忆」不是一回事
| 想要的效果 | 真实机制 | 谁负责 |
|---|---|---|
| 这次对话里记住前文 | 把历史重新塞进上下文 | 窗口大小 + 你的裁剪策略 |
| 回答时引用我的资料 | 检索后塞进上下文(RAG) | 检索质量 |
| 跨会话、跨设备记住偏好 | 存到外部数据库,下次拼回去 | 你的系统设计 |
模型本身不提供第三种。任何「它记住了我」的产品体验,背后都是外部存储在拼装上下文。
三个判断
- 抱怨「它记不住」之前,先确认那段内容这次有没有被发过去。
- 抱怨「它没看资料」之前,先确认资料位置对不对、是不是被历史挤掉了。
- 需要长期记忆 → 必须自己设计外部存储与检索,别指望模型。