你跟 AI 助手聊了半小时,把项目背景、技术栈、命名规范、个人偏好全交代清楚。第二天新开一个会话,它全忘了,你还得从头复述一遍。这是 2026 年多数 agent 的常态:上下文窗口一关,记忆归零。短会话够用,但凡要跨天、跨项目做连续协作,没有长期记忆根本跑不通。
这篇文章走一遍给 agent 接长期记忆的实操流程:为什么失忆、mem0 怎么接、Letta 怎么接、两者怎么选、何时该用长期记忆而非 RAG 或纯靠上下文窗口。每一步给真实命令和可复制的 prompt,最后附踩坑记录和 FAQ。和本站写过的 agent 记忆工具横评 互补:那篇讲怎么选,这篇讲选完之后怎么真正搭起来。如果你还在评估阶段,也可以先看 RAG 评估 SOP 量化检索质量,或对照 Dify 知识库 RAG 搭建 SOP 理解 RAG 路线。
一、先搞清楚 agent 为什么会失忆
失忆的根因不是模型不够聪明,而是上下文窗口的物理限制。哪怕窗口开到上百万 token,三个问题绕不开:
- 窗口是易失的:一次会话结束,窗口清空,下次对话从零开始。
- 窗口是有限的:长对话越堆越满,检索精度下降,还会触发截断,关键信息被挤掉。
- 窗口不区分谁说的:用户偏好、事实结论、闲聊废话全混在一起,无法按需召回。
长期记忆解决的是这三件事:把值得记的信息抽取出来、存到外部、下次对话按需检索召回。它不是替代上下文窗口,而是在窗口外面加一层持久存储,让信息能跨会话存活下来。判断标准很简单:这条信息下次会话还要不要用?要,就写进记忆;不要,留在窗口里随它过期。
二、mem0 实操:五分钟给 agent 加记忆层
mem0(读 mem-zero)是目前最主流的 agent 记忆库,GitHub 6.2 万 star,Apache-2.0 协议,YC S24 项目。定位是"AI agent 的通用记忆层",核心思路是用一个 LLM 自动从对话里抽取事实,存进向量库,下次按语义检索召回。2026 年 4 月它换了新算法,在 LongMemEval 基准上从 67.8 涨到 94.4,单次检索 token 消耗约 6.8K。
安装与最小可用示例
# 安装库(Python)
pip install mem0ai
# 要用混合检索(BM25 关键词 + 实体抽取),加 nlp 扩展
pip install mem0ai[nlp]
python -m spacy download en_core_web_smmem0 默认用 OpenAI 的 gpt-5-mini 做抽取、text-embedding-3-small 做向量化,所以要先配好 OPENAI_API_KEY。想换成别的模型看官方文档的 LLM/embedder 配置。
from openai import OpenAI
from mem0 import Memory
openai_client = OpenAI()
memory = Memory() # 默认本地配置,user_id 区分不同用户
def chat_with_memories(message: str, user_id: str = "default_user") -> str:
# 1. 先按当前问题检索相关记忆
relevant = memory.search(
query=message, filters={"user_id": user_id}, top_k=3
)
memories_str = "\n".join(
f"- {entry['memory']}" for entry in relevant["results"]
)
# 2. 把记忆拼进 system prompt
system_prompt = (
"You are a helpful AI. Answer based on query and memories.\n"
f"User Memories:\n{memories_str}"
)
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": message},
]
response = openai_client.chat.completions.create(
model="gpt-5-mini", messages=messages
)
assistant_response = response.choices[0].message.content
# 3. 把这轮对话写回记忆(mem0 自动抽取事实)
messages.append({"role": "assistant", "content": assistant_response})
memory.add(messages, user_id=user_id)
return assistant_response三个 API 就是全部:add 写记忆、search 检索、user_id 隔离用户。memory.add() 不是把原始对话原样塞进去,而是内部用一个 LLM 调用把事实抽出来("用户偏好深色模式""项目用 TypeScript"),再存向量库。这就是它比"把聊天记录全存库"高效的原因:存的是提炼后的事实,不是冗长的原文,检索时 token 消耗能压到 7K 以内。
2026 年 4 月的新算法有几个关键变化值得知道:一是 ADD-only 模式,记忆只增不删,一次 LLM 调用搞定抽取,不再做 UPDATE/DELETE;二是实体链接,抽出来的实体会被 embedding 并跨记忆关联,检索时能"顺藤摸瓜";三是多信号融合检索,语义向量、BM25 关键词、实体匹配三路并行打分再融合,比单跑语义检索准很多;四是时间感知,查询"现在用什么"和"上个月用什么"能返回不同记忆实例。
检索调优:别默认配置一把梭
memory.search() 默认 top_k=3,只取最相关 3 条。调它有三个旋钮:top_k 调召回数量(3-10,多了噪音多少了漏召回);filters 按用户/会话/agent 维度过滤;混合检索要装 mem0ai[nlp] 扩展否则只有语义检索。建议第一批记忆进来后,先跑一组"问题-期望命中"的测试,按召回率调 top_k,别拍脑袋设值。检索质量怎么量化,参考本站 RAG 评估 SOP 的测试集思路,把"问题-期望记忆"当评估集跑命中率。
自部署 vs 托管云
| 库(pip) | 自部署服务 | 云平台 | |
|---|---|---|---|
| 适合 | 原型验证 | 团队自有基础设施 | 零运维生产 |
| 启动 | pip install mem0ai | docker compose up | 注册 app.mem0.ai |
| 面板 | 无 | 有 | 有 |
| 数据出境 | 本地 | 本地 | 托管 |
自部署一条命令拉起整套服务(含面板、API、向量库),默认监听 http://localhost:3000。数据敏感、不能出境的团队走自部署;想最快跑通用 pip 库即可。
CLI 快速验证
不想写代码,先用 CLI 验证流程:
npm install -g @mem0/cli # 或 pip install mem0-cli
mem0 add "Prefers dark mode and vim keybindings" --user-id alice
mem0 search "What does Alice prefer?" --user-id alice三、Letta 实操:带记忆的有状态 agent
Letta(前身 MemGPT)走的是另一条路:它不只给 agent 加记忆层,而是直接给你一个"有状态的 agent runtime"。GitHub 2.4 万 star,Apache-2.0。核心差异是 Letta 让 agent 自己管理记忆--什么该记、什么该忘、何时翻档案,agent 内部自己决策,更接近"会自我进化的 agent"。mem0 是"你帮 agent 存取记忆",Letta 是"agent 自己存取记忆"。
安装与起一个 agent
Letta 推荐用新的 Letta Code CLI(需 Node.js 22.19+):
npm install -g @letta-ai/letta-code
letta # 终端里直接起一个带记忆的 agent要在自己应用里嵌 agent,用 Agent SDK:
npm install @letta-ai/letta-agent-sdkimport { LettaAgentClient } from "@letta-ai/letta-agent-sdk";
const client = new LettaAgentClient({
backend: "cloud", // 或 "local" 全本地跑
apiKey: process.env.LETTA_API_KEY,
});
// 建一个有记忆的 agent,指定模型和人设
const agentId = await client.createAgent({
model: "anthropic/claude-opus-4-8",
human: "Name: Alice. Role: PM.",
persona: "I am a helpful assistant that remembers context.",
});
// 发消息并流式接收
await using session = client.resumeSession(agentId);
await session.send("What do you know about me?");
for await (const message of session.stream()) {
if (message.type === "assistant") console.log(message.content);
}backend: "local" 让 agent 全程在本地跑,不经云;"cloud" 走 Letta 的 Constellation。模型不绑死,Anthropic、OpenAI、zAI 都能接,官方有模型榜单推荐。如果你在用旧版 V1 API,Python 用 letta-client、TypeScript 用 @letta-ai/letta-client,新项目官方建议直接上 Agent SDK。
Letta 的记忆架构和 mem0 哲学不同:它给 agent 一块"记忆区"(memory block),agent 像管理自己的笔记一样往里读写。好处是 agent 能自己判断什么值得记、什么时候该翻旧账,适合需要长程规划和自我进化的任务;代价是你对记忆的控制权变弱,调试时不太好直接看"它到底记了啥"。如果你要的是精确可控的记忆存取,mem0 更顺手;如果你要的是"丢给 agent 它自己成长",Letta 更合适。
写记忆抽取的 prompt
不管用哪个工具,记忆抽取质量取决于 prompt。给你一个可复制的模板,让大模型从对话里提炼结构化记忆:
你是一个记忆抽取器。读下面的对话,提取值得长期记住的事实。
规则:
1. 只抽事实,不抽闲聊和过程话("你好""我来查一下"不要);
2. 每条记忆一个短句,主语明确(用户偏好/项目事实/已做决定/待办);
3. 区分"偏好型"和"事实型",加前缀 [偏好] 或 [事实];
4. 去重:和已知记忆语义重复的不要重复抽;
5. 带时间戳:能推断出时间的标上日期。
输出:每行一条,不要编号,不要解释。
对话:
{对话内容}
已知记忆(用于去重):
{已有记忆}抽出来的记忆再喂给 memory.add() 或存进 Letta。关键是第 4 条去重--不做的话记忆库会迅速膨胀,检索噪音直线上升。
四、mem0 vs Letta vs 纯 RAG:怎么选
三者不是互斥,是不同层次。下表按真实部署维度对比:
| 维度 | mem0 | Letta | 纯 RAG(如 Dify 知识库) |
|---|---|---|---|
| 定位 | agent 记忆层 | 有状态 agent runtime | 外部知识检索 |
| 记什么 | 用户偏好、交互历史 | 同左 + agent 自我进化 | 静态文档 chunks |
| 谁管记忆 | 你的代码存取 | agent 自己决策 | 检索管道 |
| 安装 | pip install mem0ai | npm i @letta-ai/letta-agent-sdk | Docker 全栈 |
| 上手难度 | 低 | 中 | 中 |
| 适合 | 给现有 agent 加记忆 | 做长程自主 agent | 喂静态知识库 |
| 开源协议 | Apache-2.0 | Apache-2.0 | 看具体平台 |
一句话:已有 agent 想加记忆,选 mem0;要从零做一个会自我进化的长程 agent,选 Letta;要喂的是产品手册、公司文档这类静态知识,选 RAG。 很多生产 agent 两个都要:mem0/Letta 记交互记忆,RAG 检索外部知识。
五、何时用长期记忆 vs RAG vs 上下文窗口
这是最常被搞混的决策点。给你一个判断框架:
- 上下文窗口:当前这轮会话内、马上要用、用完就丢的信息。例:用户这一轮贴的代码片段。成本最低,不用接任何东西。
- RAG:外部静态知识,"模型不知道但可以查到"的。例:产品手册、API 文档、公司规章。信息源是文档,更新频率低,按 chunk 检索。详见本站 RAG 评估 SOP。
- 长期记忆:跨会话的用户态信息,"模型该记住但窗口关了就丢"的。例:用户偏好、历史决策、项目背景。信息源是对话本身,持续更新。
判断口诀:问"下次还要不要用"。不要,留窗口;要,再问"是外部知识还是用户自己的事"。外部知识走 RAG,用户的事走长期记忆。 三者叠加才是完整方案:窗口管当下,RAG 管外部知识,长期记忆管用户上下文。
六、踩坑速查
坑一:记忆库膨胀不清洗。 mem0 新算法是"只增不删"的 ADD-only 模式,记忆只积累不覆盖。跑久了库里全是语义重复的旧记忆,检索精度下滑、延迟上升。解法:定期跑一遍去重和合并,或设过期策略,关键信息变更时手动触发记忆刷新。建议给记忆库设个"体检"周期,比如每周跑一次去重脚本,别等检索明显变慢才处理。
坑二:把闲聊也当记忆存。 抽取 prompt 没写好,"你好""收到"也进了记忆库。解法:用上面的抽取模板,明确只抽事实、加 [偏好]/[事实] 前缀、强制去重。
坑三:记忆不做用户隔离。 多用户场景忘传 user_id,A 的偏好串到 B 的会话里。mem0 和 Letta 都支持 user/agent 隔离,但默认不强制--上线前务必在每个 add/search 都带上 user_id 或对应隔离字段。
坑四:把长期记忆当 RAG 用。 把几百份产品文档全塞进 mem0,当知识库用。结果是检索又慢又不准--记忆库设计目标是高频读写的交互记忆,不是大批量静态文档检索。静态知识老老实实走 RAG,别让记忆库干它不擅长的活。
坑五:自部署忘了配默认 LLM。 mem0 本地默认调 OpenAI,OPENAI_API_KEY 没配或配错,memory.add() 静默失败(不报错但没存进去)。解法:第一次跑完手动 memory.search() 验证有没有真的存进去,别假设成功。
常见问题
Q:mem0 和 Letta 必须二选一吗? A:不必,但通常一个项目主用一个。mem0 是记忆层,往现有 agent 上贴;Letta 是 agent runtime,自带记忆能力。已有 agent 想加记忆用 mem0 更轻,从零做长程 agent 用 Letta 更省事。两者都能自部署,数据都不出境。
Q:记忆存进去了,怎么知道检索准不准? A:用本站 RAG 评估 SOP 的思路,建一批"问题-期望记忆"测试集,跑命中率。mem0 官方也开源了 memory-benchmarks 评估框架,能复现它在 LongMemEval 上的分数。别靠主观感觉判断"好像记住了",上量化指标。
Q:用 OpenAI 之外的模型行不行? A:行。mem0 支持多种 LLM 和 embedder,配置见官方文档;Letta 完全 model-agnostic,Anthropic、OpenAI、zAI 都能接。换模型主要影响抽取质量和成本,记忆存取逻辑不变。生产环境建议先用便宜模型跑通,再按效果升级。
Q:记忆会被并发写坏吗? A:mem0 自部署版和云平台都有并发控制和 API 鉴权;纯 pip 库模式没有这层,高并发要自己加锁或上自部署版。Letta 的 agent runtime 单 agent 串行处理消息,并发问题相对小。多 agent 共享记忆库时,务必走带鉴权的服务端,别让多个进程直接写同一个本地存储。
Q:零基础第一次接,最短路径是什么?
A:pip install mem0ai,配好 OPENAI_API_KEY,抄上面那段 chat_with_memories 函数跑通一个能记能查的 demo。验证 memory.search() 真能召回上一轮存的记忆后,再考虑换模型、自部署、加抽取 prompt 优化。先跑通再加功能,别一上来就自部署全套服务。
参考来源
- mem0 仓库与文档:https://github.com/mem0ai/mem0
- mem0 官方文档:https://docs.mem0.ai
- mem0 论文(arXiv:2504.19413):https://mem0.ai/research
- Letta 仓库(前身 MemGPT):https://github.com/letta-ai/letta
- Letta 官方文档:https://docs.letta.com
- 本站相关:agent 记忆工具横评 | RAG 评估 SOP | Dify 知识库 RAG 搭建 SOP