对话与上下文 —— 为什么聊着聊着它就"忘了"
来源:ChatGPT 的对话形式来自 2022 年 RLHF 对齐训练
一句话:AI 的"对话"其实是每次都把全部历史重新发给模型,而模型的工作记忆(上下文窗口)有上限——这就是"忘了"的全部真相。
1. "对话"是假的,"接龙"是真的
你以为的对话:
你:你好 → AI:你好 → 你:我叫徐义杰 → AI:记住啦 → 你:我叫什么 → AI:徐义杰
模型实际经历的(API 视角):
第 1 次请求:[你:你好] → 生成"你好"
第 2 次请求:[你:你好,AI:你好,你:我叫徐义杰] → 生成"记住啦"
第 3 次请求:[…前 4 条全部…,你:我叫什么] → 生成"徐义杰"
关键事实:模型没有记忆。 每次请求都是独立的,"记得"只是因为你的程序把历史消息原样重发了一遍。你在网页里聊天时觉得它记性很好,是因为 ChatGPT 的后端帮你干了这个重发的活。
这也解释了 API 里那个 messages 数组——它不是"会话 ID",而是每次都要完整携带的记忆:
messages = [
{"role": "system", "content": "你是一个严谨的技术助手"}, # 人设,一直生效
{"role": "user", "content": "我叫徐义杰"},
{"role": "assistant", "content": "你好,义杰!"},
{"role": "user", "content": "我叫什么?"} # 新问题追加在末尾
]
2. 上下文窗口:有限的工作记忆
上下文窗口 = 一次请求能装下的最大 token 数。它像一个固定大小的白板:
[system 人设] + [历史对话...] + [新问题] + [留给回答的空间] ≤ 窗口上限
放不下了怎么办?程序只能扔掉最早的消息(或做压缩摘要)——于是"忘了"就发生了。这不是模型变笨,是白板擦掉了开头。
| 主流模型 | 窗口大小(大致) | 相当于 |
|---|---|---|
| 早期 GPT-3 | 4K tokens | 一篇短文 |
| 当前主流 | 128K tokens | 一本小书 |
| 长文本特化型 | 200K~1M | 一整套文档 |
3. 实用技巧:和"金鱼记忆"打交道
- 重要信息靠前不如靠后——离当前问题越近的内容,注意力权重通常越高
- 长对话主动让它总结:"把上面讨论的结论压缩成 5 条",然后用总结替换历史,省一大截 token
- system 里写死关键约束——人设、格式要求放 system,比在聊天里反复强调可靠
- 超长文档别硬塞——这是 RAG 的活(第 4 篇)
4. 和其他概念的区别
| 概念 | 回答的问题 |
|---|---|
| 上下文窗口(本篇) | 一次请求装得下多少 |
| 记忆(Memory) | 跨会话还认得你——靠程序把历史存数据库、下次再注入,不是模型自带 |
| RAG(第 4 篇) | 资料太多塞不下窗口 → 先检索再只塞相关的 |
| 微调 | 把知识"练进"参数里,不占窗口,但成本高、更新慢 |
一句话记忆点:模型没有记性,只有白板;窗口是白板的大小,记忆是程序替它抄笔记。
下一篇:模型只会说话、不会动手——它是怎么学会"调天气接口、查数据库"的?Function Calling 登场。