Hermes Agent 定时任务三件套:monitor-mode、notepad 与 preflight 校验

定时任务(cron)是 Hermes Agent 最实用的自动化能力之一:每天 9 点抓取 Hacker News 热榜、每 30 分钟检查一次构建状态、每小时汇总订阅源…… 但跑得越勤,问题也越明显——大部分 tick 都在烧 token 做重复劳动,配置一旦写坏还会白白消耗一次 LLM 调用,任务间要传递状态(比如“上次处理到哪条”)更是只能靠外挂文件。
2026 年 8 月初合入 main 的这批更新,给 cron 补上了三件关键装备:
- monitor-mode(监控模式)——用廉价脚本/URL 先跑一步,输出哈希没变就直接跳过整个 agent 运行,零 LLM 开销;
- notepad(任务便签)——每个任务一块持久化 KV 存储,游标、水位线、待办清单跨运行存活;
- preflight(预检)——每次调度前先验证任务配置能否跑通,坏配置直接标记
blocked_config,一次警告、绝不烧 token。
外加一个 usage_audit.jsonl 日志,把每次 cron 运行的 token 花费如实记账。本文逐一展开,附真实 CLI 与配置示例。
1. monitor-mode:让定时任务先“嗅”再跑
为什么需要它
一个典型的监控型定时任务长这样:“每 5 分钟检查一下订阅源有没有更新,有就总结给我”。在没有 monitor-mode 之前,Hermes 每个 tick 都会完整构建 agent、把 prompt 喂给 LLM——即使订阅源这 5 分钟根本没变化,你也在为一个“什么也没发生”的结果付费。
monitor-mode 的思路是把变化检测从 agent 里剥离出来:每个 tick 先用一个廉价脚本(或一次限时 GET 请求)拿到监控源的输出,按原始字节做哈希:
- 哈希没变 → 整个 agent 运行被抑制,记为一次静默的
no_changetick(不产生 LLM 调用、不投递任何消息); - 哈希变了 → 一段
MONITOR CHANGE DETECTED块(截断的 unified diff + 新输出)被注入 prompt,agent 正常运行; - 首次 tick 总是运行(建立 baseline);
- 监控源本身失败 → 视为配置错误,任务不会偷偷静默。
用法
CLI 创建:
# 用脚本做监控源(放在 ~/.hermes/scripts/ 下,或给绝对路径)
hermes cron create "every 5m" \
"Summarize any new items on the page" \
--monitor-script feed_watch.sh
# 用 URL 做监控源(每次 tick 一次限时 GET)
hermes cron create "every 5m" \
"Summarize changes on the status page" \
--monitor-url https://status.example.com/api/health
# 修改已有任务
hermes cron edit <job_id> --monitor-script feeds.sh
聊天内用 cronjob 工具创建:
cronjob(
action="create",
schedule="every 5m",
prompt="Summarize any new items on the page",
monitor_script="feed_watch.sh",
)
三条约束(源码里写死,违反会在创建时直接报错)
monitor_script与monitor_url互斥,一个任务只能有一个监控源;- monitor 模式与
no_agent=True不兼容——监控的意义就是“抑制或唤醒 agent”,纯脚本任务请用普通script模式; - 监控脚本应输出稳定内容(不要带时间戳),否则每次哈希都会变,等于每次都触发。
另外注意 --monitor-script 的解析规则与 script 一致:相对于 ~/.hermes/scripts/ 解析,.sh/.bash 用 bash 执行,其余按 Python 执行。已发布版之外,这部分实现在 cron/jobs.py 的 create_job 与调度器的 hash-suppression 逻辑中。
2. notepad:跨运行存状态,告别外挂文件
为什么需要它
状态型定时任务有个经典痛点:任务 A 每天凌晨抓一次数据,任务 B 每天早上处理“新增部分”——那“上次处理到哪条”这个游标存在哪?以前只能写到本地文件,还得自己处理并发和清理。notepad 把这个场景变成了一等公民:每个任务一块持久的 key/value 便签,存在独立的 SQLite 里(~/.hermes/cron/notepad.db),每次运行前由调度器渲染进任务 prompt——agent 能看到上次留下的状态,并在本次运行中通过 CLI 更新它。
用法
# 查看任务便签(默认 list)
hermes cron notepad <job_id>
# 读一个键
hermes cron notepad <job_id> get cursor
# 写一个键
hermes cron notepad <job_id> set cursor 128
# 删除一个键
hermes cron notepad <job_id> delete cursor
配合 monitor-mode 的典型用法:监控任务在检测到变化后,把“已处理到哪条”写进 notepad,下次 tick 就知道从哪里继续。容量上限(写入超限会大声失败而非静默截断):
- 单值 16 KB;
- 键名最长 128 字符;
- 每个任务总计 64 KB。
notepad 的读取路径与 context_from 输出在同一处注入 prompt,写入路径则是运行中的 agent 通过 hermes cron notepad ... set 完成——实现细节在 cron/notepad.py,连接/pragma 模式与 cron/executions.py 保持一致。
3. preflight:坏配置一次警告,绝不烧 token
为什么需要它
cron 任务最常见的翻车方式不是代码写错,而是环境悄悄变了:provider 的 API key 过期了、附加的 skill 缺了个环境变量、投递平台的凭据失效了。旧行为是——tick 照跑,agent 建起来,LLM 调完才发现跑不通,钱花了,错误还往往看不明白。
preflight 在构建任何 agent 机制之前先验证任务配置,校验内容(源码与文档 cron.md 确认):
- provider API key 能解析(配置了
fallback_providers链则跳过,因为降级路径可能救回缺失的主 key); - 附加的 skill 就绪(没有缺失的必需环境变量、命令或凭据文件);
- 投递平台目标已知且有 gateway 凭据(
local/origin目标从不检查)。
校验失败的后果:
- 任务
last_status变为blocked_config; - 只投递一次警告(
preflight_alerted去重标记,不会每个 tick 都轰炸你),恢复健康后标记清除,下次再坏会再次警告; - 零 LLM 调用——误配置的任务永远不会烧 token。
默认开启,cron.preflight: true。想关掉恢复旧行为:
# config.yaml
cron:
preflight: false
# 或命令行
hermes config set cron.preflight false
所有检查fail open——preflight 本身出问题不会拦住任务运行,宁可多跑一次也不误杀正常任务。
4. usage_audit:cron token 花费账本
同一批合入的还有 token 泄露治理的一部分:cron 会话不再派发后台 review(skip_background_review 标志),并新增了每次调度运行的 token 花费审计日志 ~/.hermes/cron/usage_audit.jsonl,逐行 JSONL 记录每次 fire 的 token 用量——想量化“monitor-mode 到底帮我省了多少 token”,看这个文件就一目了然。
5. 组合示例:一个省钱的“变化感知”监控任务
把三件套串起来,一个典型的“网站变化监控 + 增量摘要”任务长这样:
# 1) 监控源脚本:输出稳定内容(例如订阅源条目的标题列表)
cat > ~/.hermes/scripts/feed_watch.sh <<'EOF'
#!/bin/bash
curl -s https://example.com/feed.xml | grep -o '<title>[^<]*</title>'
EOF
chmod +x ~/.hermes/scripts/feed_watch.sh
# 2) 创建监控任务:哈希不变就静默跳过
hermes cron create "every 5m" \
"Summarize new feed items and remember the last seen count in the notepad" \
--monitor-script feed_watch.sh \
--deliver telegram
此后:feed 没变 → no_change 静默 tick,零 token;feed 变了 → agent 醒来,读 notepad 里的游标,总结新增条目,更新游标,投递到 Telegram。预算敏感用户还能配合 usage_audit.jsonl 核对每月实际开销。
6. 什么时候不该用
- 必须每次运行的任务(比如整点报时、心跳保活)不需要 monitor-mode——它只会引入无谓的“变化判断”;
- 需要跨任务共享状态时,notepad 不是答案——它是 per-job 的,任务间传数据仍用
context_from链或外部存储; - 想完全跳过 agent 的纯脚本任务,用现成的
no_agent=True+script,不要硬套 monitor 模式。
小结
这三件套让 cron 从“定时烧钱机”变成了“按需唤醒器”:monitor-mode 负责省(无变化零开销),notepad 负责记(状态跨运行存活),preflight 负责稳(坏配置不烧钱、一次警告)。对跑着大量定时任务的开发者来说,这是实打实的账单优化和运维减负。
想从零搭建一套 cron 自动化,可先看我们此前的 Hermes Agent 定时任务完全指南;把任务挂进长时后台不卡死的配置技巧见 让 Hermes 长任务不再卡死的配置指南;更多日常提效技巧汇总在 Hermes Agent 效率技巧合集。还没装 Hermes?安装指南 五分钟上手。