检查点与 /rollback
Hermes Agent 可以在破坏性操作之前自动为你的项目创建快照,并通过一条命令恢复。从 v2 开始,检查点为可选功能——大多数用户从不使用 /rollback,且影子存储(shadow-store)随时间推移会占用可观的空间,因此默认关闭。
通过 --checkpoints 为每个会话启用检查点:
hermes chat --checkpoints或者在 ~/.hermes/config.yaml 中全局启用:
checkpoints:
enabled: true这一安全网由内部的检查点管理器(Checkpoint Manager)驱动,它在 ~/.hermes/checkpoints/store/ 下维护一个共享的影子 Git 仓库——你的真实项目 .git 绝不会被触及。Agent 所操作的所有项目共享同一个存储仓库,因此 Git 的内容可寻址对象数据库(content-addressable object DB)可以在不同项目和不同对话轮次间进行去重。
什么会触发检查点
检查点会在以下操作之前自动创建:
- 文件工具——
write_file和patch - 破坏性终端命令——
rm、rmdir、cp、install、mv、sed -i、truncate、dd、shred、输出重定向(>),以及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 list | status 的别名 |
hermes checkpoints prune | 强制清理:删除孤立/过期条目、GC、执行大小限制 |
hermes checkpoints clear | 清空整个检查点存储(需确认) |
hermes checkpoints clear-legacy | 仅删除 v1 迁移产生的 legacy-* 归档 |
检查点的工作原理
从高层看:
- Hermes 检测到工具即将修改工作目录中的文件。
- 每轮对话(每个目录)一次,它会:
- 解析出文件对应的合理项目根目录。
- 在
~/.hermes/checkpoints/store/初始化或复用单个共享的影子存储。 - 将变更暂存到项目索引、构建树对象、并提交到项目引用(
refs/hermes/<project-hash>)。
- 这些项目引用构成了一个检查点历史,你可以通过
/rollback查看和恢复。
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 -->|"成功 / 已跳过"| tools
tools -->|"应用变更"| agent
配置
在 ~/.hermes/config.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 的条目。通过 .last_prune 标记
# 确保每个 min_interval_hours 最多执行一次。
auto_prune: true
retention_days: 7
delete_orphans: true
min_interval_hours: 24完全禁用:
checkpoints:
enabled: false
auto_prune: false当 enabled: false 时,检查点管理器为空操作,从不尝试 Git 操作。当 auto_prune: false 时,存储会持续增长,直到你手动运行 hermes checkpoints prune。
列出检查点
在 CLI 会话中:
/rollback
Hermes 会返回一个格式化的列表,显示变更统计信息:
📸 /path/to/project 的检查点:
1. 4270a8c 2026-03-16 04:36 patch 前 (1 file, +1/-0)
2. eaf4c1f 2026-03-16 04:35 write_file 前
3. b3f9d2e 2026-03-16 04:34 terminal: sed -i s/old/new/ config.py 前 (1 file, +1/-1)
/rollback <N> 恢复到检查点 N
/rollback diff <N> 预览自检查点 N 以来的变更
/rollback <N> <file> 从检查点 N 恢复单个文件从 Shell 检查存储
hermes checkpoints示例输出:
检查点存储位置:/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 小时幂等性标记):
hermes checkpoints prune --retention-days 3 --max-size-mb 200使用 /rollback diff 预览变更
在恢复之前,预览自某个检查点以来的变更:
/rollback diff 1
这会显示 git diff stat 摘要,随后是实际的差异内容。
使用 /rollback 进行恢复
/rollback 1
在底层,Hermes 会:
- 确认目标提交存在于影子存储中。
- 创建当前状态的回滚前快照,以便之后可以”撤销撤销”。
- 恢复工作目录中的跟踪文件。
- 撤销最后一轮对话,使 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)时,会按轮次丢弃每个项目的最早提交,直到低于上限。 - 真正清理——通过重写项目引用并随后运行
git gc --prune=now来强制执行max_snapshots,防止松散对象累积。 - 无变更快照——如果自上次快照以来没有变更,则跳过检查点。
- 非致命错误——检查点管理器内部的所有错误仅记录在 debug 级别;你的工具仍会继续运行。
检查点的存储位置
~/.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 手动检查遗留归档来访问;当你确信不再需要时,运行:
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 工作树 指南。