兰 亭 墨 苑
期货 · 量化 · AI · 终身学习
首页
归档
编辑文章
标题 *
URL 别名 *
内容 *
(支持 Markdown 格式)
# Nanobot & Hermes Agent 升级全记录 > **日期**: 2026-06-10 ~ 2026-06-13 > **作者**: 雨轩 > **标签**: 升级, nanobot, hermes, systemd, 运维 --- ## 一、背景 ### 1.1 系统现状 Nanobot 是广山哥的个人 AI 助手系统,运行在一台 Ubuntu R86S 小主机上。整个系统由多个服务组件构成: | 组件 | 版本 | 用途 | |------|------|------| | nanobot-ai | 0.1.5 | 主框架(消息路由、渠道接入、Agent 调度) | | Hermes Agent | v0.13.0 (2026.5.7) | 独立的 AI Agent 框架(对话、网关、ACP) | | 自定义管理面板 | — | 广山哥自建的 Web 管理后台(端口 9100) | | Weclaw | — | 另一个 AI 服务(独立仓库) | 除了软件包本身,还有一系列外围服务: - **nanobot-gateway** — systemd 服务,消息路由主网关 - **file-server** — 文件浏览器(端口 5000) - **dingtalk-image-bridge** — 钉钉图片桥接(端口 5002) - **wechat-image-bridge** — 微信图片桥接(端口 5003) - **management-api** — Nanobot 管理 API(端口 18800) 这些服务通过 `restart_services.sh` 统一管理,一个脚本依次停止、清理、重启全部服务。 ### 1.2 升级动机 本次升级有两个主要驱动因素: **nanobot-ai 版本落后**:当前运行的是 0.1.5,而 PyPI 上最新版本已经是 0.2.1,中间跨了 0.1.5.post1~post3、0.2.0 等多个大版本。新版本带来了 boto3 S3 集成、openpyxl Excel 处理、pypdf PDF 解析、python-pptx PowerPoint 支持等新能力。 **Hermes Agent 版本落后**:Hermes 虽然显示 "Up to date",但实际上广山哥维护的 fork 版本(v0.13.0)与上游 NousResearch 的最新版(v0.16.0)之间存在巨大差距。上游已发布多个新版本,包含大量架构重构和安全加固。 --- ## 二、升级策略 ### 2.1 核心原则 升级方案遵循三条原则: 1. **先备份,再升级** — 任何修改前必须创建可回退的完整备份 2. **可回退** — 如果升级后服务不可用,能在 5 分钟内恢复到升级前状态 3. **分步验证** — 升级 nanobot → 升级 hermes → 重启服务,每一步都验证 ### 2.2 风险识别 升级前识别的风险点: | 风险 | 等级 | 缓解措施 | |------|:----:|---------| | nanobot 0.1.5 → 0.2.1 API 不兼容 | 中 | .venv 全量备份,可 pip install 回退 | | Hermes 用户 fork 与 upstream 分叉 | 高 | 完整 git 目录备份,记录 HEAD commit | | 依赖冲突 | 中 | pip freeze 保存依赖快照 | | 服务启停顺序错误 | 低 | 使用成熟的 restart_services.sh | ### 2.3 备份方案 备份采用三层策略: - **git commit** — 代码版本控制,所有变更提交到本地 git 仓库并推送到 NAS - **pip freeze** — 精确保存当前 Python 依赖版本列表 - **全量 tar** — 虚拟环境和 hermes 目录打包到 NAS,确保能完整恢复运行环境 --- ## 三、备份执行 ### 3.1 Git 快照 ``` # nanobot 主仓库 git -C /home/nanobot/.nanobot add -A git -C /home/nanobot/.nanobot commit -m "backup: pre-upgrade snapshot" ``` 当前 HEAD:`db0a728b`,远程仓库同时推送至 GitHub 和 NAS 本地仓库。 ### 3.2 依赖快照 通过 `pip freeze` 将当前 165 个 Python 包的精确版本写入 `config/requirements-backup-20260610.txt`,包含 wxwatcher、anthropic、openai、litellm、mcp 等核心依赖。 ### 3.3 虚拟环境全量备份 Nanobot 的 .venv 目录 595MB,通过 tar 压缩后 159MB: ``` tar -czf /mnt/nas/backups/nanobot-upgrade-20260610/nanobot-venv-20260610.tar.gz \ -C /home/nanobot/.nanobot .venv ``` ### 3.4 Hermes 全量备份 Hermes Agent 的安装目录 `/root/.hermes/hermes-agent/` 体积较大(1.8GB),包含完整的 Python 虚拟环境、Node 依赖、构建产物。压缩后 610MB: ``` tar -czf /mnt/nas/backups/nanobot-upgrade-20260610/hermes-agent-20260610.tar.gz \ -C /root/.hermes hermes-agent ``` 同时记录当前 git HEAD 用于精确回退: ``` # hermes HEAD: a40e67712 # Message: fix(kanban/dashboard): fix aria-label for column select-all checkbox; add v2 dist bundle ``` 备份后的 NAS 目录结构: ``` /mnt/nas/backups/nanobot-upgrade-20260610/ ├── nanobot-venv-20260610.tar.gz (159M) ├── hermes-agent-20260610.tar.gz (610M) └── hermes-pre-upgrade-commit.txt (HEAD 记录) ``` ### 3.5 备份验证 每个备份文件创建后都验证了存在性和大小。pip freeze 确认 166 行(含注释头),tar 文件确认无报错退出。 --- ## 四、Nanobot 升级 ### 4.1 升级过程 Nanobot 的升级最简单直接——它是通过 PyPI 发布的纯 Python 包: ``` /home/nanobot/.nanobot/.venv/bin/pip install --upgrade nanobot-ai ``` ### 4.2 版本变化 | 项目 | 升级前 | 升级后 | |------|--------|--------| | nanobot-ai | 0.1.5 | **0.2.1** | | 安装方式 | PyPI | PyPI | ### 4.3 新增依赖 0.2.1 版本新增了大量依赖,主要涉及 Office 文档处理和 AWS 集成: | 包 | 用途 | |----|------| | boto3 1.43.29 | AWS S3 SDK(R2 对象存储对接) | | botocore 1.43.29 | boto3 底层核心 | | s3transfer 0.18.0 | S3 传输管理 | | openpyxl 3.1.5 | Excel .xlsx 读写 | | pypdf 5.9.0 | PDF 解析 | | python-pptx 1.0.2 | PowerPoint 处理 | | python-docx 1.2.0 | Word 文档处理 | | XlsxWriter 3.2.9 | Excel 写入优化 | | et-xmlfile 2.0.0 | XML 文件处理 | | tornado 6.5.7 | Web 服务(Telegram webhooks) | ### 4.4 依赖升级 同时,多个已有依赖也被升级到兼容版本: | 包 | 旧版 | 新版 | |----|:----:|:----:| | botocore | 1.42.68 | 1.43.29 | ### 4.5 验证 升级完成后通过 `pip show nanobot-ai` 确认版本号,不再需要其他额外操作,因为 nanobot 的核心代码通过 `pip install` 直接替换。 --- ## 五、Hermes Agent 升级 ### 5.1 版本检测 升级前首先检测版本和远程仓库状态: ``` Hermes Agent v0.13.0 (2026.5.7) Up to date # hermes 自身的版本检查 # 远程仓库 origin → git@github.com:yuanguangshan/hermes-agent.git(用户 fork) upstream → https://github.com/NousResearch/hermes-agent.git(官方源) ``` ### 5.2 获取更新 首次尝试 `git fetch upstream` 因为仓库历史庞大而超时。改用浅层拉取成功: ``` git -C /root/.hermes/hermes-agent fetch --depth=1 upstream main ``` 发现 upstream 有 1 个新 commit(`2a5dc0ef3`),修复了 Slack 视频附件问题。 ### 5.3 合并冲突 尝试 `cherry-pick` 新 commit 时,发现用户 fork 与上游已严重分叉——500+ 文件全部出现 `add/add` 冲突。这是因为用户 fork 是在早期版本从上游分离后独立发展的,两个仓库的历史完全不相关。 ``` cherry-pick --abort # 回滚,放弃合并 ``` ### 5.4 依赖更新 代码虽然无法直接合并,但子依赖可以通过 `uv sync` 更新: ``` uv sync --directory /root/.hermes/hermes-agent ``` 更新了 pydantic-core、pyjwt、yarl 等 15+ 个子依赖。 ### 5.5 广山哥的远程更新 随后广山哥更新了远程 fork 仓库(force push),将 upstream 的最新代码合并到了自己的仓库。此时: ``` git -C /root/.hermes/hermes-agent fetch origin main # + a40e67712...2a5dc0ef3 main -> origin/main (forced update) git -C /root/.hermes/hermes-agent reset --hard origin/main ``` 成功将 Hermes 从 v0.13.0 升级到 v0.16.0。 ### 5.6 版本差异 新旧版本之间的差异巨大——3619 个文件被修改,+694K / -105K 行代码: | 维度 | v0.13.0(旧) | v0.16.0(新) | |------|:-------------:|:-------------:| | 版本号 | 0.13.0 | **0.16.0** | | Python 版本上限 | `>=3.11` | `>=3.11,<3.14` | | 依赖策略 | 范围锁定 | 精确锁定(供应链安全) | | 修改文件 | — | 3619 个 | | 新增/删除行 | — | +694K / -105K | 核心架构变化包括: - **Agent 引擎重构**:旧的 `run_agent` monolith 拆分为 `conversation_loop.py`、`tool_executor.py`、`turn_context.py`、`turn_finalizer.py`、`turn_retry_state.py` 等 7+ 独立模块 - **Provider 抽象**:browser、image_gen、transcription、TTS、video_gen、web_search 全部转为 Provider + Registry 可插拔模式 - **LSP 集成**:全新 `agent/lsp/` 模块,agent 可感知编辑器诊断 - **Codex Runtime**:新增 HTTP/WebSocket 服务器模式的 agent 运行方式 - **插件系统成熟化**:plugins/ 目录大幅扩充,支持热插拔 - **依赖安全加固**:所有直接依赖改为精确版本锁定,注释明确说明是响应 mistralai 投毒事件的供应链安全加固 --- ## 六、服务重启与验证 ### 6.1 重启过程 升级后执行 `restart_services.sh`,脚本依次: 1. 停止所有 5 个系统服务 2. 清理残留进程(pkill) 3. 释放端口(5000、5002、5003、18800) 4. 重置 Telegram polling 状态 5. 按序启动:gateway → dingtalk bridge → wechat bridge → file server → management API 6. 等待 Gateway API 可用(最多 15 秒) 7. 验证所有端口绑定 ### 6.2 验证结果 全部 5 个服务正常启动,4 个端口全部监听: | 服务 | PID | 状态 | |------|:---:|:----:| | nanobot-gateway.service | 974852 | 😊 在岗 | | dingtalk-image-bridge.service | 974863 | 😊 在岗 | | wechat-image-bridge.service | 974865 | 😊 在岗 | | nanobot-file-server.service | 974867 | 😊 在岗 | | nanobot-management-api.service | 974869 | 😊 在岗 | 不需要回退。 --- ## 七、自定义管理面板的发现 ### 7.1 广山哥的反馈 升级完成后,广山哥提到他访问 `hms.want.biz` 时看到的界面与自己维护的 Hermes 管理面板不同: ``` 📊 状态总览 💬 会话记录 🧠 记忆系统 🌡️ 雨轩状态 📦 技能列表 ⚙️ 配置查看 📋 运行日志 🎨 主题:暗色 / 亮色 / 午夜 / 森林 / 日落 / 北欧 ``` ### 7.2 溯源 调查发现,这个界面并非来自 Hermes 官方 Dashboard(端口 9119),也非来自 Nanobot 的 Management API(端口 18800),而是一个 **完全独立的 FastAPI 服务**,藏在 `/root/.hermes/web-panel/` 目录下: ``` /root/.hermes/web-panel/ ├── server.py # FastAPI 后端,342 行 └── static/ ├── index.html # 单页前端,522 行 └── albums/ # 相册目录 ``` 该服务: - 运行在端口 **9100** - 由广山哥**手动启动**(`python3 web-panel/server.py`),从 6 月 7 日运行至今 - 通过 Cloudflare Access 保护(`hms.want.biz`→ Cloudflare 邮箱登录 → 本地 9100) - **不依赖 Hermes API**,而是直接读取 Hermes 的本地数据文件 - 有自己的 Token 认证机制(首次启动生成 `.token` 文件) ### 7.3 数据来源分析 这个面板的后端(server.py)不走任何官方 API,所有数据全部直读磁盘: | 功能 | 数据源 | |------|--------| | 状态总览 | `~/.hermes/config.yaml` + `~/.hermes/state.db`(SQLite) | | 会话记录 | `state.db` 的 sessions/messages 表 | | 记忆系统 | `~/.hermes/memories/MEMORY.md` 和 `USER.md` | | 雨轩状态 | `~/.hermes/data/context/daily_state.yaml` | | 技能列表 | 遍历 `~/.hermes/skills/` 目录 | | 配置查看/编辑 | 直接读写 `~/.hermes/config.yaml` | | 运行日志 | `journalctl -u hermes-gateway` | | 重启操作 | `systemctl restart` | --- ## 八、Systemd 服务归组 ### 8.1 发现的问题 在排查过程中,发现 Hermes 生态中有三个进程是手动启动的,没有注册为 systemd 服务: | 进程 | 启动方式 | 启动时间 | 问题 | |------|---------|:--------:|------| | hermes dashboard (9119) | 手动 `python hermes dashboard ...` | Jun 7 | 重启不自动恢复 | | acp-adapter | 手动 `python -m acp_adapter.entry` | Jun 12 | 重启不自动恢复 | | web-panel (9100) | 手动 `python3 server.py` | Jun 7 | 重启不自动恢复 | ### 8.2 设计方案 采用 systemd target 机制将所有服务归组管理: ``` hermes.target ├── hermes-gateway.service — 消息网关(已有) ├── hermes-dashboard.service — Web UI(新建) ├── hermes-acp-adapter.service — ACP 适配器(新建) └── hermes-web-panel.service — 管理面板(新建/改造) ``` 设计要点: - **PartOf=hermes.target** — 所有服务声明自己属于该 target - **BindsTo=hermes-gateway.service** — web-panel 与 gateway 绑定,gateway 退出时 web-panel 自动停止 - **After=hermes-gateway.service** — dashboard 和 acp-adapter 在 gateway 之后启动 - **Restart=on-failure** — 任何服务崩溃后自动重启 - **WantedBy=multi-user.target** — hermes.target 随系统开机自启 ### 8.3 创建服务文件 **hermes-dashboard.service**: ```ini [Unit] Description=Hermes Agent Dashboard (Web UI - Port 9119) After=network-online.target hermes-gateway.service PartOf=hermes.target [Service] Type=simple User=root ExecStart=/root/.hermes/hermes-agent/.venv/bin/hermes dashboard \ --port 9119 --host 0.0.0.0 --no-open --insecure Restart=on-failure RestartSec=5 WorkingDirectory=/root/.hermes/hermes-agent [Install] WantedBy=hermes.target ``` **hermes-acp-adapter.service**: ```ini [Unit] Description=Hermes Agent ACP Adapter After=network-online.target hermes-gateway.service PartOf=hermes.target [Service] Type=simple ExecStart=/root/.hermes/hermes-agent/.venv/bin/hermes acp Restart=on-failure RestartSec=5 WorkingDirectory=/root/.hermes/hermes-agent [Install] WantedBy=hermes.target ``` **hermes.target**: ```ini [Unit] Description=Hermes Agent — All Services Requires=hermes-gateway.service Wants=hermes-dashboard.service hermes-acp-adapter.service hermes-web-panel.service After=network-online.target [Install] WantedBy=multi-user.target ``` ### 8.4 ACP 依赖修复 首次启动 acp-adapter 时失败,日志显示: ``` ACP dependencies not installed. Install them with: pip install -e '.[acp]' ``` 原因是新版本将 ACP 依赖从核心依赖移到了 extras。通过重新安装解决: ``` pip install -e /root/.hermes/hermes-agent'[acp]' ``` ### 8.5 Dashboard 首次构建 Dashboard 首次通过 systemd 启动时,需要构建前端(`npm ci + tsc -b + vite build`),耗时约 40 秒。完成后端口 9119 正常监听。 ### 8.6 最终状态 ``` hermes.target active ├── hermes-gateway.service active (systemd) ├── hermes-dashboard.service active (systemd, 端口 9119) ├── hermes-acp-adapter.service active (systemd) └── hermes-web-panel.service active (systemd, 端口 9100) ``` 使用方式: ```bash # 一条命令管理全部 systemctl start/stop/restart/status hermes.target # 或单独操作某个服务 systemctl restart hermes-web-panel.service ``` --- ## 九、升级前后对比 ### 9.1 版本变化 | 组件 | 升级前 | 升级后 | |------|--------|--------| | nanobot-ai | 0.1.5 | **0.2.1** | | Hermes Agent | v0.13.0 (2026.5.7) | **v0.16.0 (2026.6.5)** | | 新增依赖 | — | boto3、openpyxl、pypdf、python-pptx 等 10 个 | | Python | 3.12.3 | 3.12.3(不变) | ### 9.2 服务管理变化 | 维度 | 升级前 | 升级后 | |------|--------|--------| | gateway | systemd | systemd(归组到 target) | | dashboard | **手动启动** | **systemd,自动恢复** | | acp-adapter | **手动启动** | **systemd,自动恢复** | | web-panel | **手动启动** | **systemd,自动恢复** | | 开机自启 | ❌ 部分服务 | ✅ **全部自启** | | 崩溃恢复 | ❌ 手动进程不会恢复 | ✅ Restart=on-failure | ### 9.3 备份体积 | 备份 | 原体积 | 压缩后 | |------|:-----:|:------:| | .venv | 595 MB | 159 MB | | hermes-agent | 1.8 GB | 610 MB | | 合计 | ~2.4 GB | ~769 MB | --- ## 十、回退方案 如果升级后需要回退,按以下步骤操作: ### 10.1 Nanobot 回退 ```bash # 恢复 .venv tar -xzf /mnt/nas/backups/nanobot-upgrade-20260610/nanobot-venv-20260610.tar.gz \ -C /home/nanobot/.nanobot/ # 降级 nanobot /home/nanobot/.nanobot/.venv/bin/pip install nanobot-ai==0.1.5 ``` ### 10.2 Hermes 回退 ```bash # 方式一:从 tar 完整恢复 systemctl stop hermes.target rm -rf /root/.hermes/hermes-agent tar -xzf /mnt/nas/backups/nanobot-upgrade-20260610/hermes-agent-20260610.tar.gz \ -C /root/.hermes/ # 方式二:git reset(需重新 uv sync) git -C /root/.hermes/hermes-agent reset --hard a40e67712 cd /root/.hermes/hermes-agent && rm -rf .venv && uv sync ``` ### 10.3 回退后重启 ```bash /home/nanobot/.nanobot/scripts/deploy/restart_services.sh systemctl restart hermes.target ``` --- ## 十一、经验与教训 ### 11.1 备份先行 本次升级最大的安全保障是升级前的全量备份。如果没有 `.venv` 和 `hermes-agent` 的 tar 备份,一旦升级后出现不兼容问题,恢复将非常困难。备份不只是心理安慰,而是真正的保险丝。 ### 11.2 不要假定用户的 fork 与 upstream 可合并 Hermes 的升级过程遇到的最大问题是用户 fork 与 upstream 历史分叉。这是一个常见场景——用户 fork 了开源项目后长期自己维护,再去合并上游时发现已经无法自动合并。对于这种情况,更好的策略是: 1. 先尝试 cherry-pick 具体需要的 commit,而不是尝试完整合并 2. 如果分叉太严重,考虑重新基于 upstream rebase,或者接受 fork 独立发展的现实 ### 11.3 系统化管理的价值 将手动启动的进程转为 systemd 服务后,带来的实际收益: - 服务器重启后所有服务自动恢复(之前需要手动逐个启动) - 进程崩溃后自动重启(之前需要手动发现和恢复) - 统一的管理接口(一条命令 vs 多个 tmux 窗口) - 更清晰的依赖关系(启动顺序、绑定关系) ### 11.4 独立服务 vs "隐藏"服务 广山哥的自定义管理面板是一个典型的技术债案例:功能完善、运行稳定,但因为没有纳入系统化管理,"寄生"在系统中间。类似的情况在很多长期运行的系统上都会出现——一个"临时"的手动启动脚本变成了运行半年的关键服务。解决方案就是亡羊补牢:发现了就立即转为 systemd 服务。 ### 11.5 关于大版本跳越 nanobot-ai 从 0.1.5 到 0.2.1 的升级相对平稳,因为 Python 包的向后兼容性较好。但 Hermes 从 v0.13.0 到 v0.16.0 的跨版本升级涉及大量架构变动(agent 引擎重构、插件系统、Provider 抽象),虽然目前看起来正常,但建议后续观察一段时间,留意是否有功能异常。 --- ## 十二、后续建议 ### 12.1 短期 - 观察 nanobot 和 Hermes 的渠道消息收发是否正常(Telegram、钉钉、企业微信) - 检查自定义管理面板的"雨轩状态"和"记忆系统"页面数据是否更新正常 - 确认 `hms.want.biz` 的 Cloudflare Access 访问正常 ### 12.2 长期 - 定期执行 `pip list --outdated` 检查 nanobot 依赖是否有安全更新 - Hermes 的上游更新建议定期 fetch 评估,避免再次出现大面积分叉 - 考虑将 Weclaw 等其他服务也纳入 systemd 管理 - 管理面板的 Token 认证可以增强为 session 机制 --- *雨轩于听雨轩* 🌧️🏠 > **本文档记录了一次完整的软件包升级过程,从备份到升级再到服务归组,涵盖 4 个 systemd 服务的创建/改造、2 个软件包的主版本升级、以及一个隐藏管理面板的发现和系统化管理。总耗时约 3 天的断续运维。*
配图 (可多选)
选择新图片文件或拖拽到此处
标签
更新文章
删除文章