ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

开源Agent记忆系统实测:Mem0、Zep、Letta等五方案对比与选型

开源Agent记忆系统实测:Mem0、Zep、Letta等五方案对比与选型

做 Agent 开发的朋友应该都有过这种体验:单看推理和工具调用,现在的模型已经挺能打,但只要上下文一断,它立刻失忆。多轮对话里靠提示词还能撑一撑,一旦涉及跨天任务、用户长期偏好、项目上下文,每次都要重新告诉它“你是谁、用户是谁、上次做到哪”。这个痛点催生了 Agent 记忆系统这个细分方向的爆发,尤其开源阵营,最近一年冒出了大量方案。我花了两周时间,从需求梳理到接入测试,把手头能跑起来的开源记忆系统逐一看了一遍,包括 Mem0、Zep、Letta、LangChain 内置 Memory 模块和 Basic Memory,分别做了记忆写入、跨会话召回、时间关系查询、脏数据处理和并发写入的实测。这篇文章就是这次多维对比的完整记录,我会把评测维度、方案差异、接入流程和踩过的坑一次性写清楚。

写对比报告之前,我先说明评测环境,方便你对照复现:Python 3.11、OpenAI 兼容的 embedding 接口、测试数据是模拟一个用户连续 10 天的对话记录,大约 200 条消息,其中有明确的偏好变化、项目进度变更和几条故意混入的脏数据。所有方案都用自托管或本地方式跑,不依赖云服务。不同基础的读者可以各取所需:只想快速了解怎么选型,看第 1 章和第 6 章;想动手接一套,直接跳到第 4 章;已经在用某套方案但总出问题,第 5 章的排查记录应该能帮你省点时间。

1. 为什么 Agent 需要一块独立的记忆层

1.1 模型无状态带来的真实困境

先厘清一个基本问题:Agent 记忆到底在解决什么?

LLM 本身是无状态的。每一次 API 调用,模型看到的只是你这次传进上下文窗口的内容,它不记得上次调用发生过什么。这个特性在产品逻辑上会造成三个很具体的问题:

第一是跨会话断裂。用户周一让你整理一份竞品资料,周五回来想接着精细化讨论,如果系统没有记忆,模型对“整理到哪了、哪些已经确认”完全没有概念,用户只能从头解释一遍。第二是 Token 成本浪费。为了弥补记忆缺失,很多团队选择把历史记录全部塞回上下文,对话一长,每次请求携带的历史消息越来越多,成本和延迟都跟着涨。第三是上下文噪音。历史里不是所有信息都有用,全量塞进去,相关性低的内容会稀释模型注意力,反而降低回答质量。

这个问题的本质是:模型的信息处理能力和长期信息保存能力是分离的。推理能力在模型权重里,而常识之外的、属于具体用户和具体任务的信息,需要外部系统来承接。所以记忆系统不是锦上添花,而是 Agent 架构里和工具调用并列的基础设施。

我习惯把 Agent 记忆分成三类来看:短期记忆,指一次会话内的最近上下文,通常靠滑动窗口解决;长期记忆,指跨会话的用户偏好、事实信息、项目状态,需要持久化存储和检索;工作记忆,指任务执行过程中的中间状态,比如已经调用了哪些工具、当前子任务进行到第几步。本文对比的“记忆系统”,主要解决的是长期记忆和工作记忆这两块,短期记忆大多数 Agent 框架自带管理能力。

1.2 一款称职的记忆层要具备哪些能力

很多人一开始会把“记忆”等价理解为“省钱版 RAG”,就是把历史对话切片、向量化、存进向量库,检索时按相似度捞出来。这个认知可以入门,但离“记忆系统”还差得远。

RAG 擅长的是从静态知识库里检索内容,但记忆是动态的:用户今天说喜欢简洁的 API 设计,下周可能说“其实复杂一点也能接受”;项目上周还在方案阶段,这周已经进入编码。记忆系统需要处理的不只是“存和取”,还包括信息的持续演进。

我在评测中给“合格记忆层”列了几条硬指标:

  • 写入能力:能从对话中抽取值得记忆的结构化事实,而不是把整段对话原样落库。
  • 更新与冲突处理:新信息推翻旧信息时,能合并或替换,而不是两条互相矛盾的记录同时存在。
  • 多级检索:既支持语义相似检索,也能按时间、实体关系、记忆类型过滤。
  • 遗忘与衰减:对过时信息有处理策略,避免记忆库变成垃圾场。
  • 可控与可解释:用户可以查看 Agent 记住了什么,必要时删除或修正某条记忆。
  • 持久化与扩展性:重启不丢,数据量增长后检索性能不明显下降。

后续第 3 章的详细对比,就是按这几条能力拆开逐项验证的。你会发现一个有意思的现象:不同方案在这几条上的取舍完全不同,有的擅长写入环节的智能抽取,有的擅长关系检索,有的干脆把记忆的维护权交给了 Agent 自己。

1.3 我把“多维对比”拆成了哪些维度

这篇报告的标题叫“多维对比”,多出来的维度不是凑数的,直接来自我实际踩过的需求场景。产品同学问的是“哪套能快速接入现有代码”;算法同学关心“召回质量会不会把无关信息捞出来”;后端同学问的是“数据存哪、能不能扛住并发”;还有一类场景很关键——数据隐私,记忆里全是用户隐私,到底能不能完全本地化。

基于这些诉求,最终确定的评测维度包括:接入复杂度、持久化方案、记忆写入机制、检索质量、上下文管理方式、框架集成度、并发与扩展性、数据可控性,以及开源协议与社区活跃度。每个维度不是只看文档参数,而是通过真实调用和问题场景来验证,比如故意制造一条矛盾信息看系统怎么处理,比如接近 200 条消息后测试召回准确率。

用一句话概括结论:没有任何一个方案在所有维度上同时拿满分,它们在架构选择上的差异,决定了各自适合完全不同的应用场景。

2. 主流开源方案概览与快速选型

2.1 五套方案的基本画像

先看我在评测范围内覆盖的五个项目,它们大致代表了当前开源 Agent 记忆的几条技术路线。

第一是 Mem0。它的前身是 embedchain 团队做的项目,定位是“给 Agent 添加长期记忆模块”。它把记忆操作封装成一套简洁的 add、search、update、delete API,底层用 LLM 做关键信息抽取,用向量数据库做语义检索。支持从几十行代码接入 LangChain、LlamaIndex、CrewAI 等主流框架,也提供独立的 REST API,是目前生态位覆盖最全的通用型方案。

第二是 Zep。它的核心卖点是基于 Graphiti 的时序知识图谱记忆,把用户交互中的实体、事件、关系存入图结构,每条关系边上带时间戳。相比普通向量检索,它能回答“用户上次提到这个需求是什么时候”“项目偏好是最近两周才变化的”这类时间敏感问题。Zep 提供自托管的社区版,定位更偏服务端记忆基础设施。

第三是 Letta,原项目名 MemGPT。它的思路和其他几个不同:把 LLM 当成一个带虚拟内存的系统,把记忆分成核心记忆(常驻上下文)和归档记忆(外部存储),并且允许 Agent 通过工具调用自己编辑记忆块。换句话说,它不只是一个记忆库,还是一个带记忆管理能力的 Agent 运行时。

第四是 LangChain 内置的 Memory 模块。严格来说它不是独立项目,而是一组工具函数,包括基于滑动窗口的会话历史、基于摘要的压缩记忆、基于向量存储的检索记忆等几种模式。它最大的优势是如果你已经在用 LangChain,接入成本几乎为零;局限是管理能力和扩展性都比较基础,更适合原型阶段。

第五是 Basic Memory。这是一个基于 MCP 协议的本地记忆服务,把记忆直接写成 Markdown 文件,落到本地目录里,可以用 Obsidian 直接打开和编辑。它的定位非常明确:个人知识管理和轻量 Agent 记忆,隐私性极好,但不太适合需要服务化部署的产品场景。

方案技术形态核心思路适合场景
Mem0独立库/REST 服务LLM 抽取 + 向量检索产品化记忆模块、多框架接入
Zep自托管记忆服务时序知识图谱时间关系与实体关系强的业务
LettaAgent 运行时虚拟上下文与记忆块自编辑研究型 Agent、自主记忆实验
LangChain Memory框架内嵌模块历史窗口/摘要/向量检索LangChain 原型阶段快速验证
Basic MemoryMCP + Markdown本地笔记文件即记忆个人助手、隐私优先场景

2.2 快速选型地图:先判断你的记忆访问模式

选型不要先看功能列表,先回答一个问题:你的 Agent 最频繁的记忆访问模式是什么?

如果你的应用场景是“用户问 Agent 上次我们聊到哪了、用户偏好是什么”,本质是语义召回,Mem0 这类“LLM 抽取 + 向量检索”的方案最顺手,因为它的回答路径最短:记忆写入时已经做了去重和冲突合并,查询时一次 search 就能拿到干净结果。

如果你的业务里时间线和实体关系很重要,比如销售助手需要知道“这个客户最近三个月对哪类产品兴趣上升”,Zep 的时序图谱优势就出来了。向量检索本质上只能回答“语义上像不像”,很难回答“谁和谁在两个时间点之间发生了什么关系变化”,这正是图记忆的擅长领域。

如果你追求的是 Agent 自主性,希望 Agent 在运行过程中自己决定什么该记住、什么该遗忘,Letta 的记忆块自编辑设计是最贴合这个理念的。不过它的心智负担更重,你需要接受“Agent 可能自己改坏记忆”这个风险。

如果你只做个人工具,不是产品级开发,Basic Memory 的体验是最好的。记忆是可读的 Markdown,出了任何问题直接改文件,这种低门槛方案在个人场景下反而最高效。

这里也回应一下很多新手纠结的问题:记忆系统和 Agent 框架是不是绑死的?实测结论是不绑。LangChain 的 Memory 模块确实深度绑定特定框架,但像 Mem0、Zep 这类独立服务,本质上是一个 HTTP 服务或独立库,可以插在任意的“编排层(harness)”和模型之间。你在自研 Agent 框架时,完全可以把记忆服务单独拆出来,用你的 harness 只负责决策循环,记忆只负责状态保持,两边通过 API 通信,逻辑反而更清晰。

3. 核心维度逐项对比

3.1 持久化与存储:数据到底住哪

记忆系统的存储介质,决定了它的部署形态、扩展边界和运维成本。这一项我按实际落库结果做了记录,不是文档里写什么我就信什么。

Mem0 把记忆项持久化在向量数据库里,默认实现方案是 Chroma,也支持切换 Qdrant、Milvus、pgvector 等,元数据和记忆分片信息一起存放在向量库的 payload 中。这意味着你的配套基础设施是“一个向量库”。好消息是几乎所有向量库都支持 Docker 单机起,坏消息是向量库本身的运维并不简单,索引参数、embedding 维度变更、数据备份这些都得自己管。

Zep 的部署要求更重:需要 PostgreSQL 存储结构化数据和向量,图数据部分由 Graphiti 引擎管理,官方推荐用 Docker Compose 一键拉起一套服务。它能承载复杂时序图谱,代价是整体服务依赖更多,部署和升级要考虑的东西明显比单库方案多。

Letta 的记忆块主存储落在 SQLite 或 PostgreSQL 里,向量索引作为附加存储。它的工作方式更接近“应用内置数据库”,自托管时轻量很多,适合单机部署。

LangChain 的内置 Memory 绝大多数实现不提供持久化,进程一重启历史就没了。社区一般会自己接一层 Redis 或数据库,严格意义上它只是内存态工具。

Basic Memory 直接把记忆写成 Markdown 文件。听起来很原始,但它的好处只有真用过才懂:记忆内容完全透明,可以用 Obsidian 的全文搜索、反向链接、图谱视图去翻阅和修订。这种“人在回路”的体验,对个人知识管理场景是很大的加分项。

方案主要存储部署形态运维复杂度
Mem0向量数据库(默认 Chroma)库/服务可嵌入,向量库独立部署中
ZepPostgreSQL + 图引擎Docker Compose 多服务高
LettaSQLite/PostgreSQL单机自托管或多容器低-中
LangChain Memory内存,不持久化进程内低
Basic MemoryMarkdown 文件本地目录极低

3.2 记忆写入:从“存原文”到“抽事实”

记忆系统的智力密集环节其实在写入阶段。同样是一段对话,有的方案原样塞进库里,有的方案会抽取出“用户偏好简洁 API 设计”这样一条干净事实,差异非常大。

Mem0 的写入流程我看下来可以概括为四步流水线:先用 LLM 从新增内容中提取候选事实,然后与已有记忆做相似度比对,第三步做合并和冲突消解,最后写入向量库。默认框架下它还会对记忆做评分和排序,把重要性低的信息排在更靠后。文档里提到的“反思”机制也很有意思,允许你额外指定一条内存指令,让它按你的规则过滤什么该记。比如我加了规则“只记录用户明确表达过的偏好,不要记录我的推测性结论”,实际效果是记忆库里的废话明显少了。

Zep 的写入走的是另一条路线。Graphiti 引擎会把对话中的实体和关系抽取出来,增量写入知识图谱,给每条关系打上时间戳。它的强项在于实体消歧和关系合并:如果用户在两段对话里用不同方式提到同一个项目,图谱可以靠实体对齐把信息归到同一节点下。这个能力在长期运营型产品里很值钱,因为真实世界的用户表达就是碎片化的。

Letta 的思路是让 Agent 自己负责写入。它在系统提示词里维护一组“记忆块”,Agent 可以调用内部工具直接修改这些块的内容、新建归档记忆、把不常用的信息移到外部存储。我从设计角度看,这个方向非常优雅,让记忆机制跟模型自身的上下文管理天然对齐;从工程角度看,风险也明显——Agent 自主读写记忆需要足够的模型能力兜底,弱模型跑这个方案很容易把记忆越改越乱。

LangChain 内置方案的处理方式最简单粗暴:Buffer 模式就是保留最近 N 轮,Summary 模式是用 LLM 定期压缩历史生成摘要,VectorStoreRetriever 模式把历史按相似度召回。它们是“够用”的方案,但都没有冲突处理和事实抽取的概念,记忆库里出现自相矛盾是常态。

3.3 检索与上下文管理:哪些记忆会被带进上下文

记忆写好了,下一步是怎么取。这里最关键的差别在于:检索结果如何进入上下文,又以什么形式进入。

Mem0 的检索链路是:先用 embedding 做向量相似度召回,再做重排序,同时支持按时间衰减、用户维度、元数据过滤。实测下来,它对“用户的一般性偏好”召回很稳,比如我连续加了 30 条不同主题的记忆,再问“用户喜欢什么风格的代码”,能稳定把对应事实捞回来。时间衰减参数默认不开启,需要适配场景自己配,比如做客服系统,三个月前的偏好显然权重更低,应该开启衰减。

Zep 的检索走图谱遍历,不只是算向量相似度。它能做的查询类型比纯向量方案多一个维度:时间。比如我问“用户上周提到过哪几个外部系统”,它能沿着带时间戳的关系边把指定时间窗口内的事件拉出来。这就是它相比 Mem0 最大的差异化价值。代价是检索链路更重,首批初始化图谱阶段会产生大量 token 消耗,环境冷启动速度也比纯向量库慢。

Letta 的上下文管理是所有方案里最有“操作系统感”的。它把常驻记忆放在上下文内的固定位置,Agent 每次处理任务时能看到自己的记忆块;归档记忆则放在外部,需要时通过工具调用把相关片段加载进上下文。这套机制有效避免了“所有历史全塞上下文”的问题,记忆的进出是显式的工具调用,而不是隐式的相似度嵌入。

在上下文管理上,我强烈建议所有产品都做一道过滤:不是所有检索到的记忆都值得注入系统提示词。实测 Mem0 和 Zep 都支持返回记忆的来源、类型和时间戳,你可以在业务层做二次筛选,只把置信度高且与当前任务强相关的记忆拼进上下文。默认全量注入,短期没事,对话一长上下文里的记忆噪音会越来越大。

3.4 框架集成与扩展性:别让记忆系统绑架架构

再好的记忆系统,接不进去也是白搭。这一项我按“能不能脱离特定框架独立存在”来评分。

Mem0 的集成面最广。它既可以被 Python/JS 代码直接 import 作为库,也可以作为独立服务起 HTTP 接口,官方维护了 LangChain、LlamaIndex、CrewAI 等组件的桥接。这意味着自研 harness 还是用现成框架,它都能插进去。Zep 是纯服务形态,提供 REST API 和官方 SDK,天然适合微服务架构,记忆服务与 Agent 运行时分离部署。Letta 自带完整的 Agent 运行时,如果用它自带的记忆能力,接入现有框架反而多一层,更适合“整套用 Letta”的场景。

LangChain 的 Memory 模块不需要额外部署,但也因此被绑定在 LangChain 生态里。如果你后续迁移到其他编排框架,这套记忆代码基本要重写。Basic Memory 走 MCP 协议,这个身份让它能接入任何支持 MCP 的客户端,包括各类桌面助手和自定义 harness,扩展思路很轻巧。

最后聊一下并发。我有意做了并发写入测试:同时发起 20 个写入请求。Mem0 因为默认存储过程包含“读取现有记忆-LLM 合并-写回”三步,并发下容易出现最后写入覆盖先写入的丢更新问题,生产环境需要队列和锁,或者用服务端的批量接口来规避。Zep 的服务端架构相对成熟,Graphiti 的索引更新有提交机制,并发表现更稳定,但代价是吞吐量和延迟会比轻量方案高。Letta 的自动记忆编辑在并发场景里风险最大,多个 Agent 同时改同一组记忆块会发生冲突,建议每个用户独立会话实例。Basic Memory 就别提并发了,它本来就不是为并发设计的。

4. 实操:三套方案的接入全流程

这一章给出我在本地真实跑通的接入流程,默认你有基本的 Python 环境和 Docker,能访问 OpenAI 兼容的接口。注意不同版本的项目 API 会迭代,以下代码以我当时跑通的版本为准,版本变化以官方文档为准。

4.1 Mem0:最快接通的通用记忆层

先安装依赖:

pip install mem0ai openai

初始化时指定 LLM 与 embedding 模型。我用的是 OpenAI 兼容接口,所以用 provider=openai 写法,实际换成任意兼容服务时只需要调整 base_url 参数。

from mem0 import Memory config = { "llm": { "provider": "openai", "config": { "model": "gpt-4o-mini", "api_key": "YOUR_API_KEY" } }, "embedder": { "provider": "openai", "config": { "model": "text-embedding-3-small", "api_key": "YOUR_API_KEY" } } } memory = Memory.from_config(config) # 写入记忆 memory.add( "用户说:我平时主要处理 Rust 后端项目,喜欢简洁的 API 设计。", user_id="u_1001", metadata={"source": "chat_session_20250110"} ) # 检索记忆 hits = memory.search("用户的技术栈偏好是什么?", user_id="u_1001", limit=5) for hit in hits: print(hit["memory"])

实测中我故意做了交叉验证:先写入“用户喜欢简洁 API”,再写入“用户最近接受了复杂接口方案”,再问“用户的 API 设计偏好”,它返回的是更新后的结论,说明冲突合并机制真实生效,而不是两条同时返回让上层自己纠结。这是 Mem0 作为通用记忆层最值得肯定的地方。

接入 LangChain 时更简单,官方提供了适配器,只需要把 memory 实例注册给 agent,后续对话会自动写入和取回。整体体验是:如果一个团队要在两三天内给现有 Agent 无缝加上长期记忆,Mem0 是效率最高的选择。

4.2 Zep:给记忆加上时间轴

Zep 推荐用 Docker Compose 拉起整套服务,官方仓库里有现成的 compose 文件,启动后等服务健康检查通过即可。

docker compose up -d

连接客户端并写入测试记忆:

from zep.client import Zep client = Zep(base_url="http://localhost:8000", api_key="local_key") # 建立会话 client.memory.add_session("session_agent_test") # 写入一段对话 client.memory.add( "session_agent_test", [ {"role": "user", "content": "本周我计划先完成记忆模块的选型评估"}, {"role": "assistant", "content": "好的,我会记录这个计划"} ] ) # 语义检索 res = client.memory.search("这周的计划是什么", session_id="session_agent_test") print(res.messages)

我真正关注的是时间查询能力。测试数据里我故意塞了一句“上周提过要对比三个消息队列”,隔几天又提到“消息队列对比已完成,改用 Kafka”。Graphiti 图谱上这两个事件的关系边带了明确时间戳,检索“用户最近一次提到消息队列是什么状态”时,返回的是更新后的状态,而不是把两条历史都平铺给你。普通向量库做不到这种程度的时间感知,这是 Zep 最核心的差异化。

需要提醒的是,Zep 的资源占用明显高于 Mem0,一个小型 demo 就要两个服务容器加一个图引擎进程,首次建图时 embedding 和 LLM 抽取的 token 消耗也不低。如果不是强时间关系场景,不建议为了“显得专业”硬上这把牛刀。

4.3 Letta:让 Agent 自己管理记忆

Letta 的安装和启动很简单:

pip install letta letta run

启动后通过交互式 CLI 创建 Agent,可以选预置的 agent 模板。它的记忆机制是显式的:系统提示词里会渲染一块“core memory”,包含人格设定、用户信息、任务进度等记忆块;Agent 在对话过程中可以调用内部工具修改这些块。我在测试里让它记住“我偏好中国风和低饱和配色”,当场问它记住了什么,能准确说出来;隔一天重启再问,通过本地 SQLite 持久化依然能召回。

这个方案最打动我的是记忆块的暴露程度。因为记忆以结构化块的形式存在于上下文里,出了问题可以直接 dump 出来看,甚至手动改掉某块。对研究型项目或者想深入理解“Agent 记忆应该长什么样”的人来说,体验非常好。

但它不适合直接拿来当纯记忆库用。它是一个完整的 Agent 运行时,如果你已经有自己的编排逻辑和工具调用循环,只想要个记忆模块,Letta 会显得比较重,强行接入成本不低。我的建议是:要么整个方案基于 Letta 构建,要么就用 Mem0/Zep 这类独立记忆层,别试图把 Letta 拆成零件。

5. 常见问题与排查技巧实录

5.1 记忆污染比没有记忆更可怕

我在测试中用错误数据模拟了一次真实事故:让模型抽取记忆时把“用户说的是他同事的偏好”记成了“用户的偏好”。结果这条错误记忆进入库后,后续所有相关检索都会把它捞出来,回答质量明显下降。

这个问题是所有 LLM 抽取类记忆系统的通病,核心原因在于抽取模型对指代消解不敏感。我的解决办法是三层防御:第一,在写入的 metadata 里打上来源会话 ID 和抽取置信度,后续可以追溯和批量清理;第二,利用 Mem0 这类方案的自定义指令能力,在初始化时明确“只记录用户第一人称明确表达的内容”;第三,建立定期复核机制,把记忆库导出成可读格式人工抽查。自研系统如果不做来源追踪,记忆污染问题后期会越积越重。

5.2 检索召回不准:先别急着换向量库

召回质量差,很多人第一反应是换更好的 embedding 模型。但我实测发现,大部分召回不准的问题出在检索链路的参数和前置数据质量,而不是模型本身。

第一个坑是相似度阈值没调。Mem0 默认返回的 top_k 结果里可能夹杂大量低分项,如果业务是问答生成,低分记忆注入上下文反而制造噪音。我建议在接入时先跑一批样本,看正常命中的相似度分布,把阈值设在高分段的底部,而不是完全依赖 top_k。

第二个坑是没做记忆类型过滤。如果你把“用户偏好”和“项目进度”两类记忆存在同一个命名空间,查询项目进度时偏好类信息也会被捞出来。Mem0、Zep 都支持按 metadata 过滤,查询时显式带上类型条件,召回准确率会立刻改善。

第三个坑是时间衰减没开。做长期运营的产品,三个月前的一条弱相关记忆不应该影响当前判断。开启时间衰减或者做时间粒度降权,效果比换 embedding 模型明显得多。

5.3 并发写入丢更新:记忆系统也要上锁

前文提到并发写入丢更新的问题。我实测 Mem0 单进程并发写 20 次,部分后写请求会基于过期快照做合并,导致先写的内容被静默覆盖。这在单用户场景看不出来,一旦做多用户产品,就是线上事故。

常规解法是给记忆写入加分布式锁或队列,把同一 session 的写入串行化。另一个思路是为记忆操作引入版本号,写入时带上期望的版本,版本不匹配就重试。Zep 的服务端架构在这一点上更省心,但如果你自研或者用 Mem0 这类库,一定要在设计评审阶段把写并发问题考虑进去。Agent 场景的写入是重操作,每一条都要过 LLM 抽取,吞吐量天然不如普通数据库写入,这决定了记忆系统的并发设计思路不能照搬常规 Web 应用。

5.4 一个小坑清单

我把自己踩过的小坑整理成速查表,供各位对照。

现象可能原因解决办法
重启后记忆全部消失使用了进程内的 LangChain Memory换成持久化记忆库或自建 Redis 持久层
检索结果与问题无关相似度阈值过低或未过滤记忆类型打印相似度分数,重新校准阈值,按 metadata 过滤
记忆里出现主观推测抽取时没有自定义指令约束在初始化配置中加入“只记录明确表达的事实”指令
同一事实多个版本并存写入阶段缺少冲突合并优先选带 LLM 冲突消解机制的方案,或自建合并逻辑
首次运行 token 消耗巨大图谱初始化或历史回放抽取控制首批回放长度,分批建图
单个容器内存占用过高向量库默认索引参数过大调整索引参数,限制批量大小

5.5 开源协议与版权复核

最后补一个容易忽略的点:开源不等于随便用。我在选型时会把每个项目的 LICENSE 文件逐行看一遍,尤其是涉及商用场景时。Mem0、Letta 这类核心项目采用宽松许可证的情况比较多,但 Zep 这种既有开源版又有商业云服务的项目,协议条款会更复杂,可能存在“额外限制用于提供同类服务”之类的条款。这不算坑,但一定要在项目启动前确认清楚,否则后面换架构的成本很高。

6. 绕了一圈,我的选型建议与实在话

跑完这一轮对比,我的核心体会是:选记忆系统,本质是在选“记忆的访问模式”。没有万能方案,但可以用几个边界条件快速圈定范围。

如果你在做一个要长期运营的 C 端产品,用户画像和兴趣偏好的记忆是核心,我建议优先看 Mem0。它的抽取、合并、检索链路最完整,社区活跃度高,踩坑的人多,经验沉淀也足,团队在遇到问题时能找到参考。如果你 90% 的 Agent 交互都围绕“谁在什么时候对什么做了什么”展开,比如 CRM、客服工单、项目管理助手,Zep 值得花成本去部署。如果你们团队技术能力强,希望 Agent 具备真正的自主记忆管理能力,愿意接受模型自主编辑记忆带来的不确定性,Letta 是一个值得研究的方向。如果只是做个个人助理或者笔记型 Agent,别犹豫,Basic Memory 的本地 Markdown 体验是最好的。至于 LangChain 内置 Memory,它只适合原型验证,生产环境我不建议依赖它独立扛记忆。

最后分享两个我个人的实操习惯。第一,无论选哪套方案,都要先定义“什么值得记”。我在接入 Mem0 时就吃了亏,刚开始配置宽松,它把大量无意义的寒暄也抽成了记忆,库里很快堆满垃圾。后来加了检索规则和写入约束,质量立刻上来。第二,记忆系统要留人工出口。生产环境里一定要提供“查看 Agent 记住了什么”的入口,用户一句“你删掉关于我的那条记录”应该是系统能力,而不是公关话术。这一点做好了,隐私合规的压力会小很多。

如果你正在给自己的 Agent 接记忆,希望这份对比能让你少走两天弯路。方案不用贪多,先确定你的数据访问模式,再回去翻对应的那章,照着接入就行。

返回列表