Agent Memory 架构

大语言模型看起来能够 "记住" 用户,真正保存信息的却不是模型本身;一次模型调用只能依据当前收到的上下文进行推理,跨会话记忆通常由 Agent 外部的文件、数据库、检索器和更新流程共同实现

因此,设计 Agent 记忆系统不能只问 "该用哪个向量数据库",而应该依次回答四个问题:

需要记住什么?记忆以什么结构保存?怎样找回当前真正需要的信息?新事实出现后,旧记忆如何更新、失效和追溯?

记忆类型决定 "存什么",存储介质决定 "放哪里",检索策略决定 "怎么找",维护策略决定 "它是否长期可信"

上下文窗口不等于长期记忆:

上下文窗口是模型本次推理时能够看到的信息;长期记忆则保存在模型之外,需要在下一次运行时重新取回并放入上下文

一个典型 Agent 的记忆流程如下:

复制代码
用户请求
   ↓
判断是否需要历史信息
   ↓
按用户、时间和记忆类型过滤
   ↓
关键词 / 向量 / 图检索
   ↓
重排并组装相关上下文
   ↓
模型推理与工具调用
   ↓
提取值得长期保存的新信息
   ↓
写入、替代或整理记忆

这也解释了为什么不能把全部聊天记录直接塞给模型;历史越长,Token 成本越高,噪声越多,真正重要的信息反而越容易被淹没

先区分短期记忆与长期记忆:

短期记忆:维持当前任务连续性

短期记忆通常绑定到某个会话或任务线程,包括:

  • 最近几轮对话
  • 当前任务状态
  • 已调用的工具及其结果
  • 尚未完成的计划
  • 临时变量和中间结论

它的作用类似人的工作记忆;任务结束后,其中大部分内容不需要永久保存

长期记忆:跨会话保留重要信息

长期记忆能够跨任务和会话复用;按照 LangGraph 等系统采用的认知分类,可以进一步分为三类:

类型 保存内容 示例
语义记忆 稳定事实和概念 用户偏好深色模式;客户要求纯素认证
情景记忆 带时间和上下文的经历 上周参加了会议;某次工具调用失败
程序记忆 规则、流程和操作方法 如何生成周报;如何完成一次市场调研

三种记忆的写入和读取方式并不相同;语义记忆适合提炼为事实,情景记忆需要保留时间和来源,程序记忆则更适合保存为可编辑的规则、提示词或 Skill

四种主要存储结构:

Markdown:最简单、最透明

Agent 可以通过 memory.md 保存用户事实,通过 soul.md 保存角色和行为规则,再通过单独的 Skill 文件保存操作流程;Hermes 等 Agent Harness 都采用了类似思路

Markdown 的优势是容易阅读、编辑、审计和版本管理;如果信息很少,还可以在每次运行时直接加载到上下文

它的问题是规模扩展能力有限;文件越来越长以后,全量加载会增加成本,模型也难以持续关注所有内容;因此,Markdown 更适合少量高价值事实、核心规则和人工维护的程序记忆

SQLite:结构化记录与全文检索

当记忆需要时间、来源、用户和状态等字段时,关系数据库会更合适;一个实用的数据结构可以包含:

字段 用途
user_id 隔离不同用户的记忆
memory_type 区分语义、情景和程序记忆
content 保存事实或事件内容
source 记录信息来自用户、网页还是工具
valid_from 事实开始生效的时间
valid_to 事实失效的时间
supersedes_id 指向被当前事实替代的旧记录
created_at 记忆写入时间

SQLite 的 FTS5 是官方提供的全文检索虚拟表模块;基于倒排索引实现高速文本检索,支持词项、短语、前缀、邻近查询、布尔条件组合以及 BM25 相关性打分排序;原生缺少中文分词能力,适合读多写少场景,可搭配外部分词器适配中文业务

关键词检索速度快、成本低、结果容易解释,尤其适合姓名、编号、日期、日志和工具调用记录;但它依赖分词与词面匹配,跨语言、同义表达和模糊意图可能降低召回率;中文数据还需要特别验证分词器或考虑 trigram 等索引方案

向量存储:按语义寻找相似内容

向量检索会先使用嵌入模型,把一段文本转换成高维向量;查询也经过相同处理,然后通过余弦距离、内积或欧氏距离寻找语义接近的记录

这里需要纠正一个常见误解:系统通常为句子、事实或文本块生成向量,而不是简单地 "把每一个单词分别存成向量"

pgvector 是 PostgreSQL 的扩展,不是 SQLite 扩展;它允许向量与普通业务字段存放在同一张 PostgreSQL 表中,并支持:

  • 精确近邻搜索
  • HNSW 和 IVFFlat 近似近邻索引
  • 余弦距离、内积、L2 和 L1 等距离计算
  • 使用普通 SQL 对用户、时间、权限和类别进行过滤

精确搜索能获得完整召回,但数据规模增大后成本会上升;近似索引以部分召回率换取速度,其中 HNSW 通常拥有较好的速度与召回率平衡,但建索引更慢、占用更多内存;IVFFlat 构建更快、内存较少,却更依赖数据量和参数设置

向量相似只代表 "表达接近",不代表 "事实正确";生产系统不能只取相似度最高的几条记录,还应结合用户范围、有效时间、来源、权限和后续重排

图结构:保存实体之间的关系

当问题的重点不再是某条独立事实,而是事实之间的关系时,可以使用图结构;图中的节点表示人物、组织、产品或事件,边表示它们之间的关系:

复制代码
Alex
 ├── 参加 → Lisbon AI Meetup
 ├── 创办 → 机器人项目
 └── 项目 → 原定五月发布
                 ↓
             推迟到六月

图能够直接表达 "谁参与了什么" "某个决定影响了哪个项目" "一条信息为何与另一条信息相关";它适合多跳查询、关系密集数据和需要追溯历史变化的场景

四种记忆检索策略:

检索方式 工作方式 优点 主要局限
直接预加载 把记忆直接放入上下文 简单、不会漏检 占用上下文,难以扩展
FTS/关键词 匹配词项、短语和布尔条件 快、便宜、可解释 不擅长同义词和跨语言
向量检索 查找语义相似的文本 表达灵活、召回能力强 相似不等于正确
图与混合检索 结合实体、关系、时间和语义 支持多跳与关系推理 索引和维护成本较高

成熟系统通常使用混合检索,而不是四选一;例如先根据 user_id 和有效时间过滤,再并行执行 BM25 与向量搜索,最后融合分数、重排结果并组装上下文

RAG、GraphRAG 与 Agent Memory:

RAG 把语言模型的参数化知识与外部非参数化记忆结合起来;系统先从外部知识库检索相关内容,再让模型依据这些内容生成答案;

RAG 解决的是 "怎样从外部知识中取回证据";Agent Memory 解决的则是 "怎样长期保存并管理与用户、任务和 Agent 自身有关的动态信息"

两者可以重叠,但不能画等号:

  • 企业文档库属于 RAG 知识源,却不一定是用户记忆
  • 用户偏好属于 Agent Memory,也可以通过向量 RAG 取回
  • 一次工具调用记录属于情景记忆,通常不会进入公共知识库
  • 程序记忆可能以 Skill 文件保存,根本不需要向量检索

Microsoft GraphRAG:

Microsoft GraphRAG 不是简单地 "给节点和边生成向量";它会从非结构化文本中抽取实体、关系和相关描述,建立知识图谱与社区层次,并生成社区报告

其查询方式包括:

  • Local Search:结合图中的实体关系和原始文本块,回答围绕具体实体的问题
  • Global Search:在社区报告上执行 Map-Reduce,回答关于整个数据集的宏观问题
  • DRIFT Search:从社区信息出发扩展局部检索,并生成更细致的后续问题
  • Basic Search:提供基础向量 RAG,便于比较不同检索方式

Microsoft 官方明确提示 GraphRAG 的索引可能成本较高;它更适合复杂、叙事性强、需要跨文档理解的数据集,而不是几条用户偏好这样的小型记忆

Graphiti 与时间上下文图:

Graphiti 是 Zep 体系中的开源时间上下文图引擎,更偏向持续变化的 Agent 记忆;它把信息组织为:

  • Entity:人物、产品、组织等实体节点
  • Fact/Relationship:带有效时间窗口的事实或关系边
  • Episode:产生这些事实的原始对话、文本或 JSON 数据
  • Provenance:从派生事实回溯到原始 Episode 的来源关系

Graphiti 支持增量更新,并将语义搜索、BM25 和图遍历组合为混合检索;旧事实被新事实替代时,可以失效而不必删除,因此既能回答 "现在是什么",也能回答 "过去是什么";

Zep 是托管式产品,Graphiti 是需要自行部署和运维的开源引擎;二者不能直接当作同一个软件版本理解

写入记忆不能等同于保存聊天记录:

一次完整对话可能包含寒暄、重复表达、推测、纠正和工具输出;如果全部写入长期记忆,数据库很快会变成无法使用的聊天垃圾场

写入前至少需要完成三步判断:

重要性判断:这条信息未来是否还会使用?

类型判断:它属于事实、事件还是程序?

冲突判断:它是新事实、重复事实,还是对旧事实的修正?

随后再选择具体动作:

操作 含义
Add 添加新事实
Update 修正现有记录
Delete 删除错误或依法必须清除的信息
No-op 信息重复,不做处理
Supersede 新事实生效,旧事实保留但失效

例如,用户先说 "访客将在晚上七点到达",随后改为 "晚上九点才能到";删除七点这条记录会丢失变化历史,直接覆盖又无法解释过去的安排;更好的方法是让旧记录在更新时刻失效,再新增一条从该时刻开始生效的九点记录

需要注意的是,产品的内部算法会随版本变化;当前,Mem0 的新一代托管算法在自动提取阶段采用 ADD-only 策略,不再让模型直接执行 UPDATE/DELETE,同时融合语义、BM25、实体匹配与时间推理;这不代表所有历史版本或人工管理 API 都遵循同一策略,因此选型时应以实际部署版本的文档为准

在线写入与后台整理:

记忆可以在两条路径上形成:

  • 在线路径(hot path):Agent 在对话过程中立即决定查询或写入记忆
  • 后台路径(background):任务完成后异步提取、合并和更新知识

LangMem 同时提供了对话中的记忆管理工具和后台记忆管理器;前者响应及时,但会增加当前请求的延迟;后者不会阻塞回答,更适合批量去重、摘要和一致性检查

一种实用架构是先把原始对话和工具结果写入 SQLite,再异步提取高价值事实;短小且必须始终生效的规则写入 Markdown,语义事实进入向量索引,复杂实体关系再进入时间图;

后台整理有时被形象地称为 "反思" 或 "做梦",但它不是统一技术标准;工程上真正需要的是明确的去重、合并、冲突检测、失效和来源追踪流程

如何选择:从最小可用架构逐步升级

场景 推荐起点
原型或个人助理 Markdown + SQLite
需要保存完整运行轨迹 SQLite + FTS5
用户表达多变或存在跨语言查询 结构化过滤 + 向量检索
大量文档问答 向量 RAG 或混合检索
复杂实体关系与多跳问题 知识图谱 / GraphRAG
高频变化且需要历史追溯 时间上下文图
希望直接使用记忆管理能力 Mem0、LangMem、Zep 等现成组件

最稳妥的演进路线通常是:

复制代码
Markdown
   ↓
SQLite + FTS5
   ↓
元数据过滤 + 向量检索
   ↓
BM25 与向量混合召回
   ↓
仅在关系复杂时引入图和时间语义

图数据库并不会自动让 Agent 更聪明;如果业务问题只涉及少量偏好、日期和联系人,引入时间图可能增加写入延迟、索引成本和运维复杂度,却没有带来同等价值

怎样正确评估记忆系统:

使用同一组事实测试 SQLite、Mem0、LangMem、Zep 和无记忆对照组能展示关键词检索、跨语言查询、事实替代和图构建延迟之间的差异,但单次运行时间不能当作严格性能排名

更可靠的评估至少应包含:

  • 召回率:需要的记忆是否被找到
  • 精确率:返回内容中有多少真正相关
  • 事实一致性:回答是否忠于存储记录
  • 时间正确性:能否区分当前事实与历史事实
  • 跨语言能力:不同语言提问能否找到同一事实
  • 更新正确性:新信息能否替代旧信息
  • 来源可追溯性:答案能否回到原始对话或工具结果
  • 延迟与成本:写入、索引、检索和生成分别消耗多少资源
  • 隔离与删除:不同用户的数据是否隔离,删除请求是否彻底执行

测试集还应包含无答案问题;一个优秀的记忆系统不仅要在有记录时回答正确,也要在没有证据时明确表示不知道

一个可靠的最终架构:

对多数 Agent 项目而言,合理的默认设计不是直接采用最复杂的 GraphRAG,而是分层组合:

  • Markdown 保存少量核心规则和程序记忆
  • SQLite 保存对话、事件、工具结果和审计记录
  • FTS5 负责名称、编号、短语和日志检索
  • 向量索引负责同义表达和跨语言语义召回
  • 元数据过滤负责用户、权限、类型和时间边界
  • 时间字段与替代关系负责处理事实变化
  • 后台任务负责提取、去重、合并和失效
  • 只有在多跳关系具有明确价值时才建立图结构

AI Agent 的长期价值不在于积累了多少聊天记录,而在于能否把经历转化为少量、准确、可检索、可更新并可追溯的知识;先明确记忆内容,再选择存储和检索方式,最后建立可靠的生命周期管理,才是一套真正可持续的 Agent 记忆系统

相关推荐
richard_first2 小时前
Transformer 与大语言模型:第10章 Residual (残差连接)
人工智能·深度学习·机器学习·transformer
zhongerzixunshi2 小时前
深耕绿色建材认证 赋能建筑行业低碳高质量发展
人工智能
Wang's Blog2 小时前
Vibe Coding一人即团队系列10: 在 Claude 与 Codex 中接入 DeepSeek 模型
人工智能
lisw052 小时前
计算与科学哲学(Philosophy of Computing and Science)
java·开发语言·人工智能
天天进步20152 小时前
Pixelle-Video 源码解析 #10:多模型适配:GPT、通义千问、DeepSeek、Ollama 如何统一调用?
人工智能·gpt
@atweiwei2 小时前
用 Rust 构建 Agent 应用的高性能框架:langchainrust 架构全景
人工智能·架构·rust·langchain·llm·agent·ai编程
欧特克_Glodon2 小时前
OpenCV计算机视觉开发入门与实践<二十二>:图像平滑之线性滤波
c++·人工智能·opencv·计算机视觉
ShiXZ2132 小时前
ChatGPT Plus用户注意:5小时限制今日恢复,额度每5小时自动刷新(且额度又又又重置了)
人工智能·chatgpt
阿童木写作2 小时前
跨马翻译:AI批量图片翻译工具,视频字幕翻译与智能抠图一站式解决
大数据·人工智能·python·音视频