Last updated on

Hermes Agent 数据库「瘦身」:v23 FTS 布局让 state.db 最高缩小 78%


如果你已经用了一段时间 Hermes Agent,大概会发现 ~/.hermes/hermes.db 越来越大。agent 需要把每条消息、每个工具结果、每次思考过程存下来,才能在跨会话中保持上下文。但这笔存储开销原本比实际需要的更大——问题不在聊天记录本身,而在于搜索索引的存储方式。

最近 Nous Research 合并了 PR #65798,引入了紧凑 v23 FTS 布局。在重载安装上,它能把 state.db 体积砍掉约 75%;在工具输出较多的场景里,最高可达 78%。真正的聊天记录、记忆和会话数据 untouched,只是搜索索引变得更小、更聪明。

本文会解释是什么在让数据库膨胀、v23 布局如何修复它,以及你要怎么做才能用上这次优化。

想了解更宏观的 v0.19.0 更新,请看我们的 v0.19.0 发布说明


为什么数据库增长这么快

Hermes 把长期状态保存在 ~/.hermes/hermes.db 这个 SQLite 数据库里。每条消息存在 messages 表中,并通过两个 FTS5 全文索引被检索:

  • messages_fts:Porter 词干索引,适合英语类搜索
  • messages_fts_trigram:trigram 索引,用于 CJK 子串搜索

从 v11 模式迁移以来,这两个索引都是内联 FTS5 表。也就是说,每个索引都各自保存了一份 content || tool_name || tool_calls 的完整副本。同一份内容在数据库里被存了三次:一次在 messages 表,另外两次在 FTS 索引里。

issue #22478 给了一个真实案例,展示问题有多严重:

组件 大小 占比
messages 数据 99 MB 19.6%
sessions 数据 45 MB 8.9%
FTS 索引 358 MB 70.8%
其他 3 MB 0.7%
总计 505 MB 100%

trigram 索引 alone 占 247 MB,也就是整个数据库的 49%。原因在于:CJK 文本生成的 trigram 远多于英文,而且 role='tool' 的工具行也被索引了。工具行通常是 base64 载荷、文件转储和子代理转录,没人会用 CJK 子串去搜它们。

这不仅是磁盘问题。庞大的内联索引会拖慢写入、延长锁持有时间,甚至在重负载网关会话里把磁盘 I/O 打满。


v23 布局改了什么

紧凑 v23 FTS 布局做了三件事:

  1. external-content 索引:FTS5 索引不再存自己的私有副本,而是直接指向 messages 表的真正列,消除了 2–3 倍的数据重复。

  2. 工具行不再进入 trigram 索引:trigram 索引跳过 role='tool' 的行。这里本来是膨胀重灾区,因为 busy agent 的工具行通常占消息字节的 ~90%。

  3. 可选迁移:现有安装保持原有旧版索引,功能不变。只有你主动运行 hermes sessions optimize-storage 时,才会切换到 v23 布局。

messages 表保持字节级一致。聊天记录、记忆、会话数据 untouched。只有搜索索引的存储方式改变。


数据:最高可缩小 78%

PR #65798 同时给出了合成数据和真实数据验证:

场景 优化前 优化后
合成 30k 消息库,60% 工具行 463 MB 131 MB(28%)
该库中 FTS 占比 ~84% ~42%
真实 25 GB / 138 万消息副本 25 GB ~10 GB

合成数据库从 463 MB 降到 131 MB,缩减 72%。真实生产副本从 25 GB 降到约 10 GB,缩减 60%,索引计数完全匹配,FTS5 完整性检查通过。在工具行占主导的工作负载中,最高可达 78%,因为 trigram 索引直接不再为工具行分配空间。


如何手动启用

新安装会自动使用 v23 布局。如果你已经在用 Hermes,只需一条命令:

hermes sessions optimize-storage

这条命令执行的是一个明确的前景操作:

  • 启动前检查磁盘空间,不够就拒绝并提示。
  • 以 O(1) 时间降级旧版索引。
  • 分 500 行一个 chunk 回填新索引,写锁占空比控制在 20% 以内,避免影响并行的网关或 CLI 会话。
  • 分块清理旧 shadow 表。
  • 运行 VACUUM 回收空间。
  • 打上新版布局版本标记。

支持 Ctrl-C 中断,且可断点续传。如果中断,下次运行会检测标记和残留表,从断点继续。重建期间如果搜索结果不完整,agent 会主动提示你,不会默默幻觉缺失上下文。

如果你磁盘空间紧张,可以跳过 vacuum:

hermes sessions optimize-storage --no-vacuum

升级后,hermes update 会弹出一行提示,告知预期空间收益和是否有可恢复的中断任务。


什么时候该运行它

如果你符合以下任一情况,建议运行 hermes sessions optimize-storage

  • ~/.hermes/hermes.db 已经超过几百 MB,且大部分是 FTS 索引。
  • 你运行工具密集型网关会话,遇到磁盘 I/O 尖刺或写入变慢。
  • 你在小 VPS 或笔记本上,磁盘空间紧张。
  • 刚安装 Hermes,想确认自己已经在 v23 布局上。

如果目前性能和空间都够用,也可以等。旧版索引会继续工作,这不是破坏性变更。


搜索质量会受影响吗

不会。你真正会搜索的内容都还在索引里。对话内容和 tool_calls/tool_name 仍可通过 external-content 索引搜索。CJK 对话子串搜索也仍然有效。唯一的区别是:CJK 子串搜索不再覆盖工具输出,而是回退到 LIKE 查询——这几乎没有影响,因为没人会用 CJK 子串去搜 base64 或文件转储。

独立评审者 @yoniebans 在真实 v19→v23 迁移上验证:messages 表的 SHA-256 指纹迁移前后一致,索引计数完全匹配。


实操步骤

  1. 查看当前数据库大小:
ls -lh ~/.hermes/hermes.db
  1. 升级到包含 v23 模式的最新版本:
hermes update
  1. 运行优化:
hermes sessions optimize-storage
  1. 完成后再次检查大小:
ls -lh ~/.hermes/hermes.db
  1. 如果你想进一步释放旧会话空间,可以在优化后配合 hermes sessions prunehermes memory clean 使用——但请先备份重要数据。

关键要点

  • Hermes Agent 的 state.db 原本被 FTS5 索引的重复副本撑大,尤其是索引工具行的 trigram 索引。
  • 紧凑 v23 FTS 布局 采用 external-content 索引,并停止对工具行做 trigram 索引,可缩减数据库 60%–78%(视工作负载而定)。
  • 新安装 默认启用 v23。老用户 通过 hermes sessions optimize-storage 手动迁移。
  • 迁移可断点续传、Ctrl-C 安全,且聊天记录字节级一致。
  • 搜索质量不受影响,只有工具输出内部的 CJK 子串搜索回退到 LIKE

参考链接: