记忆
记忆是 Agent 区别于 Chatbot 的核心组件之一。Chatbot 聊完就忘,Agent 需要记住任务做到哪一步、用户偏好什么、上次踩过什么坑。把记忆等同于“历史聊天记录”是面试最常见的误区,真正的记忆系统是分层的、有治理的。
短期记忆与长期记忆
| 维度 | 短期记忆 | 长期记忆 |
|---|---|---|
| 本质 | 上下文窗口,模型唯一能直接推理的地方 | 外部持久化存储,按需检索进上下文 |
| 生命周期 | 一次推理或一个会话 | 跨会话、跨任务 |
| 内容 | 当前任务状态、中间结果、最近的对话 | 用户偏好、关键事实、经验教训 |
| 典型存储 | 上下文窗口、会话缓冲 | 向量库、结构化存储、文件 |
关键机制有两个方向:记忆巩固(短期到长期),对话中把重要信息沉淀到长期存储,靠记忆提取而不是无脑全存;记忆召回(长期到短期),新一轮对话根据当前问题从长期记忆检索相关内容注入上下文,本质是一次 RAG 检索。
记忆的分类
认知科学的三分法,也是面试加分项:
- 语义记忆:事实和知识。“用户是 Java 程序员”“团队用 UTC+8”
- 情景记忆:过去的交互事件。“上周三讨论过这个方案的取舍”
- 程序性记忆:技能和工作流。“这类导出任务需要先校验权限”,住在 CLAUDE.md 这类自动注入的文件里
读写策略
写入侧:不是每句话都有资格变成长期记忆。写入要过治理:
- 模型只负责提出候选记忆,代码层的策略门决定是否写入、写到哪、有效期多久、是否覆盖旧记忆
- 用户显式表达的偏好可以写;一次性上下文、敏感推断不写
- 冲突处理:新记忆标 active,旧记忆标 superseded,保留版本链。低置信的新事实不覆盖高置信的旧事实
- 每条记忆带治理字段:来源、置信度、有效期、作用域、状态
读取侧:记忆多了不能全量塞进上下文。把记忆当工具:
当前任务 → 生成记忆查询 → 按权限/状态过滤 → 召回候选 → 重排 → 注入 Top 证据排序不能只看向量相似度,要叠加时效、置信度、权限过滤。用户能查看、删除、暂停记忆,删除要落到存储层而不是 UI 层隐藏。
记忆与 RAG 的区别
- RAG 查的是外部知识(文档、知识库),目标是知识召回准确性
- Memory 管的是这个用户、这个 Agent 长期积累的状态,核心是状态治理:谁能写、何时过期、冲突怎么处理、用户能不能删
面试追问
- 短期和长期记忆的区别? 短期是上下文窗口,当前任务状态;长期是外部持久化,跨会话的知识和偏好。巩固把短期沉淀成长期,召回把长期注入短期
- 记忆写入要注意什么? 不能无脑全存。模型提候选,代码层治理:来源、置信度、有效期、冲突覆盖。用户明确的偏好才写,敏感推断不写
- 记忆和聊天记录的区别? 聊天记录是原始日志,记忆是经过提取、治理、可检索的状态。把历史消息当记忆是常见误区
- 记忆冲突怎么处理? 用户上周说喜欢 Java 这周改 Go:新记忆 active,旧记忆 superseded,保留版本和来源。不硬选一边
- 长期记忆用什么存? 向量库做召回,结构化字段做过滤和治理(namespace、status、confidence、expires_at)。只用向量库在冲突、权限、删除上吃亏