在构建具备长期学习能力的 AI Agent 时,记忆系统的设计往往决定了 agent 是否能够在多轮交互中真正「成长」。Hermes Agent 作为 Nous Research 推出的自改进型 agent,其记忆架构并非简单的日志存储,而是一套基于 epoch 触发的分层固化机制。理解这一机制的设计思路,对于工程化部署和调优具有重要的参考价值。
三层记忆架构与时间尺度的分离
Hermes Agent 的记忆系统并非单一容器,而是按照信息保留的时间尺度划分为三个相互协作的子系统。第一层是持久记忆(MEMORY.md 与 USER.md),这一层以系统提示词的形式在每个会话初始化时注入,随后在会话期间保持冻结状态。MEMORY.md 承载环境事实、项目约定和跨会话的关键知识,而 USER.md 则记录用户的沟通风格和工作偏好。两者的容量受到严格限制 ——MEMORY.md 上限约为 800 个 token,USER.md 上限约为 500 个 token。这种设计确保了即使在数千次交互后,agent 的核心上下文仍然保持精炼且可缓存。
第二层是情景记忆,以 Skills 技能文档的形式存在。与传统的键值存储不同,Skills 是从具体经验中提炼出来的程序性知识。当 agent 完成一个包含五个以上工具调用的复杂任务、遇到错误后找到替代路径、或者发现值得复用的工作流时,它会在后台创建或更新一个 Markdown 格式的技能文档。这个文档不仅描述「发生了什么」,更重要的是记录「如何高效完成」「应当避免什么」以及「如何验证成功」。这正是情景记忆向语义记忆迁移的核心表现 —— 从具体的交互轨迹中抽象出可复用的模式。
第三层是基于 SQLite FTS5 的会话搜索系统。所有会话内容都被完整归档到本地数据库中,并通过全文索引支持即时检索。当 agent 需要回溯历史上下文时,它会执行 FTS5 查询获取相关会话片段,然后调用轻量级模型(如 Gemini Flash)对检索结果进行摘要,最终将摘要注入当前上下文。这一层没有容量上限,构成了 agent 记忆的「冷存储」层。
Epoch 触发机制:记忆固化的时机选择
理解 Hermes 的记忆 epoch 架构,关键在于把握记忆固化的触发条件。系统并非在每次交互后都尝试写入持久层,而是设计了明确的检查点机制。根据代码分析,Hermes 在每执行 15 次工具调用后会触发一次自检。在这个检查点上,agent 会评估当前工作是否涉及可复用的程序性知识。如果是,它会创建或更新对应的 Skill 文档。这种设计体现了「经验压缩」的核心思想 —— 不是记录每一次交互的完整轨迹,而是将有价值的工作流提取为结构化的技能文档。
对于更底层的记忆压缩,Hermes 采用容量驱动的触发策略。当 MEMORY.md 接近字符上限(约 2200 字符)时,系统会自动启动压缩流程:识别冗余条目、移除已被取代的条目、将相关条目合并为更紧凑的表述。与传统数据库的主动压缩不同,Hermes 的压缩由 LLM 自身驱动 —— 由模型判断哪些信息足够重要以至于值得保留。这种「智能压缩」的代价是压缩结果的质量高度依赖于底层模型的推理能力。
经验压缩的三层策略
Hermes 的记忆压缩并非单一算法,而是针对不同类型信息设计的复合策略。时序压缩(Temporal Compression)作用于近重复观察的合并 —— 当用户在多次会话中表达相同的偏好或遇到相似的问题时,系统会将这些跨时间的重复记录合并为单一条目,并标注其有效性时间范围。这避免了记忆文件中「用户喜欢简洁回复」被重复记录十次的冗余现象。
语义压缩(Semantic Compression)则更进一步,它将相关的情景记忆条目融合为更高层次的概念。例如,多个关于「如何使用 fal.ai API 生成品牌图像」的技能文档,可能被合并为一个涵盖图像生成工作流的统一技能。这种压缩需要模型具备从具体案例中抽象共性的能力,也是 Hermes 从情景记忆向语义记忆迁移的主要通道。
差分压缩(Differential Compression)则是一种更底层的存储优化策略。系统不存储完整的记忆快照,而是记录相邻记忆状态之间的变更差量。这类似于版本控制系统的 delta 存储机制 —— 在恢复特定历史记忆时,需要将差量逐层回放。对于存储空间受限的部署场景,这种策略可以显著降低持久化成本。
情景记忆与语义记忆的分离存储
理解 Hermes 记忆架构的关键,在于把握情景记忆(Episodic Memory)与语义记忆(Semantic Memory)的分离设计。情景记忆对应 Skills 系统中那些从具体交互中诞生的技能文档 —— 它们记录了特定情境下的成功路径、失败教训和验证方法。例如,一个关于「在 macOS 上使用 Python 脚本为图像添加水印」的技能,本质上是对某次具体任务的完整过程归档。
语义记忆则对应 MEMORY.md 中那些经过抽象的通用性知识 ——「项目使用 tabs 缩进」「数据库已从 MySQL 迁移到 PostgreSQL」「用户偏好通过 Discord 接收紧急任务通知」。这些条目不再绑定于特定情境,而是跨场景适用的事实陈述。
两者的分离存储带来了一个重要的工程特性:检索路径的差异化。情景记忆(Skills)采用渐进式披露机制 —— 系统提示词中仅包含技能名称和描述(约 3K token 承载 40+ 技能的元信息),只有在 agent 判断需要调用某一技能时,才会加载完整的 SKILL.md 内容。这种设计将技能层的 token 消耗从 O (n) 降低到 O (1),其中 n 为已安装技能数量。相比之下,语义记忆(MEMORY.md)在每次会话初始化时完整注入,检索成本为零但固定开销存在。
检索路径工程:FTS5 与按需加载的权衡
第三层会话搜索的设计体现了存储成本与检索延迟之间的工程权衡。SQLite FTS5 提供了高效的全文索引能力,查询延迟通常在毫秒级。然而,真正的成本不在搜索本身,而在于后续的 LLM 摘要环节。当 agent 发起一次会话回溯时,系统需要执行 FTS5 查询、获取相关会话片段、调用轻量级模型生成摘要、将摘要注入上下文 —— 这一流程的端到端延迟通常在数百毫秒到数秒之间,取决于网络和模型响应速度。
对于需要极致响应速度的场景,可以考虑以下参数调优方向。首先,限制 FTS5 返回结果的数量 —— 返回前 5 条与返回前 20 条的摘要延迟可能相差数倍。其次,在本地部署轻量级摘要模型(如 Gemini Flash 1.5 或类似规格的本地模型),可以消除网络开销。第三,针对高频检索的关键词建立独立的索引表,可以进一步压缩搜索空间。
配置参数与工程实践建议
对于在生产环境中部署 Hermes 的开发者,以下几个配置参数值得重点关注。memory_char_limit 控制 MEMORY.md 的容量上限,默认值 2200 字符(约为 800 个 token)。如果 agent 需要记住更多跨会话事实,可以将此值提高到 4000-5000 字符,但需要留意系统提示词的总体长度增长。user_char_limit 控制 USER.md 的容量,默认值 1375 字符。对于多用户场景或需要维护复杂用户画像的应用,可以适当提高这一阈值。
在 Skills 管理方面,建议定期执行技能审计 (hermes skills audit),清理那些已过时或低频使用的技能。如前文所述,技能列表的元信息占用约 2.2K token 的系统提示词空间,对于 token 预算紧张的应用,这一开销不可忽视。对于团队协作场景,可以利用外部技能目录机制(skills.external_dirs 配置项)共享技能库,而无需在每个实例本地维护副本。
小结
Hermes Agent 的记忆 epoch 架构本质上是一套「分级存储、渐进固化」的工程系统。情景记忆(Skills)通过 15 工具调用检查点从交互轨迹中提取,语义记忆(MEMORY.md)通过容量驱动的压缩机制持续精炼,而会话历史(FTS5)则构成了可按需检索的冷存储。三层之间的信息流动遵循从具体到抽象、从临时到持久的单向路径,而检索路径的差异化设计(渐进式披露 vs. 即时注入 vs. 按需搜索)则在灵活性与效率之间取得了平衡。理解这一架构的设计逻辑,有助于在实际部署中进行针对性的参数调优和性能优化。
参考资料:
- Hermes Agent 官方文档:https://hermes-agent.nousresearch.com/docs/
- Hermes Agent GitHub 仓库:https://github.com/NousResearch/hermes-agent