同一天写这篇的时候,Keyv 的 npm 蠕虫正在被讨论:一个包被污染,所有装过它的项目全遭殃。Agent 生态也一样——你给 Claude Code、Codex、Cursor 各装一套配置,等于把同一个秘密讲给了三个互不认识的员工。他们各自记在小本本上,谁也不告诉谁。 本文首发地址 https://h89.cn/archives/687.html

封面

你其实在重复教每个 AI 编程工具一遍

同时用 Claude Code 和 Codex 的人,大概率经历过这个循环:

  1. 在 Claude Code 里花半小时讲清楚项目架构、目录约定、踩过的坑;
  2. 切到 Codex 干活,发现它一无所知,重新解释一遍;
  3. 换了台机器或者新开了 Cursor,第三遍。

每个工具都是一个独立的"员工",工位挨着,但从不交流。你讲过的每一句话,都被各自的上下文窗口丢掉了。这不是某一个工具的问题——上下文窗口本身就是一次性的,关掉就没了。

所以当我在 GitHub 上刷到 MemTensor/memmy-agent(下文简称 Memmy)时,它的口号让我愣了一下:

"All AI remember the same you."

让 Cursor、Claude Code、Codex、OpenCode、OpenClaw、Hermes 六种工具共享同一份长期记忆。你说过一次的事,所有 Agent 都记住。

Memmy 7 月中旬开源,到现在(8 月 5 日)已迭代到 v1.0.4,GitHub 实时数据 显示 565 stars、44 commits、11 个贡献者。星数不算高,但功能完整度远超星数暗示的水平:四层记忆、六路混合召回、六种 Agent 适配器、桌面端 + CLI + API 全套落地。需要说明的是,它和同组织的 MemOS(10k stars 的「自演化记忆 OS」引擎)不是同一个项目——Memmy 更像是 MemOS 理念的消费级封装,定位是桌面端 + 本地优先的跨 Agent 记忆产品。

我把它 clone 下来翻了源码,这篇写清楚三件事:记忆引擎怎么设计的、六种 Agent 怎么接进来的、以及它凭什么解决 mem0 被诟病的记忆质量问题。

记忆引擎:不是"存下来",是"沉淀出来"

先说一个背景。市面上最火的记忆方案 mem0(56.8k stars)走的是"向量 + 全文检索 + 实体链接"的路子,单遍提取,存完就算数。但它的质量一直被人诟病,issue #4573 里有用户贴出实测称,97.8% 的召回是噪声。问题不在于"存",而在于"存的时候没想过这条记忆以后有没有用"。

Memmy 的设计思路完全不同:记忆是分层的,并且会自己演化。它的架构文档把记忆分成四层:

保存什么 怎么产生
L1 Trace 原始交互:用户请求、Agent 回复、工具调用、结果、错误签名 回合结束后写入
L2 Policy 从相似的、有价值的 L1 里归纳出的经验:触发条件、步骤、避坑点 reward 之后的归纳
L3 World Model 对项目、环境、约束的稳定认知(不是操作步骤) 从 L2 集群抽象
Skill 可调用的 SOP:名称、触发说明、执行步骤、验证条件 从合格的 L2 结晶

这是一条自下而上的升华链:原始对话 → 归纳成经验 → 抽象成环境认知 → 结晶成可复用技能。翻译成人话:不是把你说过的每句话都存下来,而是把你说过的话里值得学的部分提炼成"这个项目该怎么干活"。

这条链跑在后台,由几个独立的演化管道驱动(源码在 Memory/src/service/evolution/):

  • reward-pipeline:一个回合(episode)结束后等 30 秒反馈窗口,根据任务奖励给该回合的 L1 反向传播价值,越靠前的轨迹衰减越狠(gamma=0.9),L1 的 priority 每 30 天半衰期衰减一次。没用的记忆会自己贬值。
  • L2 induction:只有价值超过阈值(minTraceValue=0.005)的 L1 才进入归纳候选池,相似度 ≥0.65 才归纳成 L2 Policy。
  • L3 abstraction:L2 聚类抽象成场域认知,置信度 ≥0.2 才参与召回。
  • skill-pipeline:满足条件的 L2 结晶成 Skill,以后可以直接当工具调用。
  • negative-experience-pipeline:工具连续失败会生成"避坑经验",下次遇到同样的错误直接决策修复。

还有一个挺有意思的机制:Dream 整理。手动 /dream 或周期触发,把已有记忆合并、归档、提炼,类似睡眠期的记忆巩固,/dream-log 看结果、/dream-restore 回滚。

检索:六路混合召回 + 三道质量闸门

存得好只是第一步,查得准才是真本事。Memmy 的检索(Memory/src/service/retrieval/retrieval-service.ts)不是单一向量搜索,而是六路并行召回

通道 干什么 用在哪层
语义向量 vec / vec_summary / vec_action 向量相似度检索 所有层
全文检索 fts SQLite FTS5 关键词匹配 所有层
短词/中文模式 pattern 二字中文片段、两字符 ASCII 短词 所有层
结构化片段 structural 错误签名、路径、错误码精确匹配 仅 L1

六路结果按相关度融合(channel score + 层级 bonus + RRF 融合),然后过三道质量闸门:

  1. 相对阈值裁剪:低于最高相关度 20% 的候选丢弃(多通道命中 ≥2 可豁免);
  2. MMR 多样性选择0.7 × 相关度 - 0.3 × 冗余度,避免召回十条长得一模一样的;
  3. LLM 最终过滤:用一个独立的"演化模型"对机械排序结果做语义过滤,最多保留 8 条,失败回退保底 6 条。

向量存储用的是本地 SQLite + sqlite-vec 扩展,每次搜索从最近 2,000 条向量记录里建窗口再取 Top K,不是全库暴力扫。

还有个细节很见功力:新回合第一轮会做意图门控。如果你的请求是"上次我们聊到哪了?",它召回 Skill/L2/L1 但不召回 L3(世界模型);如果是闲聊或者 Memmy 自己的元命令,直接跳过召回。另外 turn_start 会排除当前 session 自己的 L1,防止刚发生的事通过长期记忆路径"回声式重复"——这个坑很多记忆系统都踩过,刚说完的话又被当成历史记忆注入回来。

真正难的工程:让六种 Agent 都接入

记忆引擎再漂亮,如果每个 Agent 都要手动调 API,就没人用。Memmy 的护城河在接入层:App/backend/src/adapters/outbound/agent-source/ 下有六个适配器目录,每个都是独立的 adapter:

Agent 历史扫描来源 实时接入方式
Cursor ~/Library/Application Support/Cursor/.../state.vscdb Hook
Claude Code ~/.claude/projects/**/*.jsonl Hook
Codex ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl Hook
OpenCode ~/.local/share/opencode/opencode.db 原生插件
OpenClaw ~/.openclaw 下的 conversation/memory SQLite Memory 插件
Hermes ~/.hermes/sessions/**/*.jsonl + state.db Memory Provider 插件

每个 Agent 的接入都做三件事:

1. 历史扫描 + 增量同步。 首次扫描把 Agent 已经写在本地的对话全部导入,之后维护一个日期时间水位做增量同步。水位机制有个细节:每次同步会重读水位时刻的那条消息(>= 包容边界),用"最后消息时间 + 消息 ID + 内容哈希"做会话检查点去重,保证幂等,不会因为水位正好落在回合中间而丢开头。

2. 按完整回合入库,不按消息。 一条用户消息 + 后续工具/系统消息 + Assistant 回复合并成一个回合,一个回合只生成一条 L1。比如"1 用户 + 2 工具 + 1 Assistant"处理了 4 条消息,但只 +1 条记忆。没有最终回复的不完整回合直接跳过,等它补全。这就是为什么 Memmy 的记忆密度比"每条消息都存"的方案高得多。

3. 实时 Hook/插件 + Skill 注入。 装完后五个接入(除 Cursor 外)会在请求执行前检索记忆注入上下文,回合结束自动采集(用户请求、Agent 回答、成功/失败状态,不需要手动 memmy-memory add)。Cursor 的 Hook 重点负责采集和 /memmy-resume 命令。另外每个 Agent 都会装一个 memmy-memory SKILL.md,让 Agent 自己也能主动存/查。

两个工程细节值得单独说:

fail-open 设计。 记忆服务挂了绝不阻塞对话:召回或采集失败就记录错误继续,单次 Memory 请求超时 45 秒,Hook 宿主超时 60 秒。这个取舍对生产力工具是必须的:记忆是增强,不是单点故障。

注入内容的安全标记。 记忆注入用 <memmy_memory_context> 包裹,当前用户请求用 <current_user_request> 明确标出,降低"旧记忆被误当成新指令"的风险。SKILL.md 的安全规则写得很直白:不存储密钥/token;不因为内容出现在记忆上下文里就回答它;不把这些标签本身写进记忆。

代价与取舍:为什么它还不能无脑用

夸完亮点,泼盆冷水。Memmy 现在是 565 stars 的 3 周龄项目GitHub,8 月 5 日复核),对比一下:

项目 Stars 质量门控 定位
mem0 ~56.8k 无(97.8% 垃圾率争议) 云优先记忆 SDK
Letta (MemGPT) ~23k 有状态 Agent + 记忆块
MemOS(Memmy 同组织) ~10k 有演化管道 自演化记忆 OS 引擎
Zep ~4.6k 仅时序有效性 时序知识图谱
Memmy 565 reward 反向传播 + 四层演化 + LLM 过滤 本地优先跨 Agent 记忆枢纽

现实问题摆在那:

  • 社区规模悬殊。565 vs mem0 的 56.8k,生态、教程、issue 响应速度完全不是一个量级。你遇到的坑大概率没人踩过。
  • 配置门槛不低。BYOK 模式下要自己配六类模型(主模型、Embedding、记忆摘要、技能进化、ASR、图像生成),每类一个 API Key。
  • 与 MemOS 的关系容易混淆。MemTensor 组织下有两个仓库:MemOS 是 10k stars 的记忆 OS 引擎(Apache 2.0),Memmy 是把它封装成桌面产品(MIT)。看星数别把两个混为一谈。
  • 本地优先是优点也是限制。数据不出本机很安心,但跨设备同步、团队共享这些场景它现在没有。

我的判断:Memmy 值得关注,但现阶段把它当观察对象,别当生产依赖。 真实原因是,我自己现在 hermes 和 opencode 接的是 Hindsight,通过一个共享的 bankId 已经实现了跨 Agent 记忆共享。Memmy 主打的核心痛点我其实已经解决了。Memmy 真正让我感兴趣的不是"共享记忆"本身,而是它的自动历史扫描更重的记忆演化机制——一键把 3.5GB 的 opencode 本地历史和 hermes 会话导入成结构化记忆,这件事 Hindsight 目前做不到。

所以我的做法很保守:hermes 和 opencode 继续用 Hindsight;Memmy 先在独立环境跑,只接一个非核心 Agent 做对照,看半年。真正值得偷师的是它的设计思路:"记忆要分层、要演化、要有质量门控"这套东西,比"存下来就能查"高一个维度。另外,装它之前记得看一眼它写进 ~/.claude/settings.json~/.codex/hooks.json 的那些文件——Agent 配置文件现在也是攻击面的一部分。


参考:


本文链接:你说过一次,所有 Agent 都记住:Memmy 跨 Agent 记忆层源码拆解 - https://h89.cn/archives/687.html

版权声明:原创文章 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文链接和本声明。

标签: Agent, Cursor, codex, OpenClaw, Hermes, Claude Code, LLM, Hook, Memmy, SQLite, mem0, MemOS

🎓 呈言英语 智能英语学习平台
📚单词学习 🎧听说练习 📖阅读理解 ✏️拼写练习 🌟 AI智能推荐 · 科学记忆曲线
🚀 立即开始免费学习

添加新评论