一个命令,让 Claude Code 拥有永久记忆

一个命令,让 Claude Code 拥有永久记忆

一个命令,让 Claude Code 拥有永久记忆 一个命令,让 Claude Code 拥有永久记忆 Modified June 11 Code block Python Copy sidecar = self. get sidecar() if sidecar is None: self. turn observations = [] return try: for obs in self. turn observations: 三层过滤 if len(obs["text"]) < 30: continue low value signals = ("exit code", "exit: 0", "[SILENT]", "usage:", "entry count:", "hits:") if any(sig in obs["text"] for sig in low value signals): continue sidecar.add event( session id=self. session id or "hermes unknown", agent="hermes", event type="observation", project path="/Users/dx/Hermes agent", tool name=obs["tool"], content summary=obs["text"][:500], content json=obs, sensitivity="normal", ) except Exception as e: logger.debug(" flush observations to sidecar failed: %s", e) finally: self. turn observations = [] get sidecar 做延迟初始化——只在第一次需要时才加载 sidecar DB 连接,不影响 Hermes 启动速度: Code block Python Copy def get sidecar(self) "AgentMemoryDB": """延迟初始化 sidecar DB。""" if self. sidecar db is None: try: sidecar core = str(Path(os.path.expanduser( " /Hermes agent")).joinpath( "20 Github 自管", "agent memory core")) sys.path.insert(0, sidecar core) from agent memory core.db import AgentMemoryDB self. sidecar db = AgentMemoryDB() self. sidecar db.init schema() except ImportError: logger.debug("agent memory core not available, sidecar disabled") return None return self. sidecar db 这三段代码加起来不到 100 行,但让 Hermes 成了三端记忆共享的桥梁。 Claude Code 和 Codex 通过外部 hook 写入 sidecar,Hermes 通过 Provider 内部 hook 写入 sidecar。 三个工具的事件汇入同一个地方。 你用 Claude Code 修了一个 bug,Hermes 马上就能在 sidecar 里找到这条记录。 和 claude mem 原版对比 claude mem 的优势是开箱即用,一个命令搞定。 我的方案优势是三端知识互通,且长期记忆有 Obsidian 做事实源,不怕丢。 两者不矛盾——我是站在 claude mem 的肩膀上做的改造。 Code block Markdown Copy 实施顺序 P0:整合设计落盘 将文档作为三端构建基准。 将旧 codex memory plugin plan 降级为 Codex adapter 参考, 不再作为独立系统方案。 在 持久化层/记忆系统.md 插件系统/记忆 Provider 插件.md 补入口链接。 P1:shared core 骨架 创建 agent memory core 仓库骨架。 实现 SQLite schema、脱敏、写入、搜索、status。 不启用任何 hook,只跑 CLI 单元测试。 P2:Claude Code adapter 先接入 先用 Claude Code hook 验证事件输入,因为 Claude Code hook 形态更明确。 只采集 SessionStart、UserPromptSubmit、PostToolUse、Stop。 验证 hook 失败不阻塞 Claude。 P3:Codex adapter 接入 复用同一 hook 脚本。 做 .codex plugin/plugin.json、hooks、MCP、Skill 映射。 验证 Codex 新会话能看到轻量历史索引。 P4:Hermes 晋升桥 从 sidecar DB 生成 L1 候选。 人工审核后再批量晋升 L2/L3。 Obsidian 同步仍走 Hermes 现有三级记忆管线。 P5:自动化和健康检查 Cron 检查 DB 大小、hook 错误率、未处理队列。 每日蒸馏候选写到 Obsidian,默认不自动晋升高层记忆。 实际效果 说说改造完之后实际跑起来的效果。 Hermes 的 observation 捕获 现在 Hermes 每轮工具调用结束后,sync turn 都会自动执行。 它会扫描 assistant 的 tool calls,提取参数摘要和结果摘要,写入 sidecar DB。 举个例子:我用 Hermes 让它读一个 Python 文件,它会生成这样的 observation: Code block Plain Text Copy [read] /Users/dx/Hermes agent/20 Github 自管/agent memory core/agent memory core/db.py 如果让它执行一条命令,生成的是: Code block Plain Text Copy [terminal] python3 m unittest discover s tests v 这些 observation 先进缓冲区,积累到 5 条或 2000 字符时批量写入 sidecar DB。 这个缓冲机制很重要——如果每个工具调用都单独写一次数据库,I/O 开销会很大。 三层过滤 不是所有 observation 都值得保留。 ❌ 不是所有 observation 都值得保留。 我在 flush observations 里加了三层过滤,大部分低价值记录在写入前就被拦住了。 1. 太短的跳过:observation 文本少于 30 字符的,直接丢掉。一条 ls 命令的输出没有记忆价值。 2. 低价值信号跳过:如果文本里包含 exit code、exit: 0、[SILENT]、usage:、entry count:、hits: 这些信号,说明是一次无意义操作,跳过。 3. 重叠去重:这一层在 on memory write 里已经实现了——检查已有记录的内容重叠度,超过 60% 就跳过。observation 端的完整去重还在路上。 三层过滤下来,真正进入 sidecar 的大概是原始 observation 的三分之一。噪声少了很多。 FTS5 搜索能力 sidecar DB 上的 FTS5 虚拟表支持全文搜索。 我在 AgentMemoryDB.search 方法里实现了这个能力。 搜索时先把用户的自然语言查询转成 FTS5 语法: 把查询词用 OR 连接,每个词加双引号,最多取前 12 个 token。 如果 FTS5 查询失败(比如包含特殊字符),会自动降级为 LIKE 模糊搜索。 这意味着你可以用 agent memory search "API bug 修复" 来搜索,不需要精确匹配。 它还支持按 agent 过滤——只看 Claude Code 的记录,或者只看 Hermes 的。 改造前 vs 改造后 维度 改造前 改造后 记忆覆盖范围 Claude Code 单端 Claude Code + Hermes + Codex 三端 搜索能力 各 Agent 独立搜索 统一 sidecar DB 全文搜索 跨 Agent 知识共享 不支持 sidecar DB 统一存储,支持 长期记忆 claude mem 自建 复用 Hermes 三级记忆 + Obsidian 噪声控制 LLM 自动压缩 三层过滤 + 晋升审核 事实源 无统一事实源 Obsidian 唯一事实源 坦白说当前进度:sidecar DB + Hermes Provider 已经跑通了,Codex 的 hooks.json 也已经配置好就位。 Claude Code 的 adapter 目录 adapters/claude code/ 还没创建,这是下一步要做的。 但核心架构和代码已经落地,数据流通路已经打通。 还有点话 折腾了一圈,最大的收获不是代码,是一个认知。 AI 工具的记忆,不是"记得你说过什么"。 你说过什么,对话历史里本来就有。 AI 工具的记忆,是在正确的时候把正确的上下文喂给 AI。 claude mem 在 Claude Code 开会话时,从历史记忆里捞相关片段塞进 system prompt。 Claude 一上来就知道你之前做过什么、踩过什么坑。 这比你自己手动把背景信息复制粘贴进新对话,效率高太多了。 但我更想说的是后面那一步——三端共享。 工具是工具,记忆是记忆。 Claude Code 是个好工具,Hermes 是个好工具,Codex 也是。 但它们的记忆不应该被绑定在各自工具里。 分开管,比绑在一起强。 把事件采集和长期记忆拆开,所有 Agent 的事件汇入公共池,再由统一的系统筛选和沉淀。 这个思路不仅适用于 AI 工具,也适用于任何需要跨系统知识共享的场景。 说到底,一个人同时用好几个 AI 工具的时候,最需要的不是每个工具都变得更强,而是让它们之间能说上话。 记忆不绑定工具,工具才能为你所用。 既然看到这里了,如果觉得不错,随手点个赞、在看、转发三连吧,如果可以给我个星标⭐,将不胜感激~谢谢你看我的文章,我们,下次再见。 AI编程 ClaudeCode Hermes Codex 永久记忆 AI工具 作者:大象 推动 AI 共学,让普通人轻松上手AI 相关链接 1. claude mem GitHub:https://github.com/thedotmack/claude mem 2. Claude Code 官方文档:https://docs.anthropic.com/en/docs/claude code 3. Hermes Agent 文档:https://hermes agent.nousresearch.com/docs 公众号:大象 AI 共学 个人号:Yishouhundanqu(注明来意) get sidecar 做延迟初始化——只在第一次需要时才加载 sidecar DB 连接,不影响 Hermes 启动速度: 这三段代码加起来不到 100 行,但让 Hermes 成了三端记忆共享的桥梁。 Claude Code 和 Codex 通过外部 hook 写入 sidecar,Hermes 通过 Provider 内部 hook 写入 sidecar。 三个工具的事件汇入同一个地方。 你用 Claude Code 修了一个 bug,Hermes 马上就能在 sidecar 里找到这条记录。 这三段代码加起来不到 100 行,但让 Hermes 成了三端记忆共享的桥梁。 Claude Code 和 Codex 通过外部 hook 写入 sidecar,Hermes 通过 Provider 内部 hook 写入 sidecar。 三个工具的事件汇入同一个地方。 你用 Claude Code 修了一个 bug,Hermes 马上就能在 sidecar 里找到这条记录。 和 claude mem 原版对比 claude mem 的优势是开箱即用,一个命令搞定。 我的方案优势是三端知识互通,且长期记忆有 Obsidian 做事实源,不怕丢。 两者不矛盾——我是站在 claude mem 的肩膀上做的改造。 实际效果 说说改造完之后实际跑起来的效果。 Hermes 的 observation 捕获 现在 Hermes 每轮工具调用结束后,sync turn 都会自动执行。 它会扫描 assistant 的 tool calls,提取参数摘要和结果摘要,写入 sidecar DB。 举个例子:我用 Hermes 让它读一个 Python 文件,它会生成这样的 observation: 如果让它执行一条命令,生成的是: 这些 observation 先进缓冲区,积累到 5 条或 2000 字符时批量写入 sidecar DB。 这个缓冲机制很重要——如果每个工具调用都单独写一次数据库,I/O 开销会很大。 三层过滤 不是所有 observation 都值得保留。 ❌ 不是所有 observation 都值得保留。 我在 flush observations 里加了三层过滤,大部分低价值记录在写入前就被拦住了。 ❌ 不是所有 observation 都值得保留。 我在 flush observations 里加了三层过滤,大部分低价值记录在写入前就被拦住了。 1. 太短的跳过:observation 文本少于 30 字符的,直接丢掉。一条 ls 命令的输出没有记忆价值。 2. 低价值信号跳过:如果文本里包含 exit code、exit: 0、[SILENT]、usage:、entry count:、hits: 这些信号,说明是一次无意义操作,跳过。 3. 重叠去重:这一层在 on memory write 里已经实现了——检查已有记录的内容重叠度,超过 60% 就跳过。observation 端的完整去重还在路上。 三层过滤下来,真正进入 sidecar 的大概是原始 observation 的三分之一。噪声少了很多。 FTS5 搜索能力 sidecar DB 上的 FTS5 虚拟表支持全文搜索。 我在 AgentMemoryDB.search 方法里实现了这个能力。 搜索时先把用户的自然语言查询转成 FTS5 语法: 把查询词用 OR 连接,每个词加双引号,最多取前 12 个 token。 如果 FTS5 查询失败(比如包含特殊字符),会自动降级为 LIKE 模糊搜索。 这意味着你可以用 agent memory search "API bug 修复" 来搜索,不需要精确匹配。 它还支持按 agent 过滤——只看 Claude Code 的记录,或者只看 Hermes 的。 改造前 vs 改造后 维度 改造前 改造后 记忆覆盖范围 Claude Code 单端 Claude Code + Hermes + Codex 三端 搜索能力 各 Agent 独立搜索 统一 sidecar DB 全文搜索 跨 Agent 知识共享 不支持 sidecar DB 统一存储,支持 长期记忆 claude mem 自建 复用 Hermes 三级记忆 + Obsidian 噪声控制 LLM 自动压缩 三层过滤 + 晋升审核 事实源 无统一事实源 Obsidian 唯一事实源 维度 维度 改造前 改造前 改造后 改造后 记忆覆盖范围 记忆覆盖范围 Claude Code 单端 Claude Code 单端 Claude Code + Hermes + Codex 三端 Claude Code + Hermes + Codex 三端 搜索能力 搜索能力 各 Agent 独立搜索 各 Agent 独立搜索 统一 sidecar DB 全文搜索 统一 sidecar DB 全文搜索 跨 Agent 知识共享 跨 Agent 知识共享 不支持 不支持 sidecar DB 统一存储,支持 sidecar DB 统一存储,支持 长期记忆 长期记忆 claude mem 自建 claude mem 自建 复用 Hermes 三级记忆 + Obsidian 复用 Hermes 三级记忆 + Obsidian 噪声控制 噪声控制 LLM 自动压缩 LLM 自动压缩 三层过滤 + 晋升审核 三层过滤 + 晋升审核 事实源 事实源 无统一事实源 无统一事实源 Obsidian 唯一事实源 Obsidian 唯一事实源 坦白说当前进度:sidecar DB + Hermes Provider 已经跑通了,Codex 的 hooks.json 也已经配置好就位。 Claude Code 的 adapter 目录 adapters/claude code/ 还没创建,这是下一步要做的。 但核心架构和代码已经落地,数据流通路已经打通。 还有点话 折腾了一圈,最大的收获不是代码,是一个认知。 AI 工具的记忆,不是"记得你说过什么"。 你说过什么,对话历史里本来就有。 AI 工具的记忆,是在正确的时候把正确的上下文喂给 AI。 claude mem 在 Claude Code 开会话时,从历史记忆里捞相关片段塞进 system prompt。 Claude 一上来就知道你之前做过什么、踩过什么坑。 这比你自己手动把背景信息复制粘贴进新对话,效率高太多了。 但我更想说的是后面那一步——三端共享。 工具是工具,记忆是记忆。 Claude Code 是个好工具,Hermes 是个好工具,Codex 也是。 但它们的记忆不应该被绑定在各自工具里。 分开管,比绑在一起强。 把事件采集和长期记忆拆开,所有 Agent 的事件汇入公共池,再由统一的系统筛选和沉淀。 这个思路不仅适用于 AI 工具,也适用于任何需要跨系统知识共享的场景。 说到底,一个人同时用好几个 AI 工具的时候,最需要的不是每个工具都变得更强,而是让它们之间能说上话。 记忆不绑定工具,工具才能为你所用。 既然看到这里了,如果觉得不错,随手点个赞、在看、转发三连吧,如果可以给我个星标⭐,将不胜感激~谢谢你看我的文章,我们,下次再见。 AI编程 ClaudeCode Hermes Codex 永久记忆 AI工具 作者:大象 推动 AI 共学,让普通人轻松上手AI 相关链接 1. claude mem GitHub:https://github.com/thedotmack/claude mem 2. Claude Code 官方文档:https://docs.anthropic.com/en/docs/claude code 3. Hermes Agent 文档:https://hermes agent.nousresearch.com/docs 公众号:大象 AI 共学 个人号:Yishouhundanqu(注明来意) 预计字数:5500 字 阅读时间:15 分钟 难度等级:⭐⭐(小白友好,技术细节有类比翻译) 核心价值:看完能用 claude mem 给 AI 装上永久记忆,理解跨 Agent 记忆共享的架构设计 预计字数:5500 字 阅读时间:15 分钟 难度等级:⭐⭐(小白友好,技术细节有类比翻译) 核心价值:看完能用 claude mem 给 AI 装上永久记忆,理解跨 Agent 记忆共享的架构设计 81,391 颗星⭐️。 这是一个 npm 包的 GitHub 星标数。 不是 Next.js,不是 React,不是任何你听过的大项目。 是一个叫 claude mem 的小工具。 它做了一件事:让你的 Claude code 拥有永久记忆。 关掉对话重新打开,它还记得你上次改了什么文件、遇到了什么报错、用了什么命令。 就像一个从不遗忘的同事。 一条命令就能装好: 装完之后重启 Claude Code,它会自动开始工作。 没有任何配置。 但用了之后发现一个问题。 我同时用三个 AI 编程工具。 Claude Code 写代码,Hermes 做日常助理和内容创作,Codex 做结构化开发。 三个工具各有各的记忆系统,互不相通。 Claude Code 记得我在项目 A 修了什么 bug,Hermes 不知道。 Hermes 知道我偏好什么写作风格,Claude Code 不知道。 我需要的不只是一个工具的记忆。 我需要三端共享的"外脑"。 所以我拆开了 claude mem,研究它的架构,然后做了一件事:把它改造成三端共享的记忆底座。 这篇文章就是改造记录。 有架构、有代码、有踩坑。 claude mem 是怎么工作的 先说一个不太恰当但很好理解的类比。 你有个助理,每次你让他做什么事,他就在笔记本上记一笔。 做完之后,他会把笔记整理成两份。 • 一份是"今天做了什么"的流水账。 • 另一份是"学到了什么"的知识卡。 流水账过一阵就丢了,知识卡永久保存。 下次你问他问题,他会先翻知识卡。 找到相关的,直接告诉你。 🐵 概念定义: claude mem 就像一个挂在 Claude Code 手边的笔记本系统。 Claude 每调用一个工具 • 读文件 • 跑命令 • 写代码 笔记本就记一笔。 等 Claude 干完活,它把流水账压缩成知识卡,存进本地数据库。 下次开会话,知识卡自动喂给 Claude。 概念定义: claude mem 就像一个挂在 Claude Code 手边的笔记本系统。 Claude 每调用一个工具 • 读文件 • 跑命令 • 写代码 笔记本就记一笔。 等 Claude 干完活,它把流水账压缩成知识卡,存进本地数据库。 下次开会话,知识卡自动喂给 Claude。 claude mem 就是这个笔记本。 它是怎么"挂"上去的? Claude Code 有一个叫 hooks 的机制。 你可以在 /.claude/settings.json 里配一系列钩子。 Claude 每次做特定动作,就自动触发这些钩子。 claude mem 装好之后,它在 Claude Code 的插件目录里放了一个 hooks.json,注册了五个钩子。 简化版长这样: 真实配置比这长得多。 每条命令前面有一大堆路径查找逻辑,因为它要兼容不同操作系统、不同 Node 版本、不同安装路径。 但核心逻辑就这些:四个时间点,四个动作。 四个钩子的数据流 我把它的工作流画成一条线,你一眼就能看懂。 • SessionStart → 启动后台服务,加载历史记忆上下文。 ◦ Claude 一开对话,claude mem 就把之前积累的知识喂给它。 ◦ Claude 一上来就知道你之前做过什么。 ◦ Claude 一开对话,claude mem 就把之前积累的知识喂给它。 ◦ Claude 一上来就知道你之前做过什么。 • UserPromptSubmit → 记录你说了什么。 ◦ 每次输入 prompt,它都捕获下来,用于理解对话意图。 ◦ 每次输入 prompt,它都捕获下来,用于理解对话意图。 • PostToolUse → 核心环节。 ◦ Claude 每调用完一个工具(读文件、写代码、跑命令),这个钩子就触发。 ◦ claude mem 从工具的输入输出里提取关键信息,生成一条 observation。 ◦ Claude 每调用完一个工具(读文件、写代码、跑命令),这个钩子就触发。 ◦ claude mem 从工具的输入输出里提取关键信息,生成一条 observation。 一次典型的 observation 长这样: • Stop → Claude 停止工作时,claude mem 把本轮积累的所有 observation 喂给 LLM, ◦ 压缩成 narrative(叙述)、facts(事实)、concepts(概念)三部分,存入长期记忆。 ◦ 压缩成 narrative(叙述)、facts(事实)、concepts(概念)三部分,存入长期记忆。 已省略 Setup 和 PreToolUse" 已省略 Setup 和 PreToolUse" 🥛 我的感悟: 这个设计很聪明。 它不是把所有对话原文都存下来——那太浪费了。 它只存"做了什么"和"学到了什么"。 LLM 就是中间的编辑,把流水账提炼成知识卡。 不是存原文,是存理解。 我的感悟: 这个设计很聪明。 它不是把所有对话原文都存下来——那太浪费了。 它只存"做了什么"和"学到了什么"。 LLM 就是中间的编辑,把流水账提炼成知识卡。 不是存原文,是存理解。 存在哪里? 底层是 SQLite,加了两层搜索能力。 FTS5 做全文搜索,支持向量搜索(PostgreSQL pgvector 风格)。 你问它"上次那个 API 报错怎么修的",它能通过关键词和语义两种方式找到答案。 为什么我不能只装一下就完事 claude mem 装上之后,Claude Code 确实有了记忆。 但我的问题没解决。 坦白说,claude mem 解决的是"单 Agent 的记忆"问题。 你用 Claude Code 写代码,它记得你改了什么。 但你换到 Hermes 问"我上次在 Claude Code 里修的那个 API bug,具体改了哪些文件",Hermes 只能一脸茫然。 这不是 claude mem 的 bug。 这是架构局限。 claude mem 的记忆库是和 Claude Code 绑定的。 存储路径、索引方式、知识格式,都为 Claude Code 服务。 其他 Agent 进不来。 📚 三个工具三个脑子,互相不通。 就像三个同事,各自记各自的笔记,从不分享。 Claude Code 知道你修了 bug,Hermes 知道你写文章喜欢什么风格,Codex 知道你项目结构怎么搭。 但它们互相不知道。 三个工具三个脑子,互相不通。 就像三个同事,各自记各自的笔记,从不分享。 Claude Code 知道你修了 bug,Hermes 知道你写文章喜欢什么风格,Codex 知道你项目结构怎么搭。 但它们互相不知道。 我的真实场景是这样的。 比如我在 Claude Code 里修了一个 API 路由的 bug,改了 routes.ts 和 middleware.ts 两个文件。 Claude Code 记得这件事。 但第二天我在 Hermes 里写一篇关于这次 bug 修复的技术文章时,Hermes 完全不知道这件事发生过。 我得手动把修 bug 的细节复制过来告诉它。 更头疼的是写作风格。 Hermes 知道我写文章喜欢口语化、短句、不用黑话。 Claude Code 不知道这些。 每次让它帮我写文档,出来的都是"综上所述""值得注意的是"这种 AI 味满满的官样文章。 🎼 claude mem 的思路没问题,但格局不够大。 它把"事件采集"和"长期记忆"绑在一个 Agent 里。 正确的做法是拆开 所有 Agent 的事件汇入一个公共池,再由统一的系统筛选、提炼、晋升为长期知识。 claude mem 的思路没问题,但格局不够大。 它把"事件采集"和"长期记忆"绑在一个 Agent 里。 正确的做法是拆开 所有 Agent 的事件汇入一个公共池,再由统一的系统筛选、提炼、晋升为长期知识。 于是我开始动手改造。 三端共享架构设计 这一章是干货最多的部分。 我尽量讲清楚。 整体架构 先看架构图: 三端各自通过自己的 hook 或 Provider 接口采集事件,全部写入同一个 sidecar DB。 sidecar DB 不属于任何一个 Agent,是独立的中转站。 原始事件在 sidecar DB 里经过筛选和晋升,高价值的才进入 Hermes 的三级记忆系统,最终同步到 Obsidian。 三个核心设计决策 第一,sidecar DB 放在哪里? 我选了 /.hermes/state/agent memory events.db。 这个路径不属于 Claude Code,不属于 Codex,不属于 Hermes。 它属于"大象的 Agent 体系"。 不管你用哪个工具,事件都往这里写。 这个决定看起来很小,其实是整个架构的地基。 如果 sidecar DB 放在某个 Agent 的目录下,那个 Agent 就天然地成了"主人",其他工具就成了"客人", 共享就变成了寄生。 第二

在 小宇宙note 阅读完整内容