ByteNoteByteNote

字节笔记本

2026年6月21日

hermes教程-检查点与 /rollback

API中转
¥120

检查点与 /rollback

Hermes Agent 可以在破坏性操作前自动为你的项目创建快照,并通过一条命令恢复。检查点在 v2 版本中为可选启用——大多数用户从不使用 /rollback,且影子存储会随时间增长,因此默认关闭。

通过 --checkpoints 在每个会话中启用:

bash
hermes chat --checkpoints

或在 ~/.hermes/config.yaml 中全局启用:

yaml
checkpoints:
  enabled: true

这一安全网由内部的检查点管理器驱动,它在 ~/.hermes/checkpoints/store/ 下维护一个共享的影子 git 仓库——你的真实项目 .git 永远不会被触及。Agent 处理的每个项目共享同一个存储,因此 git 的内容可寻址对象数据库会在项目间和轮次间进行去重。

触发检查点的条件

检查点会在以下操作前自动创建:

  • 文件工具write_filepatch
  • 破坏性终端命令rmrmdircpinstallmvsed -itruncateddshred、输出重定向(>)以及 git reset/clean/checkout

Agent 在每个目录每轮对话中最多创建一个检查点,因此长时间运行的会话不会产生大量快照。

快速参考

会话内斜杠命令:

命令描述
/rollback列出所有检查点及变更统计
/rollback <N>恢复到检查点 N(同时撤销上一轮对话)
/rollback diff <N>预览检查点 N 与当前状态之间的差异
/rollback <N> <file>从检查点 N 恢复单个文件

用于在会话外检查和管理存储的 CLI:

命令描述
hermes checkpoints显示总大小、项目数量、各项目详情
hermes checkpoints status与裸 checkpoints 相同
hermes checkpoints liststatus 的别名
hermes checkpoints prune强制清理:删除孤立/过期项、GC、执行大小限制
hermes checkpoints clear清空整个检查点基础(需确认)
hermes checkpoints clear-legacy仅删除 v1 迁移产生的 legacy-* 归档

检查点的工作原理

从高层来看:

  • Hermes 检测工具何时即将修改工作树中的文件。
  • 每轮对话(每个目录)中,它会:
    • 解析文件的合理项目根目录。
    • 初始化或重用 ~/.hermes/checkpoints/store/ 下的单个共享影子存储
    • 暂存到每个项目的索引,构建树,并提交到每个项目的引用(refs/hermes/<project-hash>)。
  • 这些每个项目的引用构成了检查点历史,你可以通过 /rollback 查看和恢复。
mermaid
flowchart LR
  user["用户命令\n(hermes, gateway)"]
  agent["AIAgent\n(run_agent.py)"]
  tools["文件与终端工具"]
  cpMgr["CheckpointManager"]
  store["共享影子存储\n~/.hermes/checkpoints/store/"]

  user --> agent
  agent -->|"工具调用"| tools
  tools -->|"变更前\nensure_checkpoint()"| cpMgr
  cpMgr -->|"git add/commit-tree/update-ref"| store
  cpMgr -->|"OK / 跳过"| tools
  tools -->|"应用变更"| agent

配置

~/.hermes/config.yaml 中配置:

yaml
checkpoints:
  enabled: false              # 主开关(默认:false — 可选启用)
  max_snapshots: 20           # 每个项目最大检查点数(通过引用重写 + gc 强制执行)
  max_total_size_mb: 500      # 存储总大小硬上限;丢弃最旧的提交
  max_file_size_mb: 10        # 跳过任何大于此值的单个文件
## 自动维护(默认开启):启动时清理 ~/.hermes/checkpoints/
## 并删除工作目录不再存在的项目条目(孤立项目)
## 或 last_touch 早于 retention_days 的项目。运行频率不超过
## min_interval_hours,通过 .last_prune 标记跟踪。
  auto_prune: true
  retention_days: 7
  delete_orphans: true
  min_interval_hours: 24

要完全禁用:

yaml
checkpoints:
  enabled: false
  auto_prune: false

enabled: false 时,检查点管理器为空操作,从不尝试 git 操作。当 auto_prune: false 时,存储会持续增长,直到你手动运行 hermes checkpoints prune

列出检查点

在 CLI 会话中:

/rollback

Hermes 会返回一个格式化列表,显示变更统计:

text
📸 项目 /path/to/project 的检查点:

  1. 4270a8c  2026-03-16 04:36  在 patch 之前  (1 个文件, +1/-0)
  2. eaf4c1f  2026-03-16 04:35  在 write_file 之前
  3. b3f9d2e  2026-03-16 04:34  在终端命令之前: sed -i s/old/new/ config.py  (1 个文件, +1/-1)

  /rollback <N>             恢复到检查点 N
  /rollback diff <N>        预览自检查点 N 以来的变更
  /rollback <N> <file>      从检查点 N 恢复单个文件

从 Shell 检查存储

bash
hermes checkpoints

示例输出:

text
检查点基础目录: /home/you/.hermes/checkpoints
总大小:      142.3 MB
  store/         138.1 MB
  legacy-*       4.2 MB
项目数:        12

  WORKDIR                                                       COMMITS    LAST TOUCH  STATE
  /home/you/code/hermes-agent                                        20       2h ago  live
  /home/you/code/experiments/rl-runner                                8       1d ago  live
  /home/you/code/old-prototype                                        3       9d ago  orphan
  ...

遗留归档 (1):
  legacy-20260506-050616                           4.2 MB

清除命令: hermes checkpoints clear-legacy

强制完全清理(忽略 24 小时幂等标记):

bash
hermes checkpoints prune --retention-days 3 --max-size-mb 200

使用 /rollback diff 预览变更

在决定恢复之前,预览自某个检查点以来的变更:

/rollback diff 1

这会显示 git diff 统计摘要,随后是实际差异。

使用 /rollback 恢复

/rollback 1

在后台,Hermes 会:

  1. 验证目标提交是否存在于影子存储中。
  2. 对当前状态创建一个恢复前快照,以便稍后“撤销撤销”。
  3. 恢复工作目录中的跟踪文件。
  4. 撤销上一轮对话,使 Agent 的上下文与恢复后的文件系统状态一致。

单文件恢复

从检查点恢复单个文件,不影响目录其余部分:

/rollback 1 src/broken_file.py

安全与性能保护

  • Git 可用性 — 如果在 PATH 中找不到 git,检查点会被透明禁用。
  • 目录范围 — Hermes 会跳过过于宽泛的目录(根目录 /、家目录 $HOME)。
  • 仓库大小 — 文件超过 50,000 个的目录会被跳过。
  • 单文件大小上限 — 大于 max_file_size_mb(默认 10 MB)的文件会被排除在快照之外。防止意外吞入数据集、模型权重或生成的媒体文件。
  • 存储总大小上限 — 当存储超过 max_total_size_mb(默认 500 MB)时,每个项目中最旧的提交会被轮换丢弃,直到低于上限。
  • 真正清理max_snapshots 通过重写每个项目的引用并随后运行 git gc --prune=now 来强制执行,因此松散对象不会累积。
  • 无变更快照 — 如果自上次快照以来没有变更,则跳过检查点。
  • 非致命错误 — 检查点管理器内的所有错误均以调试级别记录;你的工具会继续运行。

检查点的存储位置

text
~/.hermes/checkpoints/
  ├── store/                 # 单个共享裸 git 仓库
  │   ├── HEAD, objects/     # git 内部结构(跨项目共享)
  │   ├── refs/hermes/<hash> # 每个项目的分支指针
  │   ├── indexes/<hash>     # 每个项目的 git 索引
  │   ├── projects/<hash>.json  # 工作目录 + created_at + last_touch
  │   └── info/exclude
  ├── .last_prune            # 自动清理幂等标记
  └── legacy-<ts>/           # 归档的 v2 前每个项目影子仓库

每个 <hash> 由工作目录的绝对路径派生而来。通常你不需要手动触碰这些——请使用 hermes checkpoints status / prune / clear 代替。

从 v1 迁移

在 v2 重写之前,每个工作目录在 ~/.hermes/checkpoints/<hash>/ 下拥有自己完整的影子 git 仓库。这种布局无法跨项目去重对象,并且有一个已知的空操作清理器——存储会无限制增长。

首次运行 v2 时,所有 v2 前的影子仓库会被移动到 ~/.hermes/checkpoints/legacy-<timestamp>/,以便新的单一存储布局从干净状态开始。旧的 /rollback 历史仍然可以通过手动使用 git 检查遗留归档来访问;一旦你确认不再需要它,运行:

bash
hermes checkpoints clear-legacy

以回收空间。遗留归档也会在 retention_days 后被 auto_prune 清理。

最佳实践

  • 仅在需要时启用检查点hermes chat --checkpoints 或按配置文件设置 enabled: true
  • 在恢复前使用 /rollback diff — 预览将要变更的内容,以选择正确的检查点。
  • 在只想撤销 Agent 驱动的变更时,使用 /rollback 而不是 git reset
  • 如果定期使用检查点,偶尔检查 hermes checkpoints status — 显示哪些项目处于活动状态以及存储的成本。
  • 结合 Git 工作树以获得最大安全性 — 将每个 Hermes 会话放在自己的工作树/分支中,并将检查点作为额外一层保护。

关于在同一仓库中并行运行多个 Agent 的指南,请参阅 Git 工作树


分享: