没有记忆的 Agent 每次对话都是初见:用户上周说过”我对花生过敏”,这周推荐餐厅时它一无所知。上下文窗口不是记忆——它贵、有限、且会话结束即清空。长期记忆 = 把值得留的信息沉淀到外部存储,在需要时精准召回。本文给出记忆的分类、写入-存储-读取三段式设计与常见陷阱。

记忆分类学(对照人类记忆)

  • 工作记忆(感官/短期):当前上下文窗口内的对话——昂贵且易失
  • 情景记忆(episodic):发生过的事:”用户 3 月 5 日让我订了靠窗座位”——带时间的经历日志
  • 语义记忆(semantic):提炼的事实与偏好:”用户偏好靠窗、花生过敏”——去时间化的知识
  • 程序记忆(procedural):学会的技能/流程(成功的工作流模板)——进阶形态

工程上优先做语义+情景两层:语义记忆服务个性化,情景记忆服务追溯与审计。

三段式设计:写入 → 存储 → 读取

写入(什么值得记):

  • 对话结束后(或每 N 轮)用 LLM 做记忆抽取:从对话中提炼候选事实(”用户提到 X”),而非整段对话入库
  • 抽取 prompt 要求结构化输出:{事实, 类别, 重要性, 时间};重要性过滤掉寒暄噪声
  • 冲突处理:新事实与旧记忆矛盾时(”我搬家了,现在住上海”),更新而非并存——记忆需要”改写”能力

存储(存在哪、怎么组织):

  • 语义记忆:向量库(事实文本 embedding)+ 结构化表(用户画像字段:偏好/禁忌/身份)双写——向量供模糊召回,表供精确读取
  • 情景记忆:带时间戳的事件日志(append-only),按会话/主题分片
  • 元数据必备:来源会话 ID、创建时间、最后访问时间、访问次数——供遗忘与审计

读取(何时召回、召回什么):

  • 每轮用户消息 → 嵌入 → 向量检索 top-k 相关记忆 + 画像表全量注入(画像小,常驻系统提示)
  • 召回内容以”记忆块”形式插入 prompt 并标注来源与时间(”据 3 月 5 日对话:用户花生过敏”),让模型知道这是历史而非当前输入
  • 控制注入量:记忆 token 占上下文预算的固定比例(如 10-15%),防记忆挤占工作记忆

遗忘机制:不遗忘的记忆库必然腐烂

  • 时间衰减:权重随创建时间衰减(艾宾浩斯式),长期未召回的情景记忆降权/归档
  • 访问强化:被召回且”用上了”(用户未纠正)的记忆加权——用反馈做记忆巩固
  • 合并去重:周期任务把相似记忆聚类合并为一条概括(”多次提到喜欢清淡口味”)
  • 遗忘不是删除是降级:归档区保留可审计,主库保持精瘦

实践参照与自建最小版

  • 参照系:MemGPT(把记忆当 OS 分层管理,自编辑记忆)、LangGraph 的 store/checkpointer、Zep(时序知识图谱记忆)
  • 自建最小三件套:抽取 prompt + 向量库/画像表 + 召回注入中间件——百行级起步,先跑通”偏好记住”一个场景再扩展

陷阱清单

  • 记忆污染:把模型的错误推断当事实写入(”用户应该喜欢 X”)→ 只记用户明确陈述与行为证据
  • 隐私红线:敏感信息(证件、健康、财务)入记忆库需脱敏或加密,并提供”查看/删除我的记忆”用户接口(合规要求)
  • 召回噪声:不相关记忆注入会误导回答 → 相似度阈值+重要性双过滤,宁缺毋滥
  • 记忆与 RAG 混淆:RAG 检索的是外部知识,记忆检索的是用户历史——两者索引、更新频率、权限模型都不同,别共用一套库

长期记忆让 Agent 从”工具”变成”熟人”:写入靠抽取与冲突更新,存储靠向量+画像双轨,读取靠预算内召回,维护靠衰减与合并。四段做齐,再加隐私与污染两条护栏,记忆系统才既好用又可信。