AI 编程助手是怎么"记住你"的?Claude Code 与 Hermes 记忆机制拆解

0 阅读11分钟

Hello,我是Niko。16年程序员老兵,专注分享 AI编程实战经验、宝藏工具资源、前沿技术动态。不玩套路,多讲干货。


记忆可能是 Agent 最被低估的能力。没有记忆,AI 编程助手每次打开都是一张白纸,不知道你的项目结构,不记得你的代码风格,上次踩过的坑下次照踩不误。

Claude Code 和 Hermes Agent 都在解决这个问题,但路径差得挺远。我翻了两边的源码和文档,拆开来说说。

太长不看版

  1. Claude Code 的记忆本质是文件分层注入:CLAUDE.md 是你写的规则,Auto-Memory 是它自己写的笔记,每次会话开始时一起加载进系统提示词。
  2. Hermes 把记忆拆成三层:事实记忆(MEMORY.md/USER.md)、会话检索(SQLite+FTS5)、过程记忆(skill),三件事分开存、分开召回。
  3. Claude Code 的 Auto-Memory 存在 ~/.claude/projects/.../memory/ 下,只加载前 200 行,超出部分按需检索。
  4. Hermes 的 MEMORY.md 容量刻意压到约 800 tokens,会话开始时作为 frozen snapshot 注入,中途写入不改变当前会话的系统提示,为的是保护 prompt cache。
  5. Hermes 的 SQLite+FTS5 不是"长期记忆",是历史档案室,解决"上次那个问题怎么修的"这类跨会话检索需求。
  6. Hermes 最有意思的是 skill_manage:把"这类任务怎么做"写成可复用流程,支持 create/patch/edit/delete,还有后台 review 机制自动判断是否值得沉淀。
  7. Claude Code 的记忆更偏代码库上下文,Hermes 的记忆更偏自我改进运行时,两者的厚度长在不同层上。
  8. 如果你主要做交互式编码,Claude Code 的文件分层够用;如果你需要 Agent 长期自主运行并积累经验,Hermes 的三层架构更系统。

先把"记忆"这个词拆开

聊 AI 编程助手的记忆,最容易犯的错是把三件不同的事混为一谈。

事实记忆。 代码风格偏好、项目用什么框架、测试怎么跑、某台服务器的特殊配置。这类信息跨会话都有用,最好一直带着。

历史检索。 "上次那个 Docker 网络问题怎么修的""上个月讨论的那个 API 方案在哪"。不需要每次都塞进上下文,但想找的时候要能搜回来。

过程记忆。 记住的不是事实也不是聊天记录,而是"这类事情应该怎么做"。一个复杂的部署流程,一套数据清洗的标准步骤,一份 PR review 的检查清单。

事实记忆回答"环境是什么",历史检索回答"之前干过什么",过程记忆回答"下次遇到同样的事该怎么做"。这三层的切分方式和投入力度,两边差别不小。

Claude Code:文件分层 + 自动笔记

Claude Code 的记忆机制,说白了就是一套多层文件注入系统。

Claude Code 记忆分层注入系统信息图表生成.png

你打开一个项目,它会按固定的层级顺序加载多个 Markdown 文件,从通用到具体:

层级文件位置谁写的内容
企业策略/etc/claude-code/CLAUDE.md管理员组织级别的规范
全局偏好~/.claude/CLAUDE.md跨项目的个人偏好
项目规则./CLAUDE.md团队项目级的架构、构建命令
模块规则.claude/rules/*.md团队子目录级的细粒度规则
个人覆盖CLAUDE.local.md个人的项目覆盖,不入 Git
自动记忆~/.claude/projects/.../memory/Claude它自己记录的笔记

前五层都是你或团队手动维护的。最后一层 Auto-Memory 才是 Claude Code 自己写的。

Auto-Memory 我用了一段时间,觉得还挺实在。它不是什么都记,会在会话过程中判断哪些信息"值得留到下次",比如一个环境特有的报错解法、你反复纠正过的编码偏好、某个库的特殊用法。然后自动写入 ~/.claude/projects/ 下的 Markdown 文件。

有个限制:Auto-Memory 启动时只加载前 200 行。超出部分不会丢,但需要按需检索。它会维护一个记忆索引文件 MEMORY.md,里面指向各个专题文件,比如 debugging_fixes.mduser_preferences.md。会话中遇到相关问题,再去翻对应的文件。

背后的哲学就四个字:宁少勿滥。

上下文窗口是稀缺资源,把所有历史都塞进去,反而稀释当前任务的注意力。Claude Code 的选择是用文件管理取代数据库检索,用手动规则兜底自动记忆,用分层覆盖留灵活性。

也因为这个设计,Claude Code 在"记忆"上有一条明确的线:它不做跨会话的历史检索。你没法说"我们上周讨论的那个方案"然后指望它自己搜回来。每轮会话的上下文是独立的,跨会话靠持久化的 Markdown 文件,不是数据库查询。

算不算缺点?看场景。每次"打开项目、干活、关掉",文件分层完全够用。但如果你希望 Agent 能说"你上次试过另一种方案,失败了因为 XX",Claude Code 目前做不到。

Hermes:三层分开存,分开召回

Hermes Agent 走了一条更精细的路。记忆拆成三个独立的层,每层有自己的存储方式、容量上限和召回策略。

新对话.png

第一层:事实记忆,两张小卡片

Hermes 的长期记忆就两个文件:

  • ~/.hermes/memories/MEMORY.md:环境事实、项目约定、工具 quirks、踩过的坑。容量约 2,200 字符(800 tokens)。
  • ~/.hermes/memories/USER.md:用户画像,偏好、沟通风格、工作习惯。容量约 1,375 字符(500 tokens)。

加起来 1,300 tokens 左右,故意压得很小。

有个工程细节值得注意:这两个文件在会话开始时被加载成 frozen snapshot。MemoryStore.load_from_disk() 执行后,当前内容捕获到 _system_prompt_snapshot。会话中途写入新记忆,会立刻落盘,但不会改变当前会话的系统提示词。

为什么?保护 prompt cache。

每轮对话都改 system prompt,缓存前缀就会不断失效,API 成本和延迟都会上涨。Hermes 的做法是:本轮维持系统提示稳定,新记忆等下一轮会话再生效。

再看安全。写入 memory 前,Hermes 会跑一轮安全扫描,检查不可见 Unicode 字符、prompt injection 模式(比如 "ignore previous instructions")、敏感信息泄露模式(比如 curl 带环境变量)。道理很简单:这些内容以后会进 system prompt,安全要求比普通笔记高得多。

写入方式也不是简单的 open("w")。先写临时文件,os.fsync() 确保落盘,再用 os.replace() 做原子替换。读写互斥靠 fcntl.flock 排他锁。这已经是运行时资产级别的规格了。

第二层:会话检索,档案室不是备忘录

Hermes 的 SQLite+FTS5 不是用来替代 MEMORY.md 的,解决的是另一类问题。

当你说"上次那个问题怎么修的""上个月的部署方案在哪",800 tokens 的事实卡片搜不到。这时候得翻历史档案。

Hermes 在 ~/.hermes/state.db 里维护了一个 SQLite 数据库(WAL 模式),存储所有会话和消息。messages_fts 是一张 FTS5 虚拟表,通过 trigger 自动维护索引。

session_search_tool.py 的检索流程:

  1. FTS5 全文检索,一次最多拉 50 条匹配结果
  2. 沿 parent_session_id 链追溯到根会话,按会话聚合
  3. 读取完整对话,格式化成可读 transcript
  4. _truncate_around_matches() 截断到匹配点附近(默认 100k 字符窗口)
  5. 并行调用快速模型做 focused summary,再返回给主 Agent

有个容易被忽略的模式:不传 query 时,它走 recent sessions,直接返回最近会话的标题和预览,零 LLM 调用。传了 query 才进入关键词搜索。

打个比方:MEMORY.md 是你每天带在口袋里的小卡片,session_search 是公司的档案室。档案室很重要,但你不会把整个档案室塞进口袋。

第三层:过程记忆,最值得细看的部分

Hermes 最有意思的地方在 skill_manage

tools/skill_manager_tool.py 开头说得很直白:skills 是 Agent 的 procedural memory,用来保存某类任务该怎么做。MEMORY.md 存偏好和事实,skill 存做事方法。

一个 skill 文件记录:什么条件下触发这个流程、具体步骤、常见失败模式、怎么验证结果、哪些命令和脚本可以复用。

skill 不是手动创建的。Hermes 有一套后台 review 机制自动判断是否值得沉淀。

run_agent.py 里,skill review 按单轮内的工具调用迭代次数计数(_iters_since_skill),默认累计 10 次迭代后,在本轮主任务结束时触发。触发后,系统 fork 一个安静的 review agent,共享主 agent 的 memory store,运行在独立线程,stdout/stderr 重定向到 /dev/null,最多跑 8 轮迭代。

review agent 回看刚才的对话,判断:是否用了一个非平凡方法?是否经历了试错和改道?有可复用经验就创建或更新 skill,没有就说 Nothing to save. 结束。

review 完成后,系统扫描 review agent 的消息历史,提取成功的工具操作,生成一行摘要通知用户,比如 💾 Memory updated · Skill 'docker-network-fix' created

思路很清楚:先把活干完,复盘交给后台,不抢主任务的注意力。

每次 create/edit/patch 操作完成后,都会对整个 skill 目录做安全扫描。判定为阻止就回滚——create 删除整个目录,edit/patch 恢复原始内容。

放在一起看:两套设计差在哪

把两边的机制摆一张表:

维度Claude CodeHermes Agent
事实记忆多层 CLAUDE.md + Auto-MemoryMEMORY.md + USER.md(frozen snapshot)
容量控制前 200 行加载,超出按需检索刻意压到 ~1,300 tokens
历史检索不支持跨会话搜索SQLite + FTS5 全文检索
过程记忆无独立机制skill_manage(create/patch/edit/delete)
自动学习Auto-Memory 自动写笔记后台 review agent 自动沉淀 skill
外部记忆Honcho、Mem0、Hindsight 等 provider
记忆更新时机会话中随时更新,立即生效写入立即落盘,但下一轮会话才进 system prompt
安全机制依赖文件系统权限写入前扫描 injection 模式 + 原子写入
设计哲学代码库上下文专家自我改进的运行时

最大的差异不在某个功能点,在于系统重心放在哪里。

Claude Code 的记忆围绕"让编码会话更顺畅"来做。每次打开项目,Claude 就知道这个项目的规矩、你的偏好、上次学到的教训。本质上是一个代码库上下文管理系统。

Hermes 的记忆围绕"让 Agent 越用越好"来做。这次做成功的事情,下次能不能自动复用?踩过的坑,能不能自动规避?本质上是一套自我改进的运行时。

打个不太准确的比方:

Claude Code 像一个记性好的同事,每次合作前把笔记本翻到正确的页面,上次约定的规矩都记得。但不会主动去总结"我们项目的标准操作流程"。

Hermes 像一个会写 SOP 的同事,不仅记得你喜欢什么,还会在做完一个复杂任务后说"这个流程我整理了一下,下次直接照这个来"。

哪种更适合你?

没有标准答案,看你怎么用。

Claude Code 更适合交互式编码场景:你在旁边看着,实时指导;团队协作,CLAUDE.md 入 Git,人人共享同一套规则;一个项目一套规则,另一个项目另一套;不需要复杂的记忆管理,文件系统就是数据库。

Hermes 更适合 Agent 长期自主运行的场景:需要自己积累经验;"上次那个问题"不应该需要用户重复一遍;部署、运维、数据处理这类有固定模式的工作;一个 Agent 服务一个人,长期建立理解。

我自己用下来的感受:Claude Code 的记忆设计在日常编码中已经够用了。Auto-Memory 加上手动维护的 CLAUDE.md,覆盖了大部分"让 AI 理解我的项目"的需求。

但 Hermes 的三层分离确实更系统。尤其是过程记忆这一层,我觉得是目前 Agent 架构里被低估的方向。大多数 Agent 框架还在讨论"要不要加记忆",Hermes 已经在讨论"不同类型的记忆该怎么分开管"。

后面会怎么走

两边都还在快速迭代。

Claude Code 的 Auto-Memory 已经出现了类似"dreaming"的后台整理机制,自动去重、归纳、优化记忆文件。如果未来加上跨会话检索和过程沉淀,它和 Hermes 的差距会缩小不少。

Hermes 的 skill_manage 虽然有安全扫描和后台 review,但自动生成的 skill 质量到底怎么样、过拟合怎么控制、跨项目迁移 skill 会不会翻车,这些我还没用够长时间来下结论。

但有一点我比较确定:Agent 的记忆不会停在"存一个文件、下次加载"这个阶段。

事实、历史、流程,是三种不同的长期资产。存储方式、召回频率、更新策略都不一样。不管走哪条路,分层迟早得做。区别只在于现在就设计进架构,还是以后再补。


Niko-白色版.png