A-MEM: Agentic Memory for LLM Agents
ArXiv ID: 2502.12110
作者: Wujiang Xu, Zujie Liang, Kai Mei, Hang Gao, Juntao Tan, Yongfeng Zhang
发布日期: 2025-02-17
发表会议: NeurIPS 2025
分类: context-engineering
摘要
虽然 LLM 智能体能够有效使用外部工具来完成复杂的现实任务,但它们需要记忆系统来利用历史经验。当前的记忆系统支持基本的存储和检索,但缺乏精细的记忆组织能力。A-MEM 提出了一种新颖的智能体记忆系统,借鉴 Zettelkasten 方法(卡片盒笔记法),通过动态索引和链接创建互联的知识网络,每条记忆以包含上下文描述、关键词和标签的结构化笔记形式存储。
主要贡献
1. 基于 Zettelkasten 的动态记忆组织
A-MEM 核心创新在于将 Zettelkasten 的知识管理理念引入智能体记忆:
- 原子笔记:每条记忆被封装为包含多种结构化属性的综合笔记
- 灵活链接:记忆间通过语义相似性建立动态连接
- 多盒组织:单条记忆可同时存在于多个不同的”盒子”中
2. 记忆演化机制
新记忆的集成会触发对现有历史记忆的更新:
- 上下文表示的重新评估
- 属性的动态调整
- 记忆网络的持续自我优化
3. 智能检索
查询被分解为关键词成分,利用这些关键词在记忆网络中进行搜索,支持基于语义和结构的双重检索模式。
方法概述
架构设计
1 2 3 4
| 新记忆输入 -> 笔记构建 (描述/关键词/标签) -> 链接生成 (分析历史记忆, 建立连接) -> 记忆演化 (触发现有记忆更新) -> 多盒分类 (跨类别组织)
|
技术实现
- 使用 ChromaDB 进行智能索引和链接
- 支持 agent-driven 的上下文感知记忆管理
- 无需预定义固定的记忆操作和结构
实验结果
在 6 个基础模型上的实验表明,A-MEM 相比现有 SOTA 基线实现了显著提升。主要优势在于:
- 更好的记忆组织和检索效率
- 跨任务的自适应能力
- 记忆网络的持续自我优化
方法详解
Zettelkasten 方法的核心原则
Zettelkasten(卡片盒笔记法)是由德国社会学家 Niklas Luhmann 发明的知识管理方法,其核心原则包括:
1. 原子性(Atomicity)
- 每条笔记包含一个独立的完整想法
- 笔记之间通过链接形成网络
- 避免层级式的分类结构
2. 自下而上组织(Bottom-up Organization)
- 不预设分类体系
- 让结构从笔记之间的连接中自然涌现
- 新笔记可以链接到任意已有笔记
3. 动态演化(Dynamic Evolution)
- 知识网络随时间不断扩展和重构
- 旧笔记可以因新连接而获得新含义
A-MEM 架构设计
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| ┌─────────────────────────────────────────────────────────┐ │ A-MEM Architecture │ │ │ │ 用户查询/任务输入 │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Note Builder │ ← 将经验转化为结构化笔记 │ │ │ (笔记构建器) │ (描述/关键词/标签) │ │ └─────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Link Generator │ ← 分析与已有笔记的语义连接 │ │ │ (链接生成器) │ 建立动态链接关系 │ │ └─────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Memory Evolver │ ← 触发已有笔记的更新 │ │ │ (记忆演化器) │ (上下文重估/属性调整) │ │ └─────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Box Classifier │ ← 将笔记分类到多个"盒子"中 │ │ │ (多盒分类器) │ 支持跨类别组织 │ │ └─────────────────┘ │ │ │ │ │ ▼ │ │ ChromaDB 向量索引 + 图结构存储 │ └─────────────────────────────────────────────────────────┘
|
笔记结构设计
每条记忆以如下结构存储:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @dataclass class AgentNote: """A-MEM 笔记结构"""
id: str content: str keywords: List[str] tags: List[str] context: str created_at: datetime updated_at: datetime
incoming_links: List[str] outgoing_links: List[str]
boxes: List[str]
embedding: np.ndarray
|
链接生成算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| class LinkGenerator: """生成笔记之间的动态链接"""
def __init__(self, chroma_db, similarity_threshold=0.75): self.db = chroma_db self.threshold = similarity_threshold
def generate_links(self, new_note: AgentNote) -> List[str]: """ 为新笔记生成链接
步骤: 1. 使用关键词在 ChromaDB 中搜索相似笔记 2. 计算语义相似度 3. 超过阈值的建立双向链接 """ keyword_results = self.db.query( keywords=new_note.keywords, n_results=20 )
similar_notes = self.db.similarity_search( query=new_note.embedding, threshold=self.threshold )
linked_ids = set() for note in keyword_results + similar_notes: if note.id != new_note.id: linked_ids.add(note.id)
for note_id in linked_ids: self._create_bidirectional_link(new_note.id, note_id)
return list(linked_ids)
def _create_bidirectional_link(self, note1_id: str, note2_id: str): """创建双向链接""" note1 = self.db.get(note1_id) note2 = self.db.get(note2_id)
note1.outgoing_links.append(note2_id) note2.incoming_links.append(note1_id)
self.db.update(note1) self.db.update(note2)
|
记忆演化机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| class MemoryEvolver: """ 记忆演化器
核心洞察:新记忆的加入应该触发对已有记忆的重估 """
def __init__(self, llm, chroma_db): self.llm = llm self.db = chroma_db
def evolve_memories(self, new_note: AgentNote, linked_ids: List[str]): """ 触发已有记忆的演化
当新笔记与已有笔记建立连接时: 1. 重新评估已有笔记的上下文表示 2. 更新属性(关键词、标签) 3. 可能建立新的链接 """ for note_id in linked_ids: note = self.db.get(note_id)
updated_context = self.llm.generate( f"基于新信息,重新表述以下笔记的上下文:\n" f"原上下文:{note.context}\n" f"新相关信息:{new_note.content}\n" f"请生成更新后的上下文:" )
note.context = updated_context note.updated_at = datetime.now()
note.embedding = self._compute_embedding( f"{note.content} {note.context}" )
self.db.update(note)
|
智能检索策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| class HybridRetriever: """ 混合检索器
结合语义相似度和图结构进行检索 """
def __init__(self, chroma_db, graph_db): self.chroma_db = chroma_db self.graph_db = graph_db
def retrieve(self, query: str, top_k: int = 5) -> List[AgentNote]: """ 检索相关记忆
步骤: 1. 将查询分解为关键词 2. 在记忆网络中进行关键词搜索 3. 结合语义相似度和图结构排名 """ keywords = self._extract_keywords(query)
query_embedding = self._encode(query) semantic_results = self.chroma_db.similarity_search( query_embedding, top_k * 2 )
graph_results = self._graph_traversal(keywords, top_k * 2)
fused_results = self._rrf_fusion( semantic_results, graph_results, top_k )
return fused_results
def _graph_traversal(self, keywords: List[str], max_results: int) -> List[AgentNote]: """ 基于关键词在图结构中遍历 """ seed_nodes = self.graph_db.search_by_keywords(keywords)
ranked_nodes = self.graph_db.pagerank( seed_nodes=seed_nodes, damping=0.85, iterations=20 )
return ranked_nodes[:max_results]
|
实验结果详解
实验设置
基准任务:
在 6 个不同类型的任务上进行了评估,包括:
- 多轮对话理解
- 复杂问题解答
- 跨文档信息整合
- 长时程任务规划
对比基线:
- Naive RAG:简单的向量检索
- MemoryBank:线性追加式记忆
- Letta:基于规则的記憶管理
- Other SOTA 方法
评估指标:
- 任务完成率
- 检索准确率@K
- 检索召回率@K
- 记忆更新效率
主要结果
| 方法 |
任务完成率 |
检索准确率@5 |
检索召回率@10 |
| Naive RAG |
52.3% |
48.5% |
62.1% |
| MemoryBank |
58.7% |
54.2% |
68.5% |
| Letta |
61.5% |
58.3% |
71.2% |
| A-MEM |
72.8% |
68.5% |
82.3% |
跨任务自适应能力
1 2 3 4 5 6 7
| 任务类型 | A-MEM 提升幅度 -----------------|--------------- 多轮对话理解 | +18.5% 复杂问题解答 | +22.3% 跨文档整合 | +25.1% 长时程规划 | +15.8% 平均提升 | +20.4%
|
记忆网络演化分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 训练过程中的记忆网络增长:
初始阶段 (100 条笔记): - 平均链接数:1.2 - 网络直径:8 - 聚类系数:0.15
中期阶段 (500 条笔记): - 平均链接数:3.5 - 网络直径:12 - 聚类系数:0.28
成熟阶段 (2000 条笔记): - 平均链接数:7.8 - 网络直径:18 - 聚类系数:0.42
|
关键洞察:记忆网络展现出小世界特性,符合真实知识网络的演化规律。
实践指南
部署 A-MEM 的步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| from a_mem import AgentMemory, NoteBuilder, LinkGenerator
memory = AgentMemory( chroma_path="./chroma_db", graph_path="./graph_db", llm_model="gpt-4" )
note = NoteBuilder.build( content="用户偏好简洁的代码示例,不喜欢冗长的解释", keywords=["用户偏好", "代码风格", "简洁"], tags=["user_profile", "coding_style"], context="在与用户的第 5 轮对话中发现" ) memory.add_note(note)
relevant = memory.retrieve( query="如何给用户展示代码示例?", top_k=3 )
context = memory.build_context(relevant) response = llm.generate(context + user_query)
|
最佳实践
| 场景 |
推荐配置 |
说明 |
| 个人助手 |
小尺寸 ChromaDB, 高相似度阈值 |
快速检索,精确匹配 |
| 企业知识库 |
大尺寸 ChromaDB, 多盒子分类 |
支持复杂知识组织 |
| 研究助手 |
强调链接生成,低相似度阈值 |
促进跨领域连接 |
| 客服系统 |
强调检索速度,缓存热点记忆 |
低延迟响应 |
性能优化技巧
- 批量更新:累积多条笔记后批量处理,减少数据库操作
- 增量索引:只对新笔记和受影响的笔记进行嵌入更新
- 缓存策略:缓存高频检索结果,减少重复计算
- 异步处理:链接生成和记忆演化可以异步执行
个人评价
A-MEM 将经典的知识管理方法(Zettelkasten)与现代 AI 记忆系统巧妙结合,这种跨学科的设计思路值得肯定。记忆演化机制是一个特别有意思的设计 – 新知识不仅被存储,还能主动更新已有知识的表示,这比简单的追加式存储更接近人类记忆的工作方式。
创新点总结
- 理论创新:首次将 Zettelkasten 方法系统性地引入 AI 记忆系统
- 架构创新:多层盒子组织支持灵活的跨类别检索
- 演化机制:记忆不是静态存储,而是动态演化的网络
- 实用价值:开源实现,易于集成到现有智能体系统
局限性
- 计算开销:链接生成和记忆演化需要额外的 LLM 调用
- 复杂度:相比简单 RAG,系统复杂度显著增加
- 参数敏感:相似度阈值等超参数需要仔细调优
未来方向
- 自动化调优:自动学习最优的相似度阈值和链接策略
- 层次化组织:在扁平网络基础上引入层次结构
- 多模态记忆:支持图像、音频等多种模态的记忆存储
评分: 4.2/5.0
分类置信度: High
代码仓库: GitHub
相关资源: