Hermes Agent 记忆系统
Hermes 最核心的差异化能力不是工具调用,而是它真的记得你。
大多数 AI 工具每次对话都从零开始——你今天花一个小时教会它你的项目结构、命名规范、部署流程,明天开新会话,全部重来。
本章将深入解析 Hermes 如何通过三层记忆结构解决这个问题,以及 Agent 如何自主管理记忆、实现跨会话搜索与召回。
三层记忆架构
Hermes 用三层相互独立、功能互补的记忆结构来存储和召回信息。
三层设计的核心思路:高频重要信息常驻上下文,低频历史信息按需召回,深层模式由 AI 自动推理——在记忆能力与 Token 成本之间取得平衡。
┌─────────────────────────────────────────────────┐ │ 第一层:持久记忆(Persistent Memory) │ │ MEMORY.md(环境事实)+ USER.md(用户画像) │ │ → 每次会话启动时自动注入系统提示词,始终可见 │ ├─────────────────────────────────────────────────┤ │ 第二层:情节日志(Session History) │ │ SQLite + FTS5 全文检索,存储所有历史对话 │ │ → Agent 主动搜索时按需加载,不占用固定 Token │ ├─────────────────────────────────────────────────┤ │ 第三层:用户建模(Honcho,可选) │ │ 辩证推理引擎,提取跨会话模式、偏好与目标 │ │ → 比你亲口说出来的更深层地理解你 │ └─────────────────────────────────────────────────┘
| 记忆层级 | 存储位置 | 容量 | 加载方式 | 用途 |
|---|---|---|---|---|
| 持久记忆 | ~/.hermes/memories/ 下的 Markdown 文件 | ~1,300 tokens 总量 | 会话启动时自动注入系统提示词 | 关键事实,始终可见 |
| 情节日志 | SQLite 数据库 + JSONL 转录文件 | 无限(所有历史对话) | Agent 按需搜索,FTS5 全文检索 | 查找特定历史讨论 |
| Honcho 用户建模 | Honcho 服务端 API | 按 Agent 隔离 | 每轮/每 N 轮后台推理注入 | 自动推导深层偏好与目标 |
三层之间不是替代关系,而是互补关系。持久记忆回答「我总是需要知道这些」,情节日志回答「我们上周聊过这个问题吗」,Honcho 回答「你真正想要的是什么」。
持久记忆文件
持久记忆是 Hermes 记忆系统的第一层,也是最基础的一层。
它由两个存放在 ~/.hermes/memories/ 下的 Markdown 文件组成,每次会话启动时自动注入系统提示词。
两个核心文件
两个文件各司其职,互不重叠。
| 文件 | 用途 | 字符上限 | 约等于 |
|---|---|---|---|
| MEMORY.md | Agent 的个人笔记——环境事实、项目规范、工作中学到的东西 | 2,200 字符 | ~800 tokens |
| USER.md | 用户画像——你的偏好、沟通风格、工作习惯、技能水平 | 1,375 字符 | ~500 tokens |
字符上限是有意设计的——它保证记忆内容保持精炼、聚焦。如果一条新条目超出上限,memory 工具会返回错误让 Agent 先整理空间再写入,而不是悄悄丢弃旧条目。
记忆如何注入系统提示词
每次会话启动时,两个文件的内容以固定格式注入系统提示词,格式如下:
══════════════════════════════════════════════ MEMORY(Agent 个人笔记)[67% — 1,474/2,200 字符] ══════════════════════════════════════════════ 用户的项目是位于 ~/code/myapi 的 Rust Web 服务,使用 Axum + SQLx § 本机运行 Ubuntu 22.04,已安装 Docker 和 Podman § 用户偏好简洁回复,不喜欢冗长解释
这里有几个关键设计细节:
冻结快照模式:系统提示词中的记忆内容在会话开始时捕获一次,中途不会更新。
这是刻意设计——为了让 LLM 的前缀缓存(Prompt Cache)保持有效,降低 Token 成本。
Agent 在会话中修改记忆,变化立即写入磁盘,但要等下次会话启动才会出现在上下文中。
用量百分比可见:[67% — 1,474/2,200] 让 Agent 随时知道剩余容量,在接近上限时主动整理。
§ 作为条目分隔符:每条记忆之间用 § 分隔,条目本身可以是多行文字。
Agent 如何操作记忆
Agent 通过内置的 memory 工具管理记忆,支持三种操作。
| 操作 | 说明 | 参数 |
|---|---|---|
| add | 新增一条记忆条目 | target(memory/user)、content |
| replace | 替换已有条目(子串匹配定位) | target、old_text、content |
| remove | 删除已有条目(子串匹配定位) | target、old_text |
注意:没有 read 操作——记忆内容在会话启动时已经注入系统提示词,Agent 直接在上下文中看到它,不需要额外读取。
replace 和 remove 使用子串匹配定位条目,不需要提供完整条目文本:
实例
# 现在需要更新为更精确的版本
# 使用子串匹配定位——只需提供能唯一标识的片段即可
memory(
action="replace",
target="memory",
old_text="深色主题", # 唯一子串即可定位原条目
content="用户 VS Code 用浅色主题,终端用深色主题" # 替换后的新内容
)
如果子串匹配到多个条目,工具会返回错误,要求提供更精确的匹配串。
什么该记,什么不该记
Agent 会自动判断并保存有价值的信息——你通常不需要显式要求。
但了解判断标准有助于你理解 Agent 的行为,以及在需要时手动引导。
应该主动保存到 memory(环境与工作)
以下类型的信息触发 Agent 写入 MEMORY.md:
| 类型 | 示例 |
|---|---|
| 环境事实 | 本机运行 Debian 12,PostgreSQL 16,Docker 用 Podman 替代 |
| 项目规范 | ~/code/api 使用 Go 1.22,sqlc 查询,chi 路由;测试用 make test |
| 工具经验 | staging 服务器 SSH 端口是 2222,不是 22,密钥在 ~/.ssh/staging_ed25519 |
| 纠正记录 | 不要用 sudo 运行 Docker 命令,用户已在 docker 用户组 |
| 完成工作 | 2026-01-15 完成数据库从 MySQL 迁移到 PostgreSQL |
应该主动保存到 user(关于你)
以下类型的信息触发 Agent 写入 USER.md:
| 类型 | 示例 |
|---|---|
| 身份信息 | 姓名、职位、时区 |
| 沟通偏好 | 偏好简洁回复,不需要解释显而易见的步骤 |
| 厌恶项 | 不要在代码里加过多注释 |
| 工作习惯 | 每天下午 3 点前不看消息 |
| 技能水平 | 熟悉 Rust 和 Python,Go 是新学的 |
不应该保存的内容
以下内容不值得占用宝贵的记忆空间:
| 类型 | 示例 | 原因 |
|---|---|---|
| 过于笼统 | 用户有个项目 | 无信息量,无法复用 |
| 可随时重查 | Python 3.12 支持 f-string 嵌套 | 搜索即可,不值得占空间 |
| 原始数据 | 大段日志、代码块、数据表 | 超出字符限制,结构化记忆更有用 |
| 临时性内容 | 本次调试的临时文件路径 | 下次用不上 |
| 已在上下文中的内容 | 项目 SOUL.md、AGENTS.md 里已有的信息 | 重复注入浪费 Token |
好记忆 vs 坏记忆
同样的信息,写得好可以一条顶十条,写得差则毫无价值。
| 评级 | 示例 | 点评 |
|---|---|---|
| 好 | 用户的 macOS 14 Sonoma,Homebrew,Docker Desktop,Shell 是带 oh-my-zsh 的 zsh,编辑器是 VS Code + Vim 键位 | 信息密度高,相关事实打包在一起 |
| 好 | 项目 ~/code/api 使用 Go 1.22,sqlc 做 DB 查询,chi 路由。测试:make test。CI:GitHub Actions | 具体可执行的规范 |
| 好 | staging 服务器(10.0.1.50)SSH 端口 2222 不是 22,密钥 ~/.ssh/staging_ed25519 | 有上下文的经验教训,避免踩坑 |
| 差 | 用户有项目 | 太模糊,无法指导任何行动 |
| 差 | 2026 年 1 月 5 日,用户让我查看他的项目,位于 ~/code/api,我发现它使用 Go 1.22 版本…… | 太啰嗦,核心信息被淹没在叙述中 |
记忆容量管理
记忆文件有严格的字符上限,Agent 需要在接近上限时主动整理。
接近上限时会发生什么
当新条目会导致超出字符上限时,工具返回错误而非静默截断:
{
"success": false,
"error": "Memory 已用 2,100/2,200 字符。新条目(250 字符)会超出上限。
请先整理:用 replace 合并重叠条目,或 remove 过时条目,
再重试——在同一轮对话中完成。",
"current_entries": [
"用户的 macOS 14 Sonoma,Homebrew,Docker Desktop",
"项目 ~/code/api 使用 Go 1.22,sqlc 做 DB 查询"
],
"usage": "2,100/2,200"
}
收到这个错误后,Agent 的正确做法是:
- 读取当前所有条目(错误响应中已经包含)
- 找出可以删除或合并的条目
- 用
replace将几条相关条目合并为一条更精炼的版本 - 然后重试添加新条目
最佳实践:当系统提示词显示记忆使用率超过 80% 时,主动整理,不要等到报错。预防永远比补救更省 Token。
容量参考
| 存储 | 上限 | 典型条目数 |
|---|---|---|
| MEMORY.md | 2,200 字符 | 8–15 条 |
| USER.md | 1,375 字符 | 5–10 条 |
控制记忆写入权限
默认情况下,Agent 可以自由写入记忆——包括后台自动触发的自我改进回顾(一轮对话结束后在后台运行,提炼记忆和技能)。
如果你希望在任何内容写入记忆前先审核,可以开启写入审批。
开启写入审批
在配置文件中设置即可:
实例
# 开启记忆写入审批——所有写入操作需要手动批准
memory:
write_approval: true # 默认 false(自由写入)
开启后的行为变化:
| 场景 | 行为 |
|---|---|
| CLI 交互中 Agent 要写记忆 | 在终端内联提示你审批 |
| 消息平台 / 后台自动回顾 | 写入被暂存,等待你手动审批 |
审批管理命令
使用以下斜杠命令管理待审批的记忆写入:
实例
/memory pending
# 批准指定 ID 的写入,或批准全部
/memory approve <id>
/memory approve all
# 拒绝指定 ID 的写入,或拒绝全部
/memory reject <id>
/memory reject all
# 运行时开启或关闭审批(设置会持久保存)
/memory approval on
/memory approval off
适用场景:如果 Agent 保存了一个关于你的错误假设,或者你想完全掌控记忆内容,开启 write_approval 是最直接的方式。
关于后台自我改进回顾
每轮对话结束后,Hermes 会在后台运行一次自我改进回顾(background review),分析这轮对话并提炼值得保留的记忆或技能。
默认会在聊天中显示一行提示 Memory updated。
你可以调整通知的详细程度:
实例
# 控制后台回顾的通知详细程度
display:
memory_notifications: on # off | on(默认)| verbose
| 值 | 效果 |
|---|---|
| off | 不显示通知,但回顾仍在运行、仍会写入 |
| on(默认) | 简短提示,如 Memory updated |
| verbose | 包含变更预览,如 Memory + 用户偏好简洁回复 |
如果你的主模型费用较高,可以让后台回顾跑在更便宜的模型上:
实例
# 后台回顾使用独立模型,降低费用
auxiliary:
background_review:
provider: openrouter
model: google/gemini-3-flash-preview # 默认 auto = 主模型
情节日志与跨会话搜索
第二层记忆——情节日志(Session History)——存储所有历史对话的完整记录,支持全文检索和按需召回。
所有对话都自动保存
每一次会话——无论来自 CLI、Telegram、Discord 还是其他任何平台——都自动存入两个位置:
| 存储位置 | 格式 | 内容 |
|---|---|---|
| ~/.hermes/state.db | SQLite 数据库 + FTS5 全文索引 | 结构化元数据、完整消息历史(含工具调用和结果)、Token 用量、时间戳 |
| ~/.hermes/sessions/ | JSONL 转录文件 | 原始对话转录,包含工具调用记录 |
session_search 工具
Agent 内置 session_search 工具,可以在所有历史对话中执行全文检索。
整个过程无需 LLM 参与搜索阶段,直接由 SQLite FTS5 引擎完成:
工作流程:
- FTS5 按相关性排序检索匹配消息
- 按会话分组,取最相关的若干会话(默认 3 个)
- 加载各会话对话,截取匹配点附近约 10 万字符
- 用轻量摘要模型生成聚焦摘要
- 返回各会话的摘要与上下文给 Agent
支持的搜索语法(FTS5 标准):
| 语法 | 示例 | 说明 |
|---|---|---|
| 关键词检索 | docker deployment | 匹配包含任一关键词的消息 |
| 短语匹配 | "exact phrase" | 精确匹配整个短语 |
| 布尔 OR | docker OR kubernetes | 匹配任一关键词 |
| 布尔 NOT | python NOT java | 排除特定关键词 |
| 前缀通配符 | deploy* | 匹配以 deploy 开头的词 |
触发时机:Agent 会在你提到「上次我们讨论过的……」或「之前那个方案……」时自动调用 session_search,而不是让你重复解释。
session_search vs 持久记忆
两者功能互补,不是替代关系:
| 对比维度 | 持久记忆(MEMORY.md / USER.md) | 情节日志(Session Search) |
|---|---|---|
| 容量 | ~1,300 tokens 总量 | 无限(所有历史对话) |
| 速度 | 即时(已在系统提示词中) | ~20ms(FTS5 查询) |
| Token 成本 | 每次会话固定消耗 | 按需,不查不花 |
| 用途 | 关键事实,始终可见 | 查找特定历史讨论 |
| 管理方式 | Agent 主动整理 | 全自动,无需干预 |
记忆用于「我总是需要知道这些的」——环境事实、用户偏好、项目规范。
情节日志用于「我们上周聊过这个问题吗?」——查找具体历史讨论。
会话管理
情节日志中的每条会话都可以被命名、恢复、导出和清理。
命名与恢复
Hermes 会在第一轮对话后自动生成一个简短的会话标题(3–7 个词),在后台异步运行,不影响响应速度。
你也可以手动命名:
实例
/title 重构认证模块
命名后恢复会话时可以直接用标题:
实例
hermes -c "重构认证模块"
# 恢复最近一次会话
hermes --continue
# 按会话 ID 恢复
hermes -r <session_id>
自动世系(Auto-Lineage):当会话经过上下文压缩时,Hermes 自动创建延续会话并编号:
"我的项目" → "我的项目 #2" → "我的项目 #3"
按标题恢复时,自动选取最新的延续会话。
常用会话管理命令
实例
hermes sessions list
# 按来源平台筛选
hermes sessions list --source telegram
# 显示更多条
hermes sessions list --limit 50
# 重命名指定会话
hermes sessions rename <id> "新标题"
# 导出所有会话到文件
hermes sessions export backup.jsonl
# 删除指定会话
hermes sessions delete <id>
# 清理 30 天前的旧会话
hermes sessions prune --older-than 30
# 查看统计信息
hermes sessions stats
hermes sessions list 的输出示例:
标题 预览 最近活跃 ID ──────────────────────────────────────────────────────────────────── 重构认证模块 帮我重构认证模块的代码 2 小时前 20260305_09... 我的项目 #3 检查一下测试失败的原因 昨天 20260304_14... — Python 装饰器怎么用 3 天前 20260303_10...
会话自动清理(可选)
默认情况下会话历史永久保留(因为它为 session_search 提供数据)。
如果需要自动清理,在配置中开启:
实例
# 开启会话自动清理(默认关闭)
sessions:
auto_prune: true # 默认 false
retention_days: 90 # 保留最近 90 天
vacuum_after_prune: true
min_interval_hours: 24
Honcho 用户建模
Honcho 是由 Plastic Labs 开发的 AI 原生记忆后端,以插件形式集成到 Hermes 中。
它不替换 MEMORY.md 和 USER.md,而是在它们之上增加辩证推理层——通过分析你的对话模式,自动推导你未曾明确表达的偏好、目标和习惯。
与 MEMORY.md 的手动策划方式不同,Honcho 是全自动的:它在每轮对话后(频率可配置)在后台推理,积累对你越来越深的理解。
Honcho 与内置记忆的对比
| 能力 | 内置记忆 | Honcho |
|---|---|---|
| 跨会话持久化 | 本地文件 | 服务端 API |
| 用户画像 | 手动策划(USER.md) | 自动辩证推理 |
| 会话摘要 | — | 会话级上下文注入 |
| 多 Agent 隔离 | — | 按 Agent 分开建模 |
| 语义搜索 | FTS5 全文 | 基于推理结论 |
两层上下文注入
每一轮对话,Honcho 组装两层上下文注入系统提示词:
基础层(Base Context):会话摘要 + 用户表征 + 用户 Peer Card + AI 自我表征。按 contextCadence(每 N 轮)刷新一次。这是「这个用户是谁」层。
辩证层(Dialectic Supplement):由 Honcho 的 LLM 引擎实时推理生成,关注「当前最相关的是什么」。按 dialecticCadence 刷新。
辩证推理的两种启动模式:
| 模式 | 条件 | 查询方式 |
|---|---|---|
| 冷启动 | 无历史数据 | 通用查询——「这个用户是谁?他们的偏好、目标和工作方式是什么?」 |
| 热启动 | 已有历史数据 | 会话聚焦查询——「基于本次会话已讨论的内容,关于这个用户最相关的上下文是什么?」 |
三个独立调节旋钮
| 参数 | 控制的内容 | 默认值 |
|---|---|---|
| contextCadence | 基础层刷新间隔(每 N 轮调用一次 API) | 1 |
| dialecticCadence | 辩证层刷新间隔(每 N 轮调用一次 LLM) | 2(推荐 1–5) |
| dialecticDepth | 每次辩证的推理深度(1–3 次 pass) | 1 |
三个旋钮完全独立——你可以高频刷新基础层、低频运行辩证推理,也可以反过来:
实例
"contextCadence": 1,
"dialecticCadence": 5,
"dialecticDepth": 2
}
以上配置表示:每轮刷新基础层,每 5 轮做一次 2 pass 深度辩证推理。
多 pass 辩证推理
当 dialecticDepth 设为大于 1 时,每次辩证推理运行多轮 LLM 调用:
| Pass | 任务 | 说明 |
|---|---|---|
| Pass 0 | 冷/热启动推理 | 建立初始评估 |
| Pass 1 | 自我审计 | 识别初始评估的盲点,综合近期会话证据 |
| Pass 2 | 调和 | 检查前两轮的矛盾,产出最终综合结论 |
深度 3 不一定等于 3 次 LLM 调用——如果上一轮已产出高质量输出,下一轮会提前退出,节省 Token。
快速上手 Honcho
实例
hermes memory setup
或手动配置:
实例
# 启用 Honcho 作为记忆提供者
memory:
provider: honcho
实例
echo 'HONCHO_API_KEY=your_key' >> ~/.hermes/.env
在 honcho.dev 获取 API Key。
Honcho 提供的工具
开启 Honcho 后,Agent 可以使用五个专属工具:
| 工具 | 用途 |
|---|---|
| honcho_profile | 读取或更新用户 Peer Card |
| honcho_search | 基于推理结论的语义搜索(原始片段,无 LLM 综合) |
| honcho_context | 获取完整会话上下文(摘要、用户表征、近期消息) |
| honcho_reasoning | 调用 Honcho LLM 推理(可指定 reasoning_level) |
| honcho_conclude | 创建或删除推理结论 |
Honcho CLI 命令
实例
hermes honcho status
# 查看或设置会话策略
hermes honcho strategy
# 查看或设置召回模式(hybrid/context/tools)
hermes honcho mode
# 查看或设置 Token 预算
hermes honcho tokens
# 列出已知的 Honcho 会话映射
hermes honcho sessions
记忆系统配置参考
以下是所有记忆相关配置的完整参考,可直接复制到你的配置文件中使用。
实例
# 文件路径:~/.hermes/config.yaml
# Hermes 记忆系统完整配置参考
# ============================================
# --- 持久记忆配置 ---
memory:
memory_enabled: true # 是否启用持久记忆(MEMORY.md)
user_profile_enabled: true # 是否启用用户画像(USER.md)
memory_char_limit: 2200 # MEMORY.md 字符上限(约 800 tokens)
user_char_limit: 1375 # USER.md 字符上限(约 500 tokens)
write_approval: false # true = 所有记忆写入需要手动审批
provider: honcho # 可选:启用 Honcho 记忆提供者
# --- 会话自动清理(可选,默认关闭)---
sessions:
auto_prune: false # 是否自动清理旧会话
retention_days: 90 # 保留最近 N 天的会话
vacuum_after_prune: true # 清理后是否回收磁盘空间
min_interval_hours: 24 # 两次清理之间的最小间隔
# --- 后台回顾通知 ---
display:
memory_notifications: on # off | on | verbose
# --- 后台回顾使用更便宜的模型(可选)---
auxiliary:
background_review:
provider: openrouter # 模型提供者
model: google/gemini-3-flash-preview # 模型名称
常用记忆操作速查
在对话中直接操控记忆
你可以用自然语言指令 Hermes 操作记忆,无需记忆任何命令:
实例
记住:我们这个项目用 Poetry 管理依赖,不用 pip
# 删除或覆盖记忆
忘记之前关于 MySQL 的记录,我们已经迁移到 PostgreSQL 了
# 更新记忆中的信息
把 staging 服务器的 IP 更新为 10.0.2.100
# 查询记忆
告诉我你现在记住了哪些关于我的信息
斜杠命令
实例
/memory
# 查看待审批写入
/memory pending
# 批准所有待审批
/memory approve all
# 拒绝所有待审批
/memory reject all
# 开启写入审批
/memory approval on
# 关闭写入审批
/memory approval off
直接编辑记忆文件
记忆文件是普通的 Markdown,可以直接用编辑器打开修改:
实例
cat ~/.hermes/memories/MEMORY.md
cat ~/.hermes/memories/USER.md
# 用编辑器打开修改
nano ~/.hermes/memories/MEMORY.md
注意:直接编辑文件后,变化会在下次会话启动时生效,不会立即体现在当前会话的上下文中。
记忆安全与隐私
安全扫描
记忆内容在写入前会经过安全扫描,检测注入攻击和数据窃取模式。
系统会检测以下威胁模式:
| 威胁类型 | 检测内容 |
|---|---|
| 提示词注入 | 试图覆盖 Agent 系统指令的注入模式 |
| 凭据窃取 | 诱导 Agent 泄露 API Key 或 Token 的指令 |
| 后门安装 | SSH 后门或远程访问的安装指令 |
| 隐藏字符 | 不可见 Unicode 字符(零宽空格、方向覆盖等) |
匹配到威胁模式的内容会被拒绝写入。
日志中的敏感信息脱敏
API Key、Token 等敏感信息在所有日志文件中自动脱敏——即使出现在工具输出里也不会以明文形式记录:
实例
# 默认开启,敏感信息自动脱敏
security:
redact_secrets: true
数据本地存储
所有记忆数据(MEMORY.md、USER.md、state.db)默认存储在本地 ~/.hermes/ 目录,不上传到云端。
选择使用 Honcho 时,对话数据会发送到 Honcho 的服务器进行处理——这是一个有意的权衡:用数据上传来换取更深的推理能力。
