> ## Content Index
> Fetch the complete content index at: https://www.hubwiz.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# 4个主流智能体记忆系统的对比
- URL: https://www.hubwiz.com/blog/4-popular-agent-memory-systems-compared/
- Published: 2026-05-29T15:51:17.000Z
- Updated: 2026-10-13T15:18:14.000Z
- Description: 深入探讨四种长期智能体记忆方案，从文本块到时序图谱：Letta、Mem0、Graphiti 和 Cognee。
- Author: admin
- Tags: AGENT, MEMORY, #Import 2026-10-14 14:41

四个流行的智能体记忆库对同一个设计问题各自选择了不同的答案：智能体应该如何跨会话记忆信息？[Letta](https://github.com/letta-ai/letta?ref=hubwiz.com) 编辑纯文本块和文件。[Mem0](https://github.com/mem0ai/mem0?ref=hubwiz.com) 维护一个带有实体提示的向量存储。[Graphiti](https://github.com/getzep/graphiti?ref=hubwiz.com) 将事实索引为带时间戳的关系。[Cognee](https://github.com/topoteretes/cognee?ref=hubwiz.com) 运行一个实体提取流水线。

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

![概览](https://www.hubwiz.com/blog/content/images/2026/05/https-3A-2F-2Fsubstack-post-media.s3.amazonaws.com-2Fpublic-2Fimages-2Fe2527327-ae92-4285-b4db-241dd970780e_1294x320.png)

Letta 是一个完整的智能体框架，为你运行智能体。Mem0、Graphiti 和 Cognee 是你可以挂接到自己智能体上的记忆层。四个项目都在其开源版本之上运行付费云服务（[Letta Inc.](https://www.letta.com/?ref=hubwiz.com)、[Mem0 Inc.](https://mem0.ai/?ref=hubwiz.com)、[Zep](https://www.getzep.com/?ref=hubwiz.com)、[Topoteretes](https://www.cognee.ai/?ref=hubwiz.com)），各自都有超出开源版本的功能。本文覆盖的是开源版本。

## **1、Letta (MemGPT)：自编辑文本块**

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

![Letta 架构](https://www.hubwiz.com/blog/content/images/2026/05/https-3A-2F-2Fsubstack-post-media.s3.amazonaws.com-2Fpublic-2Fimages-2F53b335ce-f56d-4ae9-8c1a-8347d78adbaa_1254x692.png)

智能体通过工具调用来编辑自己的记忆。编辑接口是一小部分函数：`core_memory_replace`、`memory_replace`、`memory_insert`、`memory_apply_patch` 和 `memory_rethink`。检索也是由智能体驱动的，通过 `archival_memory_search` 和 `conversation_search`，加上文件系统的 `open_files` 和 `grep_files`。

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

[functions/function\_sets/base.py:263-280](https://github.com/letta-ai/letta/blob/0.16.8/letta/functions/function%5Fsets/base.py?ref=hubwiz.com#L263-L280)

```
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 agents**（`letta/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?"](https://www.letta.com/blog/benchmarking-ai-agent-memory?ref=hubwiz.com) 文章（2025年8月）将 [LOCOMO](https://snap-research.github.io/locomo/?ref=hubwiz.com)（一个多会话对话回忆基准测试）的对话记录转储到附加在一个普通智能体上的文件中，得分 74.0%，高于 Mem0 图变体的 68.5%（[arXiv 2504.19413](https://arxiv.org/abs/2504.19413?ref=hubwiz.com)，2025年4月）。Letta 认为智能体在训练后已经擅长迭代文件搜索，因此专门的记忆系统增加的价值很小。

## **2、Mem0：去掉图，加入实体链接**

Mem0 开始时有一个可选的图层，然后在 v3 开源重写中将其移除。这个删除仅适用于开源版本。Mem0 的[托管平台](https://docs.mem0.ai/platform/overview?ref=hubwiz.com)仍然列出图记忆和基于时间的衰减作为功能。

图记忆通过 [PR #1718](https://github.com/mem0ai/mem0/pull/1718?ref=hubwiz.com) 作为一个可选层引入，然后在2025年扩展到支持五种图数据库：Neo4j、内存中的 Memgraph、嵌入式 Kuzu、AWS 托管的 Amazon Neptune，以及 Apache AGE（Postgres 的图扩展）。v3 流水线在提交 `a488e190`（[PR #4805](https://github.com/mem0ai/mem0/pull/4805?ref=hubwiz.com)，2026年4月14日合并）中移除了该模块。

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

![](https://www.hubwiz.com/blog/content/images/2026/05/image-308.png)

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

[memory/main.py:1487-1489](https://github.com/mem0ai/mem0/blob/v2.0.4/mem0/memory/main.py?ref=hubwiz.com#L1487-L1489)

```
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](https://arxiv.org/abs/2504.19413?ref=hubwiz.com)，2025年4月）在 LOCOMO 上对图变体 Mem0g 与纯向量 Mem0 进行了基准测试，图很少能证明其成本是值得的。

![Mem0 基准测试](https://www.hubwiz.com/blog/content/images/2026/05/https-3A-2F-2Fsubstack-post-media.s3.amazonaws.com-2Fpublic-2Fimages-2F6c071805-b330-4863-9b22-9413b811a706_862x396.png)

图变体在总分上略胜，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](https://github.com/getzep/graphiti/blob/v0.29.1/graphiti%5Fcore/edges.py?ref=hubwiz.com#L271-L279)

```
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](https://github.com/getzep/graphiti/blob/v0.29.1/graphiti%5Fcore/utils/maintenance/edge%5Foperations.py?ref=hubwiz.com#L569-L571)

```
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 摘要以保持亚秒级延迟。

![Graphiti 架构](https://www.hubwiz.com/blog/content/images/2026/05/https-3A-2F-2Fsubstack-post-media.s3.amazonaws.com-2Fpublic-2Fimages-2Fdce0b152-de1d-4cb8-ba4c-d6104c869e40_1198x732.png)

成本很高。单个 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](https://github.com/topoteretes/cognee/blob/v1.1.0/cognee/api/v1/cognify/cognify.py?ref=hubwiz.com#L316-L344)

```
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](https://github.com/topoteretes/cognee/blob/v1.1.0/cognee/modules/chunking/models/DocumentChunk.py?ref=hubwiz.com#L10-L37)

```
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_of` 和 `contains` 看起来像普通的类型提示，但 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 流水线](https://www.hubwiz.com/blog/content/images/2026/05/https-3A-2F-2Fsubstack-post-media.s3.amazonaws.com-2Fpublic-2Fimages-2F4593242a-6b31-4dca-ba1b-c2399f3628ea_1306x474.png)

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

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

## **5、对比**

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

![对比表](https://www.hubwiz.com/blog/content/images/2026/05/https-3A-2F-2Fsubstack-post-media.s3.amazonaws.com-2Fpublic-2Fimages-2F2c417475-c336-49ce-94c1-63f6d6dfa88f_1496x754.png)

## **6、基准测试格局**

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

- **LOCOMO**（[arXiv 2402.17753](https://arxiv.org/abs/2402.17753?ref=hubwiz.com) / [snap-research.github.io/locomo](https://snap-research.github.io/locomo/?ref=hubwiz.com)）测试超长多会话对话的回忆和推理，分为单跳、多跳（组合在不同会话中陈述的事实）、时序、开放域和对抗类别。由 [Mem0](https://mem0.ai/research?ref=hubwiz.com)、[Graphiti (Zep)](https://www.getzep.com/mem0-alternative?ref=hubwiz.com) 和 [Letta](https://www.letta.com/blog/benchmarking-ai-agent-memory?ref=hubwiz.com) 报告。
- **LongMemEval**（[arXiv 2410.10813](https://arxiv.org/abs/2410.10813?ref=hubwiz.com) / [xiaowu0162.github.io/long-mem-eval](https://xiaowu0162.github.io/long-mem-eval/?ref=hubwiz.com)）在长聊天历史上运行500个问题，测试五种能力：信息提取、多会话推理、时序推理、知识更新和弃权。由 [Mem0](https://mem0.ai/research?ref=hubwiz.com) 和 [Graphiti (Zep)](https://arxiv.org/abs/2501.13956?ref=hubwiz.com) 报告。
- **HotPotQA**（[arXiv 1809.09600](https://arxiv.org/abs/1809.09600?ref=hubwiz.com) / [hotpotqa.github.io](https://hotpotqa.github.io/?ref=hubwiz.com)）是基于 Wikipedia 的多跳问答，每个答案需要跨两个或更多段落的推理，以精确匹配和 F1 评分。由 [Cognee](https://www.cognee.ai/blog/deep-dives/ai-memory-evals-0825?ref=hubwiz.com) 报告。
- **BEAM**（[arXiv 2510.27246](https://arxiv.org/abs/2510.27246?ref=hubwiz.com)，ICLR 2026）探测多达 10M token 对话中的事实跟踪、信息更新、矛盾解决和时序顺序，一个测试套件涵盖十种记忆能力。由 [Mem0](https://mem0.ai/research?ref=hubwiz.com) 报告。

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

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

## **7、归根结底**

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

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

有一个相邻的空间很容易与这些混淆。像微软 [GraphRAG](https://arxiv.org/abs/2404.16130?ref=hubwiz.com) 和 [LightRAG](https://arxiv.org/abs/2410.05779?ref=hubwiz.com) 这样的文档 RAG 系统也构建知识图谱，但是从静态语料库在单次批量处理中构建，而不是从增量智能体交互中构建。GraphRAG 是 Graphiti 实时摄取的批量重计算对照，而 Cognee 在 HotPotQA 上与 LightRAG 进行基准对比。它们为不同的问题构建了相同的数据结构。

---

原文链接: [Agent Memory Systems and Knowledge Graphs: Letta, Mem0, Graphiti, and Cognee](https://codepointer.substack.com/p/agent-memory-systems-and-knowledge)

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

> **这是「Agent / MCP」专题的一部分。**完整地图见：[Agent / MCP / 自动化完全指南](https://www.hubwiz.com/blog/agent-stack/)