止观
Hermes实战

Hermes 三天放出的 v0.21.3 补丁,一半打在定时任务的痛点上

稿子里排好队、今天本该发的,是写了两天刚完稿的《我把 bot 团队拉进了一块看板:Hermes Kanban 实战》。计划赶不上版本,今早例行去 GitHub Releases 转了一圈:Hermes 出 v0.21.3 了。按我的老规矩,新版本解读插队,kanban 那篇顺延到明天。

先看这个 release 的体量。9 月 11 号 v0.21.2 刚落地,9 月 14 号 v0.21.3 就来了,三天窗口,官方口径是 338 个合并 PR、1036 个非 merge 提交、2642 个文件改动,+13 万行。官方自己也说了这是 rollup 补丁版本,正式的精选 release notes 要攒到 v0.22.0 一起发。所以我这篇只能自己从 commit 记录里刨:哪些改动是冲着把 agent 当服务跑的人来的。

刨完的结论放在前面:这个版本延续 v0.21.2 的路线,主打“不打扰”。没有爆炸新功能,但它把后台里那些会突然咬人一口的东西,挨个关了笼子。

※ ※ ※

先对个账:v0.21.2 修了什么,0.21.3 接着修什么

想看懂 0.21.3,得先回头看一眼三天前的 0.21.2。那个版本的副标题就叫 “The state.db Patch Release”,起因是 v0.21.0 把 session store 的连接层大改了写法,结果在某些安装环境里把状态库 state.db 搞得很容易受伤。0.21.2 用六个 PR 堵住了四类“第二个写者”的入口:

v0.21.2 堵住的坑当时会发生什么
profile gateway 每 5 秒往根库写 hosted-room 状态多实例互踩,改成写独立的 shared-state.db
dashboard 启动就开一个可写连接和 gateway 抢锁,改成先以只读打开
cron 存活检查直接 open() 活的数据库SQLite 的 POSIX 锁会被这种裸开取消,改走连接注册表
doctor --fix 在有人持有写锁时做 checkpoint可能压坏 WAL,改成证明安全才动手

一句话总结:0.21.2 解决的是“别把库写坏”。

而 0.21.3 里被官方点名唯一详写的那条修复(#110934),解决的是下一个层次的问题:“别把句柄漏光”。gateway、dashboard、CLI 这些长寿进程虽然不该写库,但各自还会重复创建读句柄,日志里隔几天就冒一次 “N live SessionDB handles” 的警告——数据库其实是健康的,警告刷得人心里发毛。修复后的规则很干净:读的一方一律 readonly attach,写的一方共享注册表里的同一个句柄。

打个比方,v0.21.2 是“进门不许乱翻东西”,v0.21.3 是“进门别一人复印十把钥匙”。跑几台常驻 agent 服务的人对这类问题最有体感:假设你有两台云主机,一台 203.0.113.10 跑 gateway 接消息,一台 198.51.100.7 跑 dashboard 看会话,两台机器上那个 ~/.hermes/state.db 都会被三四个进程同时打开。0.21.0 时代轻则警告刷屏,重则库文件损坏;0.21.2 之后锁干净了;0.21.3 之后连虚警都没了。三个版本连起来读,才看得出官方对 session store 这场事故是“止血、包扎、复查”一步步在收尾。

这个窗口还有条同族修复值得单独说:state.db WAL refusal on cross-VM filesystems。跨虚拟机的文件系统(NFS 这类)上,SQLite 直接拒绝开 WAL 模式。原因很硬:网络文件系统上的文件锁本来就不可信,与其悄悄坏数据,不如启动时就掀桌。这种“宁可不开工也不坏数据”的取舍,我是认的。

※ ※ ※

cron 的三种死法,这版本各给了一味药

把 agent 当服务跑的人,一半的依赖都在 cron 上。定时任务最阴险的不是报错,是静默没跑。v0.21.3 给调度器补了三块,全在这个方向。

第一块:automatic bounded re-runs when a fire never reached the model。以前的行为是到点触发,算“跑过了”。但如果这一枪因为网络抖动、provider 抽风,请求根本没送到模型手里,当天的活就直接蒸发,日志里还找不出异常。举个最常见的场景:你设了每周一早八点让 agent 汇总上周数据发群,某天早上你的推理服务 API 恰好抽风三十秒,这周你就是安静地什么也没收到。升级后,调度器能识别“fire 从未触达模型”这种状态并自动重跑。注意 bounded 这个词,重跑有次数上限,不会把一次抖动放大成重试风暴。

第二块:let planned downtime skip missed recurring runs。做过运维的都懂:计划内停机升级一小时,回来发现积压的 N 个周期噼里啪啦全补跑。错过的日报在停机两小时后补发毫无意义,纯烧 token 还刷屏。现在计划内停机可以选择“跳过错过的周期”,而不是无脑追债。

第三块是个小命令:hermes cron resnap <job>。背景挺隐蔽:cron 任务创建时会“快照”当时的推理档位,全局默认模型从 A 切到 B 之后,老任务还钉在 A 上跑,想跟着新默认走只能删了重建。resnap 就是让没钉死的任务重新采用当前全局默认,同时保留“钉死”选项给那些你故意锁档位的任务。档位管理这种小事,终于不用靠重建任务这种粗暴手段了。

v0.21.3 三条改动主线

※ ※ ※

省钱和守门,都落在细节里

跑过带截图任务的人都知道 token 大户是谁:computer-use 盯浏览器时,屏幕没变,每一轮还是一整张截图原样重发。这版本上游加了截图去重,按会话比对帧内容,画面没变就不再重发。对长时间盯一个静态页面的任务,这是能直接从账单上看出来的区别。

安全上补了一条我很欣赏的:云主机元数据服务(IMDS)访问强制过审批。所有主流云的实例元数据端点都长得差不多,比如 http://169.254.169.254/latest/meta-data/,本机进程随便 GET 一下就能拿到这台实例的临时 IAM 凭据,不需要任何认证。这是云上最经典的越权跳板:agent 被 prompt injection 诱导,绕个弯去访问元数据地址,拿到云凭据,整台机器的云资源就是别人的了。v0.21.3 之后,agent 要碰这类地址必须先过人工审批,浏览器工具那边则是无条件封死。堵攻击链堵在“顺手拿凭据”这一步,比事后审计体面得多。

技能管家 curator 的清理阈值也从 90 天压到 30 天(14 天不用先标 stale,30 天未用归档)。技能库装多了没人收拾的,这是官方帮你减肥。

其余零碎的,按重要程度过一遍:

改动一句话说明
HEIF/HEIC/AVIF 解码iPhone 照片直接丢给视觉模型,不用先转 JPG
每个模型选择器加 reasoning effort思考档位从“个别模型支持”变成全面板标配
多路复用 gateway 收口hermes gateway migrate --multiplex,一个 gateway 进程服务所有 profile,运行中新建的 profile 热加载
Slack 粘贴表格修复贴进对话的表格以前会凭空消失
OpenRouter OAuth PKCE 登录hermes auth add openrouter --type oauth,不用手搓 API key
CLI 的 vi 模式display.vim_mode 加 /vim 命令,输入框支持 h/j/k/l
契约层gateway 的 JSON-RPC 方法用 Pydantic 定义,自动生成 TS/OpenRPC 给前端消费
视频模型上新Wan 3.0、Kling 3.0、MiniMax H3 Max Turbo、Gemini Omni Flash 1.1 文生视频等入目录

那个契约层值得多说半句。以前 Python 后端和 TypeScript 前端之间的消息格式靠人肉对齐,字段改名全靠 grep 的勇气。现在 wire contract 是唯一真源,前端手写的类型定义删掉换成生成的。这种活不会出现在任何宣传图里,但它是“改代码不改崩对面”的地基。桌面端和云端用户还有一条实感很强的:远程 dashboard 会话在刷新风暴下会被整条吊销(#110061),根因是两条刷新路径并发时把已轮转的 token 重放给了认证服务端、触发 reuse detection,修复是把同 token 的并发刷新请求合并。用桌面端连远程 gateway 的人,升级后登录态会明显变稳。

※ ※ ※

升级演示(虚拟环境版)

git 安装路径的升级,拿一台干净机器演示,主机用文档保留地址 203.0.113.5 示意:

ssh demo@203.0.113.5
cd ~/.hermes/hermes-agent
git fetch --tags
git checkout v2026.9.14
venv/bin/pip install -e .
hermes --version
# Hermes Agent v0.21.3 (2026.9.14)

docker 或托管部署更省事,官方镜像直接跟着 tag 走。注意更新完 gateway 要重启才会跑新代码,常驻服务会断一两分钟,挑没任务在跑的时间窗动手;如果给 gateway 挂了守护,确认它是“外部 shell 执行重启”而不是从 gateway 进程内部发指令,后者会被防自杀保护直接拒绝。

※ ※ ※

该不该更

跑常驻任务的人,我的建议是:更。这个版本没有行为大改,全是防劣化补丁,尤其 state.db 句柄和 cron 静默失败这两条,属于“你现在没出事是因为还没撞上”。轻度用户无所谓,等 v0.22.0 的精选 release notes 一次性看完也行,官方说了这个窗口的完整解读到时候补。

一个小提醒:curator 清理阈值改成 30 天了,手动装的、又不常被命中的技能,记得定期用用,或者干脆把它挪出托管目录。

你的 agent 定时任务,有没有过“以为在跑、其实早就悄悄死了”的经历?评论区说说你是什么时候发现的。

点个在看,把这篇转给那个 cron 报错从不看的人。

明天发的是被我插队的那篇:《我把 bot 团队拉进了一块看板:Hermes Kanban 实战》——多 bot 怎么共用一块板、dispatcher 的护栏长什么样、边界在哪,实战踩坑全在里面。

※ ※ ※

资料来源

  • ▪ 官方 release notes:GitHub NousResearch/hermes-agent 的 v0.21.2、v0.21.3 两条 release
  • ▪ 提交记录:git log v2026.9.11..v2026.9.14(1037 条,逐条筛选);文中 commit message 均为原文摘录或直译
  • ▪ 源码核对:cron/jobs.py(resnapshot_job)、agent/curator.py(14/30 天阈值)、tools/approval_detection.py 与 tools/browser_tool.py(IMDS 封禁)
  • ▪ 文中示例主机均为文档保留地址(RFC 5737),非作者真实环境;升级命令为 git 安装方式的通用写法
  • ▪ 生成日期:2026-09-15

评论 (0)