4个主流智能体记忆系统的对比

四个流行的智能体记忆库对同一个设计问题各自选择了不同的答案:智能体应该如何跨会话记忆信息?Letta 编辑纯文本块和文件。Mem0 维护一个带有实体提示的向量存储。Graphiti 将事实索引为带时间戳的关系。Cognee 运行一个实体提取流水线。

知识图谱将事实存储为实体之间的类型化关系。Obsidian 基于可导航为图的双向笔记链接构建了一个百万用户产品。Karpathy 的 LLM Wiki 提出让 LLM 从零开始构建持久知识库。图结构可以让你遍历事实之间的连接,而不仅仅是按相似度匹配。但越来越多的从业者认为,仅用文件在实践中已经足够好,而专门的图谱工具增加了复杂性却没有带来相应的收益。我们将这四个从最少图到最多图排列,并追踪两个核心问题:相关事实是否能一起被检索回来,以及事实变更如何处理?

Letta 是一个完整的智能体框架,为你运行智能体。Mem0、Graphiti 和 Cognee 是你可以挂接到自己智能体上的记忆层。四个项目都在其开源版本之上运行付费云服务(Letta Inc.Mem0 Inc.ZepTopoteretes),各自都有超出开源版本的功能。本文覆盖的是开源版本。

1、Letta (MemGPT):自编辑文本块

Letta 不使用图。记忆被分层,由智能体自己管理。记忆块永久保留在上下文中。每个都是一个带标签的文本字段,有固定的字符限制,LLM 在每一轮都会读取和编辑。之外是按需通过向量搜索的归档记忆对话历史记录,以及可选的用于上传文档的文件系统表面。

智能体通过工具调用来编辑自己的记忆。编辑接口是一小部分函数:core_memory_replacememory_replacememory_insertmemory_apply_patchmemory_rethink。检索也是由智能体驱动的,通过 archival_memory_searchconversation_search,加上文件系统的 open_filesgrep_files

core_memory_replace 是这些编辑函数中最简单的一个。

functions/function_sets/base.py:263-280

def core_memory_replace(agent_state, label, old_content, new_content) -> str:
    """Replace the contents of core memory. To delete memories, use an empty string for new_content."""
    current_value = str(agent_state.memory.get_block(label).value)
    new_value = current_value.replace(str(old_content), str(new_content))
    agent_state.memory.update_block_value(label=label, value=new_value)
    return new_value

更新是块文本上的简单字符串替换,没有结构来跟踪什么改变了或何时改变的。过时事实是否被替换完全取决于 LLM 是否注意到矛盾并调用该函数。Letta 还提供了sleeptime agentsletta/groups/sleeptime_multi_agent_v*.py),一个在对话轮次之间整合和重写块的后台循环,因此记忆可以在实时交互之外发生变化。机制仍然是自编辑文本。

为了从头到尾走一遍完整流程,假设你给智能体一个人设块,上面写着"Lives in Boston."。你发送"I moved from Boston to SF."。智能体读取自己的块,看到矛盾,然后调用 core_memory_replace 在文本中将"Boston"替换为"SF"。当你后来问"Where do I live?"时,不需要检索步骤,因为那个块一直在上下文中,现在读作"Lives in SF."。Boston 已经消失了,没有任何记录表明它曾经在那里。整个流程依赖于模型注意到矛盾并选择覆盖。如果它没有注意到,什么都不会触发。

Letta 的"Is a Filesystem All You Need?" 文章(2025年8月)将 LOCOMO(一个多会话对话回忆基准测试)的对话记录转储到附加在一个普通智能体上的文件中,得分 74.0%,高于 Mem0 图变体的 68.5%(arXiv 2504.19413,2025年4月)。Letta 认为智能体在训练后已经擅长迭代文件搜索,因此专门的记忆系统增加的价值很小。

2、Mem0:去掉图,加入实体链接

Mem0 开始时有一个可选的图层,然后在 v3 开源重写中将其移除。这个删除仅适用于开源版本。Mem0 的托管平台仍然列出图记忆和基于时间的衰减作为功能。

图记忆通过 PR #1718 作为一个可选层引入,然后在2025年扩展到支持五种图数据库:Neo4j、内存中的 Memgraph、嵌入式 Kuzu、AWS 托管的 Amazon Neptune,以及 Apache AGE(Postgres 的图扩展)。v3 流水线在提交 a488e190PR #4805,2026年4月14日合并)中移除了该模块。

实体链接取代了图记忆。实体使用 spaCy 而非 LLM 提取,并存储在并行的 {collection}_entities 向量集合中。每个实体行持有一个 linked_memory_ids 列表。这是一个中心辐射结构,实体指回提到它的记忆,而不是类型化边。在查询时,实体重叠成为加性评分中的一个信号,语义加 BM25 加实体加成,融合并归一化。

实体加成计算只有三行算术。

memory/main.py:1487-1489

num_linked = max(len(linked_memory_ids), 1)
memory_count_weight = 1.0 / (1.0 + 0.001 * ((num_linked - 1) ** 2))
boost = similarity * ENTITY_BOOST_WEIGHT * memory_count_weight

一个实体匹配会提升它链接到的每一条记忆,通过 memory_count_weight 衰减,使无处不在的实体不会淹没结果。关系感知是加到向量分数上的一个数字。

在 Poppy 例子中,M1 和 M2 都超过了 0.1 阈值并作为检索对返回,M3 被丢弃。"Poppy" 加成在两者上相同,所以它没有决定它们的顺序。M2 在 BM25 关键词项上领先(BM25 评分的是与查询的字面词语重叠,不同于基于嵌入的语义评分),这超过了 M1 更高的语义分数。返回的是原始记忆文本,智能体将其放入提示词并据此回答。Mem0 放弃了结构化的类型化遍历——即通过遍历边来回答"谁拥有那只去做了检查的狗"的能力。它保留了低成本的胜利——共同检索共享实体的记忆。

为什么去掉图?Mem0 自己的论文(arXiv 2504.19413,2025年4月)在 LOCOMO 上对图变体 Mem0g 与纯向量 Mem0 进行了基准测试,图很少能证明其成本是值得的。

图变体在总分上略胜,68.44 对 66.88,并在时间维度上获胜,但收益很薄。它在单跳和多跳上失败了,搜索速度慢了约3倍,token 消耗约2倍。

3、Graphiti (Zep):双时态事实图

Graphiti 完全围绕图构建。数据模型有 EpisodicNodes(存储提取每个事实的原始输入)、EntityNodes、CommunityNodes(总结相关实体的集群),以及一个作为事实边的 EntityEdge:Entity --RELATES_TO--> Entity,带有事实文本和嵌入。

每条事实边都是双时态的。它记录有效时间(valid time),即事实在世界中为真的时间(valid_at/invalid_at),以及事务时间(transaction time),即系统知道它的时间(created_at/expired_at)。

graphiti_core/edges.py:271-279

expired_at: datetime | None = Field(default=None, description='datetime of when the node was invalidated')   # transaction time
valid_at:   datetime | None = Field(default=None, description='datetime of when the fact became true')       # valid time
invalid_at: datetime | None = Field(default=None, description='datetime of when the fact stopped being true')  # valid time

当矛盾的事实到来时,旧边被标记为无效而不是删除。

graphiti_core/utils/maintenance/edge_operations.py:569-571

edge.invalid_at = resolved_edge.valid_at
edge.expired_at = edge.expired_at if edge.expired_at is not None else utc_now()
invalidated_edges.append(edge)

Graphiti 关闭旧边而不是删除它。旧事实仍然可查询,所以你可以问现在什么是真的,与那时什么是真的。

摄取是增量的。每次调用 add_episode 都会触发 LLM 提取节点和边,实体解析使用确定性的 MinHash 和 LSH 快速路径加上 LLM 回退,然后进行边去重和矛盾解决。没有批量重计算,这与静态 GraphRAG 不同。检索结合余弦相似度、BM25 和广度优先图遍历,配合可插拔的重排序器(RRF、节点距离、MMR、episode-mentions、交叉编码器),并在查询时跳过 LLM 摘要以保持亚秒级延迟。

成本很高。单个 episode 可以触发许多 LLM 调用——节点提取然后去重然后边提取然后逐边解析、时间戳和属性。这是频谱中昂贵的一端,与 Mem0 的赌注相反。Zep 论文(arXiv 2501.13956)和 README 承载了正向收益声明。

4、Cognee:提取、认知化、加载

Cognee 将记忆视为一个数据工程问题。它的流水线是 ECL:提取、认知化、加载。公共 API 是 add()cognify()search()memify(),还有一个更新的智能体门面 remember/recall/forget/improve

cognee/api/v1/cognify/cognify.py:316-344

default_tasks = [
    # EXTRACT: classify raw Data items into typed Document objects
    Task(classify_documents),
    # EXTRACT: split Documents into semantic text chunks
    Task(
        extract_chunks_from_documents,
        max_chunk_size=chunk_size or get_max_chunk_tokens(),
        chunker=chunker,
    ),
    # COGNIFY: LLM-extract entities and relationships into a knowledge graph
    # COGNIFY: LLM-summarize each chunk for retrieval
    Task(
        extract_graph_and_summarize,
        graph_model=graph_model,
        config=config,
        custom_prompt=custom_prompt,
        task_config={"batch_size": chunks_per_batch},
        **kwargs,
    ),
    # LOAD: persist nodes, edges, and embeddings to graph/vector DBs
    Task(
        add_data_points,
        embed_triplets=embed_triplets,
        task_config={"batch_size": chunks_per_batch},
    ),
    Task(extract_dlt_fk_edges),
]

DataPoint 本体将图边声明为指向其他 DataPoint 的类型化 Pydantic 字段。

cognee/modules/chunking/models/DocumentChunk.py:10-37

class DocumentChunk(DataPoint):
    text: str
    chunk_index: int
    is_part_of: Document                        # edge to the parent Document
    contains: List[Entity] = None               # edges to the entities inside it
    metadata: dict = {"index_fields": ["text"]}  # which field gets embedded

is_part_ofcontains 看起来像普通的类型提示,但 Cognee 在运行时读取它们,并将每个类型化字段转换为 DataPoint 节点之间的图边。metadata 中的 index_fields 条目声明哪个字段被嵌入,因此单个类同时描述了图层和向量层。在 Cognee 中,记忆是一个建模练习。

流水线本身是可组合的。上面 default_tasks 列表中的每一步都是一个 Task,这些任务链接成一个你可以编辑的流水线。默认的 cognify 链分类、分块、提取图并摘要,然后添加数据点和外键边。存储跨越三个可插拔层:图数据库(默认基于 Kuzu 的"ladybug",或 Neo4j、Neptune、Postgres)、向量数据库(默认 LanceDB,还有 pgvector、Chroma)和关系数据库(SQLite 或 Postgres)。搜索是一个大型枚举(SearchType),以 GRAPH_COMPLETION(向量引导的三元组搜索加上 LLM)为旗舰,以及 RAG_COMPLETION、CHUNKS、SUMMARIES、CYPHER、NATURAL_LANGUAGE、TEMPORAL 等。

Cognee 在三个明确阶段处理同一个事实。你将两条陈述作为原始文本添加,仍然是未结构化的。你调用 cognify,它将文本分块、提取实体和类型化边,并将它们一起写入图、向量和关系存储。GRAPH_COMPLETION 搜索以向量种子开始查找,遍历匹配的三元组,并将它们交给 LLM 来组成答案。与其他方案不同,Cognee 使构建步骤显式化。你决定何时重建图,而不是在每次写入时重建,并且开启时序模式后,新旧位置作为带日期的事件共存。

Cognee 还添加了两个功能。第一,本体论对齐(ontology grounding)。一个 OWL/RDF 解析器根据提供的本体论验证 LLM 提取的实体,并为每个节点标记 ontology_valid 标志,因此你可以区分有根据的实体和幻觉实体。第二,基于 dlt(数据加载工具)的结构化数据摄取,它将关系型数据源拉入并自动推导外键边,使数据库成为图的一部分。

5、对比

该表并排回答了文章的两个问题——共同检索和事实变更——加上每个方案的成本和回报。

6、基准测试格局

这些系统在一小部分测试长对话历史回忆和推理的基准上进行评估。以下是每个基准测试的内容。

不出所料,每个厂商自己的基准测试都显示自己获胜。

但这些数字并不直接可比。Mem0 的 92.5 和 Letta 的 74.0 都是 LLM 作为裁判的分数,但每个厂商运行自己的答案模型、裁判模型和裁判提示,在不同的题目子集上(Letta 去掉了对抗类别并使用 gpt-4o-mini),因此差距反映的不仅是记忆系统,还有评估工具本身。Continua AI 的"The LoCoMo Fair Fight"显示,仅更换模型(gpt-4o-mini 到 gpt-4.1-mini)就使分数移动了约10分。LOCOMO 的对话只有约 16k 到 26k token,在现代上下文窗口内,因此分数不能迁移到长智能体任务。Zep 的"Lies, Damn Lies & Statistics: Is Mem0 Really SOTA?"质疑了 Mem0 的 SOTA 声称,认为基准测试有缺陷,且 Mem0 的比较运行了一个错误配置的 Zep 实现。为取代它而构建的新基准——LongMemEval、MemoryArena(arXiv 2602.16313)、Locomo-Plus(arXiv 2602.10715)以及 Vectorize 的 Hindsight——表明该领域已经向前发展,尽管还没有一个巩固为标准。

7、归根结底

基准测试模糊了比较,但这四个背后的设计并不模糊。从数字中退一步,"多少图"的频谱分解为两个它一直在混在一起的问题:读取是否需要遍历,从事实跳到事实来找"谁拥有那只去做了检查的狗",以及写入是否需要在值变更时保留历史

图还需要前期付费。摄取消耗 LLM 调用来提取和解析节点和边,因此成本落在写入上,只在需要遍历或回溯的读取上才获得回报。这种不对称性才是这四个真正在争论的东西。Letta 从未构建图,而 Mem0 在论文显示图变体在单跳和多跳回忆上失败、搜索慢3倍、token 成本2倍之后,也移除了自己的图。Graphiti 和 Cognee 围绕遍历和历史最重要的工作负载构建。

有一个相邻的空间很容易与这些混淆。像微软 GraphRAGLightRAG 这样的文档 RAG 系统也构建知识图谱,但是从静态语料库在单次批量处理中构建,而不是从增量智能体交互中构建。GraphRAG 是 Graphiti 实时摄取的批量重计算对照,而 Cognee 在 HotPotQA 上与 LightRAG 进行基准对比。它们为不同的问题构建了相同的数据结构。


原文链接: Agent Memory Systems and Knowledge Graphs: Letta, Mem0, Graphiti, and Cognee

汇智网翻译整理,转载请标明出处