这是房间里"memory"这个词最容易误导人的对比页。
Mem0 / Letta 说"memory"的时候,意思是:这个循环里的 LLM 应该记住之前发生的事。用户三轮前告诉 Agent 自己吃素 —— 下一轮不应该推荐牛排。跨对话,Agent 应该记住"这个用户喜欢简洁回答"。这真的有用,是难题,Mem0 和 Letta 做得好。
puppyone 说"context"的时候,意思是:Agent(任何 Agent,不只是这一个)应该有一个持久、有 scope、版本化的工作空间。不是"你三轮前说了什么",而是"规格写了什么、昨天那个研究 Agent 写了什么、客户 onboarding 文档当前 canonical 版本是什么、Cursor 在 14:32 commit 了什么"。这是不同层的不同问题。
可以只用 Mem0 不用 puppyone。可以只用 puppyone 不用 Mem0。生产里大部分两个都用,因为它们解决不同的失败。
| 维度 | Mem0 / Letta | puppyone |
|---|---|---|
| "memory" 指什么 | 循环内 / 跨对话 LLM 该回想的内容 | Agent 和人共同操作的整个共享工作空间 |
| 生命周期 | 短到中(轮、session、有时几周) | 长(月、年;除非回滚否则永久) |
| 基本单位 | 记忆条目 / 事实 / 摘要 / embedding | 文件,带完整内容和历史 |
| 主要用户 | 一个应用聊天循环里的一个 Agent | 跨产品跨时间的多个 Agent + 人 |
| 存储形状 | 向量库 + 结构化记忆 schema | 文件系统(markdown / JSON / CSV / 任何东西) |
| 原生接口 | SDK 调用(memory.add、memory.search、memory.update) | Bash、MCP、REST、sandbox 挂载 |
| 多 Agent 协作 | per-agent 记忆;要共享需要显式设计 | 原生 —— 同一个工作空间,per-agent 路径 scope |
| 审计 / 版本控制 | 限于记忆 CRUD 日志 | 按 Agent 身份的 Git 风格 commit、完整 diff、回滚 |
| SaaS 接入 | 不是它的活 —— 你喂它对话轮 | 内置:Notion、Slack、Gmail、Postgres 等连接器 |
| 范围 | 在聊天循环之内 | 整个 Agent 栈之上 |
| 真正擅长 | "别忘了用户告诉过你什么" | "成为每个 Agent 都从中读、向里写的持久底座" |
要解决的问题是 Agent 内的对话连续性的时候,用 Mem0 或 Letta:
这是真实的难题。puppyone 不为这个建。我们没有 LLM-aware 的抽取流水线,不会自动总结对话轮,也不会按终端用户做记忆 scope。Mem0 和 Letta 这块做得好,去用。
要解决的问题是多 Agent 多人共享、持久、文件形态的上下文的时候,用 puppyone:
如果你一直在把每个项目产物塞进一个向量化的记忆库、看着它膨胀成搜不动的摘要堆 —— 你在用记忆层干上下文的活。形状不对。
真正的生产 Agent 栈里:
干净的分工:Mem0/Letta = "循环内 LLM 该记住的事";puppyone = "循环外世界长什么样"。
不太一样,差异重要:
core_memory 概念和可编辑的 scratchpad —— 那是一个 Agent 进程内的工作记忆原语,不是跨多个 Agent 多个工具(Cursor、n8n、你的自建代码)跨时间共享的工作空间。memory.search 返回相关条目建,不是围绕 cat /specs/architecture.md 返回一份规格的 canonical 内容建。你完全可以让 Letta 或 Mem0 作为 写入 puppyone 的一方 —— Agent 用 Letta 管自己的工作记忆,再把重要产物(最终报告、转换数据集、决策)以文件形式 commit 到 puppyone,给栈里其他人。
向量库(Pinecone / Zilliz / FAISS / pgvector)是检索原语。Mem0/Letta 在它们之上建记忆抽象。puppyone 在另一层:文件的 canonical 存储,embedding 是派生索引,想放哪里都行。
我们另外有一篇 puppyone vs 向量数据库 详聊这个。短版:向量找文档;puppyone 存文档。
不存在迁移。Mem0 / Letta 留在你 Agent 代码里。
/research,planner 写 /plans,executor 写 /output。Mem0/Letta 仍然管各自 Agent 的工作记忆。一个月后边界会很清楚:易逝的对话状态在 Mem0/Letta;持久、共享、版本化的文件在 puppyone。
puppyone 替代 Mem0 或 Letta 吗? 不。我们不做对话事实抽取或循环内的记忆管理。Mem0 和 Letta 做这个做得好。我们坐在底下,撑着长程共享上下文。
puppyone 能作为 Letta 或 Mem0 的存储后端吗? 可以把记忆快照持久化到 puppyone 做审计和版本历史,可以。我们不是它们内部存储的 drop-in 替代。
puppyone 为什么不做自动记忆抽取? 因为那是 per-agent / per-application 的事,最好在 Agent 循环里做。我们想做底座,不想做大脑。加抽取要么会偏向我们抽什么(迎合一个 Agent 的需求),要么让我们作为通用底座变差。
我 Agent 已经有 Mem0 了,为什么还要 puppyone? 因为 Mem0 装的是 LLM 该记住的内容。它不装 Agent 该跟着走的规格、Agent 该读的代码库、Agent 昨天写完今天同事要看的报告、应该变成文件的 Slack 线程。这些是 puppyone 的活。
puppyone 有语义搜索吗? puppyone 是文件底座;embedding + 语义搜索是上面一层,我们把"在 puppyone 内容上接一个向量库(或 pgvector)"做得很简单。我们不内置向量库,因为大多数团队要么已经有一个,要么想自己选。
Mem0 / Letta = Agent 循环里的记忆。puppyone = Agent 操作的世界。别把一个塞到另一个该在的位置。生产里大多数两者都跑,"我们刚说了什么"和"什么是真的"之间留一道清楚的线。
给你的 Agent 两边都给:循环里的工作记忆 + 循环外的持久工作空间。Get started