深度研究 | Hermes 记忆系统深度解析:四层架构如何重塑 Agent 记忆范式
00 / 引言:从"养虾"到 Hermes
前段时间,出现了一个有趣的现象:很多人开始放弃"养虾"(openclaw),纷纷转向一个名为Hermes的开源 Agent 项目。不得不感叹技术变化之快,因为Hermes 是开源的,所以我也研究了一下Hermes的代码,看看是技术的快速迭代,还是说Hermes真有东西。
通过深入Hermes的源码,发现 Hermes 在记忆系统架构的设计值得借鉴,于是写了这篇文章详细分析梳理一下Hermes的记忆系统。下面我们一起看看它是如何构建 prompt 状态、持久化会话、刷新记忆和查询历史对话的。
首先说一个核心发现:Hermes 没有采用单一的记忆系统,而是构建了四个独立但协同的记忆层级。
支撑这四层架构的核心设计原则简单而深刻:保持 prompt 稳定以支持缓存,将其他内容推送到工具层。
01 / Hermes 的上下文结构
在深入记忆系统之前,有必要先理解 Hermes 实际发送给模型的内容结构。
Prompt 组装顺序
Hermes Prompt 组装流程────────────────────────────────────────────────────────────────[0] 默认 Agent 身份定义[1] 工具感知的行为指导[2] Honcho 集成块(可选)[3] 可选的系统消息[4] 冻结的 MEMORY.md 快照[5] 冻结的 USER.md 快照[6] Skills 索引[7] 上下文文件(AGENTS.md, SOUL.md, .cursorrules, .cursor/rules/*.mdc)[8] 日期/时间 + 平台提示[9] 对话历史[10] 当前用户消息────────────────────────────────────────────────────────────────这一结构的背后是 Hermes 对提供商侧 prompt 缓存的深度优化。Prompt 构建器在源码中非常明确地表达了这一点:稳定前缀应尽可能长时间保持稳定。
这一个设计决策解释了 Hermes 记忆架构的大部分选择:
- 如果信息需要在每轮都可用 → 保持极小并注入一次
- 如果信息量大、历史性强或偶尔有用 → 推出 prompt,按需检索
02 / Layer 1: 冻结提示词记忆
Hermes 的内置记忆系统出奇地小。
1.1 双文件结构
Hermes 在~/.hermes/memories/目录下存储持久化记忆:
| 文件 | 用途 | 字符限制 |
|---|---|---|
MEMORY.md | Agent 关于环境、约定、工具特性、经验教训的笔记 | 2,200 字符 |
USER.md | 用户档案:偏好、沟通风格、身份信息 | 1,375 字符 |
总共约1,300 tokens。这不是很多。
而且这是有意为之。
1.2 会话冻结机制
在会话开始时,Hermes 加载这两个文件,将其渲染为 prompt 块,然后为会话的其余部分冻结该快照。
会话生命周期中的内存行为────────────────────────────────────────────────────────────────Session Start ↓加载 MEMORY.md + USER.md ↓渲染到系统提示词 ↓【冻结快照】←─── 此后系统提示词不再变化 ↓用户交互进行中... ↓内存写入操作 → 持久化到磁盘 ↓但不会改变已构建的系统提示词 ↓仅在新会话开始或压缩触发重建时生效────────────────────────────────────────────────────────────────会话中的写入会立即持久化到磁盘,但不会改变已构建的系统提示词。这些变更只有在新会话开始时,或在压缩触发的 prompt 重建后才会显现。
1.3 渲染格式
══════════════════════════════════════════════MEMORY (your personal notes) [67% — 1,474/2,200 chars]══════════════════════════════════════════════User's project is a Rust web service at ~/code/myapi using Axum + SQLx§This machine runs Ubuntu 22.04, has Docker and Podman installed§User prefers concise responses, dislikes verbose explanations1.4 四个精妙设计
设计一:使用字符限制而非 token 限制
这使得内存逻辑与模型无关。Hermes 不需要特定于模型的分词器来决定内存是否已满。
设计二:基于简单分隔符的文件格式
条目之间用§分隔。没有向量数据库。没有自定义二进制存储。只是纯文本文件。
设计三:系统提示词记忆故意保持极小
这可能是整个设计中最重要的点。Hermes 并不试图将整个历史填入 prompt 内存。它只想要最高价值的事实。
设计四:将记忆视为策展状态,而非日记
这是 Hermes 与 Clawdbot 之间最大的区别。
Clawdbot 的日志有一种仅追加的风格。Hermes 明确推向相反方向。工具模式和测试表明:
- √ 保存用户偏好
- √ 保存环境事实
- √ 保存重复性修正
- √ 保存稳定约定
- × 不保存任务进度
- × 不保存会话结果
- × 不保存临时 TODO 状态
Hermes 希望MEMORY.md和USER.md保持热状态、紧凑且缓存友好。
1.5 Memory 工具操作
Hermes 通过单一的memory工具管理这些文件,提供三个动作:
memory( action="add", # 添加新条目 target="memory", # "memory" 或 "user" content="...")memory( action="replace", # 替换现有条目 target="user", old_text="dark mode", content="User prefers light mode in VS Code")memory( action="remove", # 删除条目 target="memory", old_text="SSH backdoor hints")一个很好的可用性细节是:replace和remove使用子字符串匹配。你不需要内部 ID。只需传递现有条目中的唯一子字符串。
1.6 安全防护
系统还会在进入 prompt 内存之前拒绝完全重复的内容并阻止危险内容。源码扫描内存条目中的:
- prompt 注入模式
- 凭证泄露字符串
- SSH 后门提示
- 不可见的 Unicode 字符
这是合理的,因为写入内存的内容实际上将成为未来系统提示词的一部分。
03 / Layer 2: session_search 情景回忆
如果MEMORY.md和USER.md是 Hermes 的热记忆,那么session_search就是它的长尾回忆系统。
2.1 SQLite 架构
所有过去的会话存储在~/.hermes/state.db,一个包含以下内容的 SQLite 数据库:
-- 会话表CREATETABLE sessions ( idINTEGER PRIMARY KEY, parent_session_id INTEGER, created_at TIMESTAMP, -- ...);-- 消息表CREATETABLE messages ( idINTEGER PRIMARY KEY, session_id INTEGER, roleTEXT, contentTEXT, timestampTIMESTAMP, -- ...);-- FTS5 全文搜索索引CREATEVIRTUALTABLE messages_fts USING fts5( content, role, session_id);2.2 搜索管道
当模型需要从先前对话中回忆某事时,Hermes不会搜索MEMORY.md。它搜索会话数据库。
Hermes 的情景回忆管道────────────────────────────────────────────────────────────────FTS5 全文搜索过往消息 ↓按会话分组结果 ↓解析父/子谱系 ↓加载顶部匹配会话 ↓在相关匹配周围截断脚本 ↓使用廉价的辅助模型总结每个会话 ↓将聚焦的摘要返回给主模型────────────────────────────────────────────────────────────────2.3 与语义索引的对比
这与试图对每个内存笔记进行语义索引的系统非常不同。
Hermes 基本上是在说:
- 保持始终注入的记忆极小
- 将真实历史存储在 SQLite 中
- 仅在需要时搜索该历史
- 在交还之前总结结果
这是一个务实的设计。它也比盲目地将长历史填入每个 prompt 更便宜。
文档将session_search描述为回答以下问题的方式:
- “我们上周讨论过这个吗?”
- “我们对 X 做了什么?”
- “正如我之前提到的……”
换句话说,MEMORY.md用于持久事实,而session_search用于情景回忆。
04 / Layer 3: 压缩与内存刷新
Hermes 另一个巧妙的部分是在压缩长对话之前发生的事情。
随着会话增长,Hermes 最终会总结对话的中间部分以保持在模型的上下文窗口内。但总结是有损的。重要的事实可能会消失。
3.1 内存刷新机制
所以 Hermes 首先进行内存刷新。
在压缩之前,它会注入一个合成的系统/用户指令,基本上说:
会话正在被压缩。保存任何值得记住的内容。优先考虑用户偏好、修正和重复模式,而非特定于任务的细节。然后它只使用memory工具运行一个额外的模型调用。
3.2 压缩流程
如果模型认为某些内容应该在压缩中幸存下来,它会在对话被总结之前将其写入MEMORY.md或USER.md。
完整压缩流程────────────────────────────────────────────────────────────────长对话进行中 ↓【触发压缩条件】 ↓内存刷新阶段 → 注入特殊指令 → 仅启用 memory 工具 → 模型决定哪些内容应持久化 → 写入 MEMORY.md/USER.md ↓压缩中间轮次 ↓重建 prompt(从磁盘重新加载内存) ↓继续使用更小的上下文和更新的内存────────────────────────────────────────────────────────────────3.3 缓存失效与重建
更好的是,压缩后 Hermes 会使缓存的系统提示词失效并重建,从磁盘重新加载内存。这意味着在压缩前立即刷新的任何内容都将成为下一个稳定 prompt 快照的一部分。
流程:长对话→ 将持久事实刷新到内存→ 压缩旧轮次→ 重建 prompt→ 使用更小的上下文和更新的内存继续这正是让 Hermes 感觉像一个真正的记忆架构而不是附加笔记存储的原因。
05 / Layer 4: Skills 作为程序性记忆
Hermes 的记忆故事不仅仅是事实和脚本。
它还有技能。
4.1 Skills 的定位
技能位于~/.hermes/skills/下,充当可重用的知识文档。文档明确将其描述为 Agent 的程序性记忆。
当 Hermes 发现非平凡的工作流、修复棘手问题或学到更好的做事方法时,它可以将其保存为技能并在以后重用。
这是件大事。
大多数记忆系统只关注语义回忆:姓名、偏好、事实、摘要。但 Agent 还需要记住如何做事,而不仅仅是发生了什么。
4.2 三种记忆类型的分离
Hermes 通过将程序性知识与 prompt 内存分离来处理这个问题:
| 语义记忆 | MEMORY.md / USER.md | 紧凑的持久事实 | 用户偏好、环境配置 |
| 情景记忆 | session_search | 情景回忆 | “我们上周讨论了什么?” |
| 程序记忆 | skills/ | 可重用工作流 | 如何修复特定 bug、部署流程 |
4.3 Token 效率技巧
这里还有一个不错的 token 效率技巧。Hermes 不会盲目地将每个技能注入 prompt。它注入一个紧凑的技能索引,并且只在需要时加载完整的技能内容。
Skills 注入策略────────────────────────────────────────────────────────────────每次轮次 ↓注入紧凑的 Skills Index ├── 技能名称列表 └── 简短描述 ↓模型判断需要哪个完整技能 ↓按需加载完整技能内容────────────────────────────────────────────────────────────────这使得程序性记忆可用,而无需在每轮支付完整的 token 成本。
06 / Layer 5: Honcho 深度用户建模
然后是可选的 Honcho 层。
如果本地内存是 Hermes 的策展笔记本,那么 Honcho 就是它对更丰富用户模型的尝试。
5.1 Honcho 的功能
Honcho 在默认的hybrid模式下与内置内存系统一起运行。它添加:
- 跨会话用户建模
- 跨机器和跨平台连续性
- 用户上下文的语义搜索
- 关于用户或 AI 同伴的辩证、LLM 生成的答案
有趣的部分是 Hermes 如何在不破坏 prompt 缓存的情况下集成它。
5.2 首轮 vs 后续轮次
Honcho 集成策略────────────────────────────────────────────────────────────────【首轮对话】 ↓预取的 Honcho 上下文可以烘焙到缓存的系统提示词中 ↓【后续轮次】 ↓避免改变稳定的系统提示词 ↓在 API 调用时将 Honcho 回忆附加到当前用户轮次 ↓这意味着: • 稳定前缀保持稳定 • Prompt 缓存仍然有效 • 第 N 轮可以消费在第 N-1 轮后预取的上下文────────────────────────────────────────────────────────────────5.3 双同伴建模
Honcho 本身也建模两个同伴:
- 用户
- AI 助手
所以 Hermes 不仅试图记住你。它还可以随着时间的推移构建自身的表示。
这既酷又有点狂野。
07 / Hermes vs openclaw:设计哲学对比
我之前也写过关于 openclaw记忆架构的文章,所以比较值得明确说明。
7.1 openlcaw的方式
openclaw 架构────────────────────────────────────────────────────────────────存储模式:Markdown 优先 ↓主要真相来源:每日日志和长期内存文件 ↓记忆回忆:对存储笔记的混合搜索────────────────────────────────────────────────────────────────7.2 Hermes 的方式
Hermes 架构────────────────────────────────────────────────────────────────Prompt 内存:激进边界控制 ↓会话历史:SQLite,不在 prompt 内存文件中 ↓过去工作回忆:通过 session_search ↓程序记忆:推送到 skills ↓深度用户建模:可选地委托给 Honcho────────────────────────────────────────────────────────────────7.3 核心差异
这里的关键是,Hermes 比 Clawdbot更具缓存意识。
- Clawdbot更倾向于"记忆作为可搜索的存储知识"
- Hermes更倾向于"记忆作为热工作集加上冷检索层"
我实际上认为这是生产 Agent 的正确方向。
并非所有内容都值得生活在系统提示词中。
08 / Hermes 的三大成功之处
在浏览了 repo 和文档后,我认为 Hermes 在三个大方向上做对了。
8.1 分离热记忆与冷回忆
这是核心架构胜利。
Hermes 的热/冷分离────────────────────────────────────────────────────────────────热记忆(Prompt Memory) • 小(~1,300 tokens) • 快速访问 • 缓存友好 • 始终可用冷回忆(Retrieval Layers) • SQLite 会话历史 • Skills 程序记忆 • Honcho 用户建模 • 按需访问────────────────────────────────────────────────────────────────小 prompt 内存用于始终重要的东西。搜索只对偶尔重要的东西。
8.2 将 prompt 稳定性视为一等约束
许多 Agent 系统谈论内存时不谈论缓存。Hermes 显然关心两者。
冻结快照、延迟 prompt 更新、轮级 Honcho 注入和压缩会话重建都指向同一个设计原则:
如果你想获得良好的延迟和成本,就不要随意改变你的 prompt。
Prompt 稳定性保障机制────────────────────────────────────────────────────────────────✅ 会话开始时冻结内存快照✅ 会话中写入不立即更新 prompt✅ 仅在压缩或新会话时重建✅ Honcho 上下文在轮级附加而非改变系统提示词────────────────────────────────────────────────────────────────8.3 承认记忆是复数的
Hermes 不假装一个存储就能解决一切。
它有:
- 语义档案记忆(MEMORY.md / USER.md)
- 情景会话回忆(session_search)
- 通过技能的程序记忆(Skills)
- 通过 Honcho 的可选高阶用户建模
这是对 Agent 实际需要的更现实的看法。
09 / 视界君观点:记忆架构的范式转移
Hermes 的记忆系统研究让我对 Agent 记忆有了更深的理解。
9.1 从"更多"到"正确"的范式转变
很多 Agent 项目的记忆系统追求"记住更多"——更大的上下文窗口、更多的历史记录、更丰富的向量存储。
但 Hermes 的启示是:问题不是记不住,而是记了太多不该记的东西。
传统范式 Hermes 范式────────────────────────────────────────────────────────────────记住更多 记住正确的东西 ↓ ↓更大上下文 分层存储 ↓ ↓更多 tokens 热记忆 + 冷检索 ↓ ↓成本爆炸 缓存优化────────────────────────────────────────────────────────────────9.2 Prompt 缓存是被忽视的瓶颈
在 Agent 的性能讨论中,我们经常关注:
- 模型推理速度
- 工具调用效率
- 记忆检索延迟
但prompt 缓存往往被忽视。
Hermes 的设计表明,在真实生产环境中,prompt 缓存的影响可能超过所有其他因素。一个稳定的 prompt 前缀意味着:
- 大幅降低 API 成本
- 显著提升响应速度
- 更好的用户体验
9.3 多层记忆是自然的选择
人类记忆本身就是多层的:
- 工作记忆(短期,当前任务)
- 情景记忆(过去经历)
- 语义记忆(事实知识)
- 程序记忆(技能)
Hermes 的四层架构与此惊人地对应:
人类记忆 Hermes 实现────────────────────────────────────────────────────────────────工作记忆 → 当前会话上下文情景记忆 → session_search语义记忆 → MEMORY.md / USER.md程序记忆 → Skills元认知 → Honcho(可选)────────────────────────────────────────────────────────────────这不是巧合。这是认知科学启发工程设计的典型案例。
9.4 待思考的问题
尽管 Hermes 展示了优秀的架构设计,但仍有几个问题值得关注:
问题一:字符限制的灵活性
当前 MEMORY.md 和 USER.md 的字符限制是硬编码的(2,200 和 1,375 字符)。这是否应该:
- 根据不同模型的上下文窗口动态调整?
- 根据用户的使用模式个性化?
- 引入更精细的重要性评分来决定内容留存?
问题二:Skills 的发现机制
当前通过紧凑索引按需加载技能,但随着技能数量增长,如何确保:
- 相关技能能被及时发现?
- 不会遗漏隐式相关的技能?
- Skills 之间能相互引用和组合?
问题三:跨平台的 Honcho 同步
Honcho 承诺跨机器和跨平台的连续性,但具体实现:
- 如何处理不同平台间的数据同步延迟?
- 如何保证数据一致性和隐私安全?
- 当用户在不同设备上有不同使用模式时,如何建模?
问题四:评估标准
Hermes 的记忆系统缺乏统一的评估框架。如何衡量:
- 记忆的准确性 vs 完整性?
- 检索效率 vs 覆盖率?
- 用户满意度 vs 系统复杂度?
10 / 总结
Hermes 的记忆系统不是巨型知识库,也不是增强的向量存储。它是一个分层连续性架构。
中心是一个微小的策展 prompt 内存:MEMORY.md和USER.md。围绕它的是一个用于情景回忆的可搜索 SQLite 历史。除此之外,是一个用于程序重用的技能系统。如果你启用 Honcho,Hermes 会在所有内容之上添加更深的用户模型。
所有设计之下的设计原则让我印象最深:
记忆应该帮助 Agent 保持有用,而不是破坏 prompt 稳定性
这就是真正的技巧。
不是记住更多。而是在正确的层级、以正确的成本记住正确的东西。
对于希望构建生产级 Agent 的开发者而言,Hermes 提供了一条可复制、可优化、可扩展的记忆架构路径。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~
