大模型的记忆和上下文有什么区别?为什么不能把历史一直塞进窗口?
简化版
上下文是某次模型前向真正可见的 token;产品“记忆”通常是应用在外部存储中保存、检索并按需注入上下文的信息。一直追加历史会挤占输出预算、增加 Prefill/KV 成本、放大过期冲突与隐私暴露,还可能触发中间信息利用下降。正确做法是将近期原文、结构化任务状态和经权限过滤的长期记忆分层管理。
详细版
基础模型权重里的知识不等于某个用户的会话记忆;一次无状态推理不会自动把新事实写回参数。短期上下文适合当前步骤与最近指代,结构化状态保存正在生效的目标和约束,长期记忆才保存未来可能复用的偏好或事实。
长期记忆必须有写入门槛、来源、版本、过期时间、检索策略和删除能力。读取时先做用户/租户权限过滤,再检查相关性、时效和冲突;写入时不能把模型猜测当成用户事实。历史消息可以摘要或外置,但关键数字、否定条件和未完成事项应保留可追溯来源。
完整版教学
判断边界:上下文决定模型“这一次能看到什么”,记忆系统决定应用“长期保存什么、何时取回、是否允许使用”。
一、先区分参数、上下文、状态与记忆
模型参数保存训练得到的统计知识;上下文是本次前向的可见 token;任务状态是当前仍生效的目标、约束和待办;长期记忆是跨请求保存、未来可能取回的信息。四者生命周期和可信度不同,不能都叫“模型记住了”。
基础推理调用通常可视为无状态计算;即使平台提供 Thread 或 Conversation API,持久化也是平台在模型调用之外管理消息或状态,再在后续调用时提供给模型。产品必须明确这层责任,而不能假设模型会自行永久保存。
二、核心机制怎么工作
LLM 每次生成只基于当前输入上下文和模型参数。产品里说的“记忆”通常是数据库、向量库或用户画像,在下一次请求前被检索出来放回上下文。它提升连续性,但也引入召回错误、隐私合规和冲突处理问题。
短期历史可直接保留,长历史要摘要,跨会话偏好需结构化存储并设置来源、置信度和过期时间。读取记忆前做权限与相关性过滤,写入前区分稳定事实和一次性表达,用户纠正时建立新版本而非悄悄覆盖审计记录。
三、带数字的拆解
一个客服会话积累了 60000 token 历史,但当前模型有效预算只有 16000 token。系统可以保留最近 3000 token、检索 5 条相关长期记忆、再加一段 800 token 摘要,而不是原样塞入全部对话。
可用上下文 = 窗口上限 - 系统提示 - 工具描述 - 当前问题 - 输出预算
记忆命中率 = 被正确检索的有用记忆数 / 应被使用的记忆数
历史压缩率 = 摘要 token 数 / 原始历史 token 数
四、流程图和工程落点
可以把它拆成下面这条链路来讲:
用户新请求
|
读取短期对话
|
检索长期记忆
|
冲突与权限过滤
|
拼装上下文
|
模型回答并按策略写回记忆
五、和相近方案怎么区分
| 概念 | 存放位置 | 生命周期 |
|---|---|---|
| 上下文 | 本次请求 token | 一次推理 |
| 权重知识 | 模型参数 | 训练后长期存在 |
| 长期记忆 | 外部存储 | 按产品策略保留 |
| 摘要历史 | 会话状态 | 随对话更新 |
六、上线或训练时最容易踩的坑
-
旧记忆可能过期,使用前要允许新信息覆盖旧信息。
-
不要把敏感信息默认写入长期记忆,尤其是身份、财务和健康数据。
-
把模型生成的推测写成用户事实会形成自我强化错误,写入必须要求明确证据或用户确认。
-
多租户检索键缺少 tenant/user 约束会造成跨用户记忆泄露,这是数据隔离问题而非 Prompt 问题。
七、冲突、过期与删除怎样处理
记忆条目至少应保存主体、事实、来源、写入时间、有效期和版本。新信息与旧信息冲突时,不能简单按向量相似度任选一条;应按可信来源、事件时间和用户确认决定当前值,并保留替代关系以便审计。
| 场景 | 正确处理 | 不应做法 |
|---|---|---|
| 用户纠正偏好 | 新建版本并让旧值失效 | 两个值同时注入 |
| 临时出差地点 | 设置短 TTL | 永久当作常住地 |
| 删除请求 | 清理主存、索引和派生缓存 | 只删展示层记录 |
| 模型推测 | 等待证据或用户确认 | 自动写成事实 |
删除还要验证后续检索确实不再返回,并处理备份和审计记录的合规边界。所谓“忘记”不是 Prompt 里写一句不要使用,而是存储、索引、缓存和下游副本都执行可验证的生命周期策略。
八、常见误区与追问
- 误区:模型聊过一次就会永久记住。 若应用没有把历史保存并在下次请求重新注入,模型不会跨 API 请求保留这段会话。
- 误区:把所有历史塞进上下文最可靠。 长历史会挤占预算、引入过期冲突并触发 lost-in-the-middle;应保留近期对话并检索相关记忆。
- 误区:向量检索出来的记忆一定相关。 相似度只表示表征接近,还要检查用户归属、时间有效性、事实来源与当前意图。
- 追问:长期记忆应该什么时候写入? 只写稳定、未来可复用且有明确来源的信息;临时情绪、模型猜测和敏感数据默认不自动持久化。
- 追问:如何处理用户要求删除记忆? 删除主存、向量索引和派生缓存,记录合规审计事件,并验证后续检索确实不再返回。
- 追问:记忆和 RAG 知识库有什么区别? 记忆通常面向用户或会话且可变,知识库面向组织事实和文档;二者都需检索,但权限、生命周期和权威性不同。
九、加强记忆
记住“上下文是桌面,记忆是档案柜”。回答前从档案柜取必要材料放到桌面,桌面大小有限,档案也要能更新和清理。
上下文是“这次模型看见什么”,记忆是“应用长期保存什么、何时再给模型看”。答题时沿写入、存储、检索、冲突、删除五个环节说明责任边界。
项目实战落地
项目里怎么做的
《AI智能客服与工单处理系统》的 AI 客服把「记住」和「带给模型」分成两件事:
- 存:全部落库。 每次会话一条
customer_chat_session,每条消息一行customer_chat_message,role取USER或ASSISTANT;AI 消息存的是经过安全过滤后的最终回答。 - 带:只取最近 8 条。 每次提问都按会话重新查历史,
HISTORY_LIMIT = 8,SQL 按id desc取 8 条,再在代码里反转成时间正序。 - 拼:作为文本放进提示词。 历史拼成「客户:…… / 智能客服:……」,和检索到的资料、本轮问题一起分别替换模板里的
{history}、{context}、{question};系统提示词另作一条系统消息发送。
// 带进提示词的历史对话条数。太少上下文不够,太多会把提示词撑得很长
private static final int HISTORY_LIMIT = 8;
模型本身不保存任何东西:每一轮请求里有哪些历史,完全由这次查库的结果决定。
《AI Agent 智慧医院智能导诊就诊系统》的预问诊是同样的分工:全部消息存在 triage_message,每轮只把本轮之前最近 6 条、每条截到 150 字拼进提示词。
为什么这样取舍
- 条数取 8。 太少,模型接不住上下文;太多,提示词会被撑得很长。
- 倒序取再反转。 按
id desc取才能拿到最近的几条,反转后模型读到的是正常的对话顺序。
面试官还会追问
- 第一次提问时会话是怎么创建的?客户续聊时怎么防止接着别人的会话聊下去?
- 客户端点「新会话」时,为什么要先中断正在进行的流式请求?
学完《AI智能客服与工单处理系统》,上面这些追问你都会迎刃而解。