ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Hermes v0.16.0 一周百 PR 实战:原生桌面 App 与 web 管理台双端交付方法论

Hermes v0.16.0 一周百 PR 实战:原生桌面 App 与 web 管理台双端交付方法论

1. 一周百 PR 的 Surface Release 到底在做什么

Hermes v0.16.0 这个版本号本身没什么稀奇,稀奇的是它的发布节奏——从立项到 Surface Release 落地,核心团队用一周时间合入了上百个 PR。这个数字放在任何一个成熟项目里都算激进,放在一个要同时交付原生桌面 App 和 web 管理台的项目上,就更值得拆开看看了。

先把概念对齐。所谓 Surface Release,指的是把原本只存在于命令行、脚本或者内部工具链里的能力,第一次以"用户能直接看见、直接点"的形态暴露出来。Hermes 之前的形态更接近一个 agent 运行时,用户通过配置文件、命令行参数去驱动它。v0.16.0 做的事情,是给它套上一层原生桌面 App 的壳,同时保留 web 管理台作为配置和观测入口。这两条线并行推进,才导致了 PR 数量的爆炸。

为什么这件事值得单独写一篇?因为"一周百 PR"这个现象背后,藏着一套可复现的工程方法。很多人看到的是速度,但真正决定成败的是拆分粒度、并行边界和合并策略。我见过太多团队想复刻这种节奏,结果要么 PR 互相踩踏,要么合并后回归测试全线飘红。Hermes 这次能跑通,不是因为他们手速快,而是因为他们在动手之前就把"什么该并行、什么必须串行"想清楚了。

这篇文章适合三类人看:一是正在做桌面端 + web 双端交付的开发者,二是想理解大规模 PR 并行合并策略的工程负责人,三是正在部署或准备部署 Hermes agent、想搞清楚桌面版和 web 管理台各自职责边界的用户。我会从架构拆分讲到具体操作,再讲到实测中踩到的坑,尽量把"为什么这么做"讲透,而不是只给一堆结论。

需要提前说明的是,Hermes 的桌面版在 Windows 和 Ubuntu 上都有部署路径,web 管理台则承担了大部分配置工作。这两者的分工不是随便定的,后面会专门拆。

2. 原生桌面 App 与 web 管理台的职责切分逻辑

2.1 为什么不是"全都塞进桌面 App"

很多人第一反应是:既然做了原生桌面 App,为什么不把所有功能都放进去,web 管理台岂不是多余?这个想法在早期确实流行过,但 Hermes 的选择恰恰相反——桌面 App 只做"高频、轻量、需要系统级能力"的事,web 管理台承接"低频、重配置、需要可视化"的事。

这个切分的依据是交互频率和系统权限两个维度。桌面 App 需要调用本地文件系统、系统托盘、原生通知、进程管理等能力,这些在浏览器沙箱里做不了或者做得很别扭。而 agent 的技能配置、MCP 接入、模型参数调整这类操作,用户可能一周才碰一次,但每次都要面对大量表单和结构化数据,放在 web 里用成熟的表单组件反而更高效。

我实测下来,这个边界如果划错,最典型的症状就是:桌面 App 里塞了一堆设置项,用户找不到;web 管理台里放了个需要实时响应的功能,延迟高到没法用。Hermes 这次把"实时状态展示"放在桌面 App 的托盘和主窗口,"配置持久化"放在 web 管理台,算是踩在了合理线上。

2.2 双端共享的到底是什么

双端并行开发最大的坑是逻辑重复。如果桌面 App 和 web 管理台各自实现一套 agent 调用逻辑,那 PR 数量翻倍不说,行为不一致的问题会层出不穷。Hermes 的做法是抽出一层共享的 core 层,桌面端和 web 端都通过它来和 agent 通信。

具体来说,core 层负责:agent 生命周期管理、技能加载、MCP 连接维护、消息路由。桌面 App 通过本地 IPC 调用 core,web 管理台通过本地 HTTP 接口调用 core。这样两端看到的 agent 状态是同一份,不会出现"桌面显示运行中、web 显示已停止"这种经典 bug。

提示:如果你也在做类似的双端架构,core 层的接口设计要尽早冻结。Hermes 这一周百 PR 里,有相当一部分是 core 接口的适配改动,如果接口反复变,两端的 PR 会互相阻塞。

2.3 一周百 PR 的拆分粒度参考

把上面这套架构落到 PR 上,Hermes 的拆分大致是这样的:

类别PR 占比典型粒度
core 层接口与逻辑约 25%单个技能加载器、单个 MCP 连接器
桌面 App UI约 30%单个窗口、单个托盘菜单项
web 管理台约 25%单个配置页、单个状态面板
构建与打包约 12%单平台打包脚本、签名流程
文档与示例约 8%单篇部署指南、单个配置示例

这个粒度意味着单个 PR 的改动量被压得很小,review 成本低,合并冲突概率也低。代价是 PR 数量多,需要一套自动化的 CI 来兜底。Hermes 的 CI 里,每个 PR 都要跑 core 层单测、桌面端冒烟、web 端构建三件套,缺一不可。

3. 并行开发的合并策略与冲突预防

3.1 分支模型:为什么不用长期 feature 分支

一周百 PR 能合进去,前提是分支生命周期极短。Hermes 采用的是短分支 + 频繁 rebase 的模式,单个分支存活时间基本不超过一天。长期 feature 分支在这种节奏下是灾难,因为主干每天都在变,分支拖三天就会积累大量冲突。

我自己的经验是,分支存活超过 48 小时,rebase 成本就会指数上升。Hermes 的做法是要求每个 PR 在提交后 24 小时内完成 review 和合并,超时要么拆分要么关闭重开。这个规则听起来严苛,但正是它保证了主干始终处于可发布状态。

3.2 冲突高发区的提前锁定

并行开发最怕的是多人改同一个文件。Hermes 在动手前做了一件事:把冲突高发区列出来,指定专人负责,其他人只能通过接口调用,不能直接改。

冲突高发区通常包括:路由注册表、技能清单、依赖版本文件、打包配置。这些文件的共同特点是"所有人都要往里加东西"。Hermes 的处理方式是把这些文件改成"约定式注册"——比如技能清单不再手写,而是扫描目录自动生成。这样新增技能只需要加目录,不用改清单文件,冲突自然消失。

3.3 CI 作为合并闸门的具体配置

光靠人 review 挡不住问题,Hermes 的 CI 闸门配置值得抄。核心是三道:

  1. 快速检查:lint + 类型检查,30 秒内出结果,不过直接打回。
  2. core 层单测:覆盖 agent 生命周期、技能加载、MCP 连接,5 分钟内跑完。
  3. 双端冒烟:桌面端启动到托盘就绪,web 端构建到首页可访问,10 分钟内跑完。

三道全绿才允许合并。这套配置的关键是"快",如果 CI 要跑半小时,开发者就会绕过它。Hermes 把最慢的端到端测试放在 nightly 里,PR 阶段只跑冒烟,这是速度和质量之间的务实取舍。

注意:冒烟测试的覆盖范围要定期 review。我见过项目冒烟测试跑了半年,结果它测的那条路径早就没人用了,真正的新路径反而没覆盖。

4. 桌面端在 Windows 与 Ubuntu 上的部署差异

4.1 Windows 部署的坑点集中在权限与路径

Windows 上部署 Hermes 桌面版,最容易出问题的是两处:一是安装路径含空格或中文,二是系统权限不足导致托盘图标不显示。前者会让某些依赖库加载失败,后者会让 App 启动后"看起来没反应"。

实测下来,安装路径建议用纯英文、无空格的目录,比如C:\Hermes。权限方面,如果托盘图标不出现,先检查是否以管理员身份运行过一次,让系统完成首次注册。另外 Windows 11 对托盘图标的收纳策略比较激进,图标可能被折叠进"隐藏的图标"里,别误判成没启动。

4.2 Ubuntu 部署要处理的是依赖与显示服务

Ubuntu 上的问题更偏底层。桌面 App 依赖的图形库如果版本不匹配,启动会直接报错退出。常见的是缺少libgtk相关库,或者 Wayland 和 X11 的兼容问题。

我的做法是先跑一遍依赖检查,把缺的库补齐,再确认显示服务类型。如果是 Wayland 环境,某些窗口行为可能和预期不一致,必要时切到 X11 会话验证。Ubuntu 上还有一个容易忽略的点:App 的桌面快捷方式需要手动放到~/.local/share/applications下,否则在应用菜单里找不到。

4.3 双平台打包的 PR 拆分方式

Hermes 把打包相关的 PR 按平台拆开,Windows 打包、Ubuntu 打包、签名流程各自独立。这样做的好处是某个平台出问题不会阻塞另一个平台的合并。打包脚本里,平台相关的路径、依赖、签名配置全部参数化,公共部分抽到共享脚本里。

这套拆法我复刻过,确实能减少互相等待。但要注意,打包脚本的公共部分一旦改动,两个平台的 PR 都要跟着 rebase,所以公共部分的接口要尽量稳定。

5. 实测中暴露的问题与排查链路

5.1 桌面版无法更新:从现象到根因

"hermes桌面版无法更新"是个高频问题。现象是点击更新后进度条卡住,或者更新完版本号没变。排查链路我整理成下面这样:

第一步,确认更新源是否可达。桌面 App 的更新通常走一个固定的检查接口,如果网络环境导致接口不可达,更新会静默失败。这一步可以通过查看 App 日志确认。

第二步,确认旧版本进程是否完全退出。Windows 上经常出现旧进程还在后台,新版本文件被占用无法替换。任务管理器里结束所有相关进程再重试。

第三步,确认安装目录写权限。如果 App 装在系统保护目录下,更新时没有写权限,替换文件会失败。把安装目录换到用户目录下通常能解决。

第四步,确认版本号比对逻辑。有些情况下更新其实成功了,但版本号显示逻辑有缓存,重启 App 后才会刷新。

5.2 卸载残留导致的重新安装失败

"hermes desktop 卸载"之后重新安装报错,多半是残留文件没清干净。Windows 上残留主要在三个地方:安装目录、用户配置目录、注册表项。Ubuntu 上则是安装目录和~/.config下的配置目录。

我的建议是卸载后手动检查这几个位置,确认没有残留再重装。特别是配置文件目录,如果里面存了旧版本的 schema,新版本读取时可能直接崩溃。

5.3 agent 连接不上的分层排查

桌面 App 显示 agent 未连接,问题可能出在三个层次:core 层没起来、IPC 通道断了、agent 进程本身崩了。排查顺序应该是从下往上:先确认 agent 进程在不在,再确认 core 层日志有没有报错,最后看桌面 App 的 IPC 连接状态。

这个分层排查的思路很重要,因为现象都是"连不上",但根因可能完全不同。我踩过的坑是直接去查桌面 App,结果发现是 agent 进程因为某个技能加载失败早就退了。

6. 从这次发布里能抄走的方法论

6.1 把"能并行"和"必须串行"提前标出来

一周百 PR 的核心不是快,是"该并行的并行,该串行的串行"。Hermes 在动手前就把任务分成两类:接口定义、core 层改动这类必须串行,UI、文档、打包这类可以并行。串行的部分优先做完并冻结,并行的部分才铺开。

这个顺序如果反了,先铺开并行任务,等接口一变全部返工,PR 数量再多也是白搭。

6.2 用自动化把 review 成本压下来

PR 多了,review 就是瓶颈。Hermes 的应对是让 CI 承担大部分机械检查,人只 review 逻辑和边界。格式化、lint、类型、单测这些全部自动化,reviewer 打开 PR 时看到的是"机器已经确认没低级问题"的状态,注意力可以集中在设计上。

6.3 主干始终可发布是底线

不管并行多少任务,主干必须随时能出一个可用的版本。Hermes 靠的是短分支 + 频繁合并 + CI 闸门这三件套。任何让主干变红的 PR 都会被立即回滚,而不是"先合进去再修"。这条底线守住了,发布节奏才可控。

6.4 文档和示例别放到最后

这次发布里文档和示例占了约 8% 的 PR,而且是和功能同步推进的。我见过太多项目把文档留到最后,结果功能细节已经记不清了,写出来的文档和实际行为对不上。同步推进虽然麻烦,但准确性高得多。

7. 部署与使用中的几个实操建议

如果你正准备部署 Hermes,不管是 Windows 还是 Ubuntu,有几个点值得提前注意。

第一,安装路径统一用英文无空格目录,这一条能避开大量莫名其妙的问题。第二,首次运行给足权限,让系统完成必要的注册,之后再按需降权。第三,配置改动优先走 web 管理台,桌面 App 只做日常操作,这样配置的持久化和版本管理更清晰。第四,遇到连接问题先分层排查,别一上来就重装。第五,更新前先确认旧进程完全退出,这一步能省掉很多"更新失败"的误判。

关于 web 管理台和桌面 App 的配合,我的习惯是:桌面 App 常驻托盘负责状态监控和快速唤起,web 管理台在需要改配置时打开。两者共享同一份 core 状态,所以不会出现数据不一致。这个分工用顺了之后,日常操作基本不用碰命令行。

最后说一个容易被忽略的细节:Hermes 的技能和 MCP 接入配置,建议在 web 管理台里改完之后,导出备份一份。桌面 App 重装或者换机器时,直接导入就能恢复,比重新配一遍省事得多。这个习惯我在多个 agent 类工具上都用,屡试不爽。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进