我手里有一个用了几天的仓库动态助手。它会读取 NVIDIA/NemoClaw 公开仓库里的 Issue 和 PR,再按固定格式整理成日报。经过几轮调整,它已经保存了一份专门的 Skill,也留下了一些会话和运行状态。

后来我准备维护运行环境,首先想到的就是这些内容怎么处理。重新创建一个空沙箱并不麻烦,但我不想重新教一遍日报格式,也不希望之前的会话和记忆就此丢失。

这次我用 NemoClaw 做了一次完整迁移:从源沙箱 repo-watch 创建快照,再恢复出一个名为 repo-watch-copy 的新沙箱。恢复后,我在新 Dashboard 里建立空白会话,换了一批仓库数据,只输入“照以前的格式整理”。新沙箱仍然调用了 daily-nemoclaw-digest Skill,输出格式与迁移前一致,Skill 文件的校验值和会话记录也都能对应上。完成这些检查后,我才停掉源沙箱。

本文参加 NVIDIA AI 智能体加速精讲堂活动,体验产品为 NVIDIA NemoClaw

NemoClaw 迁移结果

迁移之前

这个助手的任务很简单:定期读取 NVIDIA/NemoClaw 公开仓库里的更新,从中选出需要关注的内容。第一次生成的日报比较散,我后来把格式固定为五条,每条包含编号、标题、状态、URL 和一句“为什么重要”,最后再加一段 Bottom line。Hermes 根据这次修改生成了 daily-nemoclaw-digest Skill。

Hermes Dashboard 中生成的 NemoClaw 仓库日报

为了直接在浏览器里对话,我在创建沙箱前设置了 NEMOCLAW_HERMES_DASHBOARD_TUI=1。Hermes 的 Chat 页实际是把 TUI 嵌进 Dashboard,右侧保留模型和会话列表;上图就是我平时检查日报的入口。

这个任务还有一个好处:输入都是 GitHub 上的公开数据,不需要接 Slack、邮箱或内部工单。我也没有给助手仓库写权限,它只负责读取和整理。这样做迁移检查时,变量比较少。日报没出来,可以先查 Agent 状态和模型连接,不用先排查第三方系统的授权是否过期。

我用日报来检查迁移效果,主要是因为结果好核对。操作前可以记录 Skill 文件的哈希、会话列表和数据库状态;恢复后再换一批输入,看新沙箱是否继续使用原来的格式。单独问一句“你还记得我吗”说明不了多少问题,文件和实际输出更可靠。

我也没有在开始时就停掉源端。副本没有检查完之前,repo-watch 照常运行。迁移测试一旦出问题,日报还能从旧入口继续做,不会因为一次测试把正在用的助手也停掉。

这个过程涉及三个组件。Hermes 是 Agent runtime,负责对话、工具、Skills、记忆和会话,日报格式的保存和调用发生在这一层。OpenShell 提供沙箱、策略、凭据代理和推理代理。NemoClaw 运行在主机侧,负责接入 runtime,并管理版本、Shields、推理路由、快照、恢复和重建。本文关注的是 NemoClaw 如何处理一个已经有状态的 Agent。

测试使用 NemoClaw v0.0.95,对应 Hermes 0.18.0。开始迁移前,我保存了四项信息:status --json 返回的沙箱和路由状态、sessions 列表、日报 Skill 的 SHA-256,以及 Dashboard 中的一次实际输出。迁移完成后,再按这四项逐一对照。

迁移前四项基线的对照方式

做快照之前,我先执行了一次 stop 和 start。停止后,状态查询返回 sandbox_container_stopped;重新启动后,NemoClaw 拉起沙箱,同时恢复 Hermes Gateway 和主机转发。再次打开页面,Skill 和会话还在,recordedRoute 与共享 liveRoute 也没有出现漂移。确认普通停启不会丢状态后,我再继续做迁移。

快照里有什么

NemoClaw 不会直接打包整个容器,而是根据 Agent manifest 备份需要长期保存的目录和文件。对 Hermes 来说,快照主要包括 .hermes 下的 skillsmemoriessessions、workspace 和 profiles,以及 SOUL.md.hermes_historyruntime/state.db、默认的 kanban.db 等文件。SQLite 数据库使用在线备份,避免直接复制正在写入的数据库文件。

NemoClaw 创建快照时的状态选择与数据库备份

daily-nemoclaw-digest/SKILL.md 位于这些持久化目录中。我分别在迁移前后计算它的 SHA-256,两个值一致,说明 Skill 文件没有变化。会话和记忆不能只看文件数量,还要通过 CLI 查询和新会话继续检查。

SKILL.md 本身就是一份可以直接打开查看的 Markdown 文件,里面写着触发条件、处理步骤和输出要求。检查哈希之前,我先确认了这确实是自己改过的那一份,而不是同名空文件。以后如果哈希对不上,也可以直接做文本对比,看看究竟是字段顺序变了,还是整份 Skill 没有恢复。

manifest 也明确了快照不包含哪些内容。外部目录、worktree、附件和临时 workspace 不会自动备份,非默认的看板数据也要单独处理。业务原始数据仍应使用自己的存储和备份方案,NemoClaw 的快照主要保存 Agent 需要延续的运行状态。

恢复时,NemoClaw 会按照目标端的 manifest 校验 Agent 类型、配置目录、状态文件路径和备份策略。如果两端配置不兼容,恢复会直接失败。清理和覆盖的范围也只限于 manifest 声明的状态目录。通过 policy-add --from-file--from-dir 添加的自定义策略,会连同校验后的 YAML 内容和注册信息一起保存,重建时可以重新应用。

创建快照前,需要临时关闭源沙箱的 Shields。我把超时时间设为十分钟,并将操作原因填写为 clone validationsnapshot create --name before-clone 完成后,我马上重新开启 Shields,避免源沙箱长时间处于可修改状态。快照名称使用 before-clone,以后查看列表时也能直接知道它对应迁移前的状态。

哪些不会搬走

执行 snapshot restore before-clone --to repo-watch-copy 后,NemoClaw 会使用源沙箱当前的镜像创建一个新沙箱,再恢复 manifest 中定义的状态。源沙箱 repo-watch 保持不变,新沙箱使用独立名称 repo-watch-copy,并获得自己的本地 Dashboard 端口。

使用 --to 后,可以在不影响源端的情况下检查副本。目标端如果有问题,旧 Agent 仍然可以继续运行。主机维护、灾备测试以及版本升级前,都可以先按这种方式准备一个副本。

快照、NemoClaw 与 Host 的状态边界

快照不会包含所有运行配置。auth.json、NemoClaw 生成的 config.yaml.env 会被排除,模型 Provider 的原始 API Key 仍由主机和 OpenShell 的凭据代理管理。Gateway 当前使用的 liveRoute 也不会写入 Agent 快照。

目标沙箱恢复时,NemoClaw 会根据当前环境重新生成配置,按源端的 recordedRoute 为目标登记路由,并检查它与 Gateway 共享 liveRoute 是否兼容。Skill、会话和记忆会从快照中恢复,目标沙箱再通过当前环境连接模型服务。

同一个 OpenShell Gateway 管理的所有沙箱共享一条 liveRoute。NemoClaw 还会为每个沙箱记录预期路由,并在 status --json 中显示 recordedRouteliveRouterouteDrift。同一 Gateway 下已经停止的沙箱,也会参与 Provider 或模型变更时的冲突检查。这次迁移没有给副本更换模型,只检查两个路由字段是否一致,避免模型变化影响前后对比。

如果快照包含 Hermes 的 state DB,恢复后需要重启目标 Gateway,避免它继续使用恢复前的数据库连接。我执行 gateway restart 后,再查询会话并生成一次日报。Shields 的开关状态不在快照中,所以目标沙箱也要单独查询并执行 shields up

创建快照和恢复副本时使用的主要命令如下:

NemoClaw 创建快照并恢复到新沙箱

restore --to 复用源沙箱当前的镜像,适合克隆和灾备;涉及版本升级时,可以使用 rebuild。它会自动备份状态、重新创建沙箱、恢复配置和 manifest 状态,再应用策略并检查 Hermes 是否正常。这次我先完成副本迁移,再在副本上测试升级,两类问题可以分开排查。

检查新沙箱

目标沙箱显示 Ready 后,我又检查了文件、运行状态和凭据。

先看沙箱身份和文件。repo-watch-copy 应当是一个独立沙箱,Hermes 版本仍为 0.18.0,日报 Skill 的 SHA-256 与源端一致。Dashboard 地址通过命令读取实际分配的端口,没有写死在脚本里。源端和目标端页面可以同时打开,也能避免浏览器误连到旧地址。

我把两个 Dashboard 地址分别复制到不同的浏览器窗口。先在副本里新建空白会话,再关掉源端页面,刷新副本后重新输入任务。测试数据也换成快照创建之后更新的一批 Issue 和 PR。这样看到的答案来自新沙箱,不会把旧页面、旧会话里的内容算到迁移结果里。

源端与副本的 Skill 校验及 Dashboard 连通性

接着检查运行状态。重启 Gateway 后,CLI 可以列出迁移前的会话;status --json 中的 recordedRoute 与共享 liveRoute 一致,没有 route drift。

NemoClaw 显示的 Inference: reachable 主要检查路由是否可以访问。HTTP 401 或 403 在某些情况下也可能被判断为 reachable,因此还需要发起一次实际推理。我在新 Dashboard 中创建空白会话,换了一批同类型的数据,只输入“照以前的格式整理”。它调用了恢复后的 Skill,仍然按五条、相同字段顺序和相同结尾生成日报。

这里我没有把字段名称再提示一遍,也没有把迁移前的日报贴给它照着改。如果还得重新说明“五条、URL、为什么重要、Bottom line”,就不能算原来的 Skill 已经接上了。最后生成的内容用了新数据,格式则保留了下来。

最后检查凭据和策略。Skill、会话和数据库都能在恢复后的状态中找到,但模型 Provider 的原始 Key 不在快照文件中;副本仍然通过 Gateway 的共享路由访问模型。随后,我开启目标端 Shields,再检查策略状态。

Provider Key 不在快照中,并不代表快照可以公开。会话、Dashboard profile 和消息平台的 pairing state 都可能包含业务数据、登录信息或配对凭据,快照仍然需要按私有数据保管。

迁移后的七项检查结果

这些检查需要结合起来看。文件一致,只能证明内容已经复制,不能证明目标端可以正常运行;status 正常,也不能证明 Skill 和会话已经被 Hermes 加载。为了避免误用旧页面,我核对了新沙箱名称和 Dashboard 地址;为了避免复用旧答案,我又换了一批仓库数据重新生成日报。结果保留了原来的五条格式,具体内容则随新数据变化。

检查期间,源沙箱一直保持可用。只有副本全部通过后,我才切换工作入口。如果某项状态没有恢复,可以继续使用旧沙箱处理任务,再重新检查恢复过程。

切换到副本

确认 repo-watch-copy 可以继续工作后,我执行了 nemohermes repo-watch stop。这个命令会停止源沙箱的容器和本地转发,但保留状态、策略、注册信息和 OpenShell 记录;需要回切时可以重新执行 start。迁移前创建的 before-clone 快照也继续保留。

同样的迁移方式也适用于 release 值守、客服工单分派或长期代码维护。运行时间较长的 Agent 通常已经积累了会话、Skills、策略和路由配置,重新安装程序无法恢复这些内容。实际切换时,可以让源端继续服务,先启动并检查副本,确认无误后再切换入口,最后停止源端。

旧 Dashboard 断开后,我又在副本中生成了一次日报,并重启终端检查本地入口。我确认当前打开的是 repo-watch-copy 的 Dashboard,原来的 Skill 和会话也都能找到,日报格式没有变化。后续任务可以直接从副本继续运行。

如果后续需要升级,我会在已经检查过的副本上执行 rebuild --yes,然后重复前面的检查。rebuild 会创建新的 sandbox home,并轮换 Hermes API bearer token;Dashboard 端口仍使用该沙箱登记的端口。升级后还要重新确认沙箱身份、状态、访问入口和凭据。

操作记录

下面汇总这次操作使用的命令。执行前需要保证 repo-watch 正在运行,且 repo-watch-copy 尚不存在。如果目标沙箱已经存在,restore --to 会拒绝执行;只有加入 --force --yes 才会删除并重建目标。建议先保存当前版本、状态和文件校验值。

# 基线
nemohermes --version
nemohermes repo-watch status --json
nemohermes repo-watch inference get
nemohermes repo-watch sessions --limit 20
nemohermes repo-watch exec -- \
  sha256sum /sandbox/.hermes/skills/daily-nemoclaw-digest/SKILL.md

# 封存源端
nemohermes repo-watch shields down \
  --timeout 10m --reason "clone validation"
nemohermes repo-watch snapshot create --name before-clone
nemohermes repo-watch snapshot list
nemohermes repo-watch shields up

# 恢复副本
nemohermes repo-watch snapshot restore \
  before-clone --to repo-watch-copy
nemohermes repo-watch-copy gateway restart
nemohermes repo-watch-copy shields status
nemohermes repo-watch-copy shields up

# 验收与切换
nemohermes repo-watch-copy dashboard-url --quiet
nemohermes repo-watch-copy status --json
nemohermes repo-watch-copy sessions --limit 20
nemohermes repo-watch-copy exec -- \
  sha256sum /sandbox/.hermes/skills/daily-nemoclaw-digest/SKILL.md
nemohermes repo-watch stop

参考资料

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐