如何管理 AI Agent 的记忆之三:让 mem0 给 AI Agent 装一层"通用记忆"
Posted on 六 08 8月 2026 in AI
| Abstract | 如何管理 AI Agent 的记忆之三:让 memo0 给 AI Agent 装一层"通用记忆" |
|---|---|
| Authors | Walter Fan |
| Category | learning note |
| Version | v1.0 |
| Updated | 2026-08-08 |
| License | CC-BY-NC-ND 4.0 |
写完前两篇——自己用 pgvector 手搓记忆系统、让三个编码工具共享记忆——有读者问我:这些活儿有没有现成的轮子?
有,而且很成熟:mem0(读作 "mem-zero")。GitHub 6 万多 star,Apache 2.0,自我定位是 AI Agent 的"通用记忆层"(universal memory layer)。我把前两篇里自己吭哧吭哧写的"重要性打分、事实抽取、去重、多信号检索"对着它的源码和文档过了一遍,感受是:该有的它基本都有,而且做得比我那一百行讲究得多。
更让我意外的是:它官方就带了 Claude Code、Codex、OpenCode 的集成——仓库里躺着 .claude-plugin、.codex-plugin,还有一行命令就能挂上的 MCP server。这正好接上前一篇"自己搭 MCP + Skill"的话题:原来这条路,人家已经铺好了。
这篇分三段:它到底是什么、架构怎么设计的、怎么用;然后重点讲怎么深度接进三个编码工具。 老规矩,代码都是照官方文档核对过的,不是我瞎编。
一、mem0 是什么:一个"记忆即服务"的中间层
先给个一句话定位:
mem0 坐在你的 Agent 和存储之间,帮你把"从对话里该记什么、怎么存、怎么找回来"这套脏活全包了。
你只管调两个动作——add(把这段对话喂给它)和 search(按当前问题捞回相关记忆)。中间那些"用 LLM 抽事实、算 embedding、去重、加权排序"的活儿,它在内部替你干了。对照前两篇你就懂了:我手写的 remember() / recall(),就是 mem0 的 add / search 的简化版。
它给自己划了三类典型用户:
- AI 助手/聊天机器人:跨会话记住用户偏好,越用越懂你。
- 客服/医疗等:调取历史工单、病人偏好,给个性化回应。
- 自主 Agent:从过去的运行里学经验,别每次从零开始。
一个最小的"带记忆的对话"长这样(OSS 版,官方 README 示例,我做了裁剪):
from openai import OpenAI
from mem0 import Memory
openai_client = OpenAI()
memory = Memory()
def chat_with_memories(message: str, user_id: str = "default_user") -> str:
# 1) 先按当前问题检索相关记忆
hits = memory.search(query=message, filters={"user_id": user_id}, top_k=3)
mem_str = "\n".join(f"- {e['memory']}" for e in hits["results"])
# 2) 把记忆拼进 system prompt,生成回答
messages = [
{"role": "system", "content": f"你是助手。参考已知记忆回答。\n{mem_str}"},
{"role": "user", "content": message},
]
reply = openai_client.chat.completions.create(
model="gpt-5-mini", messages=messages
).choices[0].message.content
# 3) 把这轮对话喂回 mem0,让它自己决定记什么
messages.append({"role": "assistant", "content": reply})
memory.add(messages, user_id=user_id)
return reply
注意第 3 步:你把整段对话丢给 add,记什么、怎么提炼、要不要记,是 mem0 内部用 LLM 决定的——你不用自己写打分逻辑。这就是它和"裸向量库"最大的区别:向量库只负责存和查,mem0 多了"理解和提炼"这一层。
二、架构拆解:它内部到底做了什么
mem0 的 add 不是简单 INSERT。官方把它描述成一条抽取 → 累加存储 → 检索的管线。我按它 2026 年 4 月那版新算法梳理一下(细节以官方研究页和文档为准):
flowchart TD
IN["add(messages)"] --> EX["信息抽取<br/>LLM 提炼出事实/决定/偏好"]
EX --> EL["实体链接<br/>抽实体、embedding、跨记忆关联"]
EL --> ST["累加存储 ADD-only<br/>只增不覆盖"]
ST --> V[("向量库<br/>Qdrant / pgvector")]
ST --> H[("历史库<br/>SQLite")]
Q["search(query)"] --> MS["多信号检索"]
MS -->|语义相似| V
MS -->|BM25 关键词| V
MS -->|实体匹配| V
MS --> TR["时间推理<br/>选对'当前/过去/将来'那条"]
TR --> OUT["排序融合后的 top-k"]
几个设计点,我觉得值得单独说说,因为它们正好回应了前两篇里的取舍:
- ADD-only,只增不改。新版算法一次 LLM 调用就抽完,不做 UPDATE/DELETE,记忆只累加。这和我前一篇里"命中就 UPDATE 去重"的思路不同——它靠检索端的排序和时间推理来处理"旧事实过时",而不是写入端覆盖。各有取舍:累加式实现简单、可追溯,代价是库会长得快,更依赖检索质量。
- 多信号检索。语义相似 + BM25 关键词 + 实体匹配,三路并行打分再融合。这正是前一篇我强调的"别只看向量相似度",它做成了默认能力。
- 时间推理。同一个事实的不同时间版本,它能按"你问的是现状、往事、还是计划"选对那一条。这解决了"用户上周改了架构、别翻两个月前老配置"那个痛点。
- 作用域三件套:
user_id、agent_id、run_id。分别对应"哪个用户、哪个 Agent、哪一次运行"——天然就是前一篇强调的"用户/项目/会话隔离",不用你自己拼命名空间。
三种形态:库 / 自建 server / 云平台
这点对落地很关键,别选错:
| 形态 | 怎么起 | 存储默认 | 适合 |
|---|---|---|---|
| 库(OSS) | pip install mem0ai → Memory() |
本地 Qdrant + SQLite 历史库 | 试水、原型、自己玩 |
| 自建 server | cd server && make bootstrap |
Postgres + pgvector | 团队、要 dashboard 和 API key |
| 云平台 | 注册 app.mem0.ai 拿 key | 托管 | 不想运维、直接上生产 |
API 上的区别就一行:
# OSS:本地跑,自带向量库
from mem0 import Memory
m = Memory()
m.add("我用 Go,不要给我推 Java 方案", user_id="walter")
print(m.search("推荐个后端技术栈", filters={"user_id": "walter"}))
# 云平台:连托管服务,换个 client
from mem0 import MemoryClient
client = MemoryClient(api_key="m0-xxx")
client.add("我用 Go,不要给我推 Java 方案", user_id="walter")
print(client.search("推荐个后端技术栈", filters={"user_id": "walter"}))
一句话选型:自己玩用库,团队用自建 server,怕运维上云平台。 你会发现自建 server 的默认存储就是 Postgres + pgvector——和我前一篇手搓的那套底子一模一样,只是人家在上面盖了完整的房子。
三、深度集成:一行命令接进三个编码工具
这是重头戏,也是 mem0 让我眼前一亮的地方。它对编码 Agent 的集成不是"你自己看 SDK 文档去接",而是官方做好了 skill 和 MCP,一行命令挂上。而且明确支持 Claude Code、Codex、Cursor、Windsurf、OpenCode 等一票工具。
集成分两个层次,正好对应前一篇讲的"手(Tools/MCP)+ 规矩(Skill)":
层次一:装 Skill,让工具"会写 mem0 代码 / 会用 mem0"
mem0 提供两类 skill,都走 npx skills add 这个标准命令:
参考型 skill(常驻,教工具正确使用 mem0 的 SDK):
# 教它 mem0 的 Python/TS SDK 用法,写集成代码不再瞎猜
npx skills add https://github.com/mem0ai/mem0 --skill mem0
# 教它 mem0 CLI 的终端用法
npx skills add https://github.com/mem0ai/mem0 --skill mem0-cli
流水线型 skill(按需触发,跑一整套工作流,用斜杠命令调用):
npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate
npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration
/mem0-integrate:在你现有仓库里,测试先行地把 mem0 接进去——它会自动探测技术栈、问你用云还是自建、先写失败测试、再让集成保持"可开关的增量"。/mem0-test-integration:验证上一步接得对不对,跑你仓库原生测试 + 真实端到端冒烟,最后出一张打分卡。
这套设计挺有意思:它把"如何正确集成一个库"本身,也做成了 Agent 能执行的 skill。 你在 Claude Code 里敲一句 /mem0-integrate,它就照着这套流程帮你把 mem0 焊进项目,还带测试兜底。
层次二:挂 MCP,让工具"能直接存取记忆"
Skill 是"知识和流程",MCP 才是"真正的手"。挂上 mem0 的 MCP server 之后,三个工具就能在对话里直接读写你的记忆库。官方给了一条命令搞定多个客户端:
# 先去 app.mem0.ai 拿 API key,然后一条命令挂到多个工具
npx mcp-add \
--name mem0-mcp \
--type http \
--url "https://mcp.mem0.ai/mcp" \
--clients "claude,claude code,cursor,windsurf,vscode,opencode"
跑完之后的效果,和我前一篇自己搭 MCP 想达到的一模一样,但零代码:
- 你在 Claude Code 里说"记住:这个项目 CI 用 GitLab,不是 GitHub",它通过 mem0 MCP 把这条写进你的记忆库。
- 第二天切到 OpenCode 干活,它通过同一个 mem0 MCP 检索,"想起"了这条——尽管这条不是它写的。
一张图收口整个集成:
flowchart TD
subgraph Tools["三个编码 Agent"]
CC[Claude Code]
CX[Codex]
OC[OpenCode]
end
SK["mem0 Skills<br/>教它怎么用 / 何时用"]
MCP["mem0 MCP<br/>mcp.mem0.ai/mcp"]
ENG["mem0 记忆引擎<br/>抽取 · 累加 · 多信号检索"]
DB[("同一份记忆后端")]
CC --> SK
CX --> SK
OC --> SK
CC --> MCP
CX --> MCP
OC --> MCP
SK -.指导.-> MCP
MCP --> ENG --> DB
对比一下前一篇我自己搭的方案:我是"手写 MCP server + 手写 Skill + 自己维护 pgvector",mem0 是"官方 skill + 官方 MCP + 托管或自建引擎"。如果你只是想快速让三个工具共享记忆,mem0 这条路省事得多;如果你想完全掌控数据和逻辑、或有特殊的记忆策略,前一篇那套自建方案给你的自由度更大。 两条路不冲突——你甚至可以用 mem0 的自建 server(底层也是 pgvector),既省了造轮子,又把数据留在自己机器上。
什么时候用 mem0,什么时候别用
工具再好也有边界,说几句实在的:
适合用 mem0 的场景:
- 你想快速给 Agent 加长期记忆,不想自己写抽取/去重/检索。
- 你同时用多个编码工具,想让它们共享一份记忆——官方集成现成。
- 你要跨会话的用户级个性化(助手、客服、教育类产品)。
可能不适合、或要谨慎的场景:
- 数据敏感、合规要求高:云平台要把对话送到它那边抽取,涉密项目慎用;这种情况优先自建 server 或纯 OSS 库。
- 每次 add 都要过 LLM:抽取是有成本和延迟的(虽然新算法已优化到单次调用)。高频、低价值的写入,得掂量 Token 账。
- 你需要非常定制的记忆策略:比如特殊的重要性评分、领域专用的图结构——这时候前两篇那种自建方案反而更顺手。
- 强一致/事务性记忆:mem0 是 ADD-only 累加式,"实时精确覆盖旧值"不是它的强项,得靠检索端时间推理绕。
一句话:
mem0 帮你把"记忆的通用脏活"外包掉;但"记什么、值不值得记、数据放哪"这些决策,仍然是你的责任。
收个尾:三篇串起来的记忆地图
这三篇其实是一条线:
- 第一篇:记忆为什么要分层(工作/情景/语义/程序),生命周期怎么管,自己用 pgvector 手搓一套——懂原理。
- 第二篇:怎么让 Claude Code、Codex、OpenCode 共享同一份记忆(单一事实源 + MCP)——懂协作。
- 本篇:直接用成熟的 mem0,架构、用法、官方集成一条龙——懂选型。
给你一张落地 checklist:
- [ ] 先想清楚:你要的是"快速可用"还是"完全掌控"?前者选 mem0,后者可自建。
- [ ] 试水用
pip install mem0ai+Memory(),几行代码跑通 add/search。 - [ ] 团队/生产:自建 server(
make bootstrap,底层 pgvector)或上云平台。 - [ ] 给编码工具装 skill:
npx skills add ... --skill mem0(+mem0-integrate按需)。 - [ ] 挂 MCP 让三个工具共享记忆:
npx mcp-add --url https://mcp.mem0.ai/mcp --clients "..."。 - [ ] 上线前想清楚数据合规:敏感项目别用云平台的抽取,走自建。
如果要比较 mem0 和自建 pgvector,建议使用同一批脱敏样本、同一个模型和同一组问题,分别记录:安装与升级成本、写入时延、检索时延、返回候选数量、事实更新后的处理方式、删除是否彻底,以及模型调用次数。没有实测数字时,就明确写“待验证”,不要用项目 star 数或宣传语替代质量评估。
还应单独写清数据边界:云端方案会把哪些内容送出本地,自建方案由谁维护模型和数据库,用户如何查看、导出和删除记忆。通用记忆层最容易被忽略的不是 API,而是数据隔离、租户边界和“忘记我”能否真的生效。
最后一句
我自己是"先手搓、再用轮子"这个顺序过来的,反而觉得值——先手搓一遍,你才知道 mem0 每个设计点在解决什么问题;直接用轮子,容易把它当黑盒,出了问题一脸懵。
所以我的建议是:前两篇的原理别跳过,但真要上项目、尤其想让三个编码工具共享记忆时,不必重复造轮子——pip install mem0ai 加两行 npx,你前一篇想要的效果,基本就有了。
工具会迭代,mem0 的 API 和集成命令也可能变(落地前记得看它最新文档);但"给 Agent 一层会提炼、会遗忘、能共享的记忆"这个方向,是确定的。
全文思维导图
@startmindmap
<style>
mindmapDiagram {
node {
BackgroundColor #F8F9FA
RoundCorner 10
Padding 10
FontSize 13
}
:depth(0) {
BackgroundColor #1E3A5F
FontColor white
FontSize 18
FontStyle bold
}
:depth(1) {
FontSize 15
FontStyle bold
}
:depth(2) {
FontSize 13
}
}
</style>
* Mem0 通用记忆层
** 是什么
*** Agent 和存储之间的中间层
*** add / search 两个动作
*** 内部包办抽取/去重/检索
*** 我手搓的 remember/recall 的加强版
** 架构
*** add: 抽取→实体链接→累加存储
*** ADD-only 只增不覆盖
*** search: 语义+BM25+实体 多信号
*** 时间推理选对版本
*** 作用域 user/agent/run
** 三种形态
*** 库 OSS: Memory() 本地 Qdrant
*** 自建 server: pgvector + 面板
*** 云平台: MemoryClient + key
** 深度集成
*** 装 Skill: npx skills add
*** mem0-integrate 测试先行
*** 挂 MCP: npx mcp-add
*** 三个工具共享同一记忆
** 边界
*** 敏感数据慎用云
*** 每次 add 过 LLM 有成本
*** 定制策略不如自建
*** 累加式非强一致
** 系列串联
*** 一懂原理(手搓)
*** 二懂协作(共享)
*** 三懂选型(mem0)
@endmindmap

本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。 欢迎在我的个人网站 https://www.fanyamin.com 访问原文并评论。