第十章:定时任务与自动化(Cron)
Hermes 不只是"问答"——它内置完整的 cron 调度器 与一组让自动化"既灵活又安全"的工程能力,让你可以用自然语言或标准 cron 表达式安排任意周期 / 一次性任务,并把结果投递到任意平台。本章把 cron 的所有玩法、与技能 / Webhook / Kanban 的协作模式、以及若干"开箱即用"的自动化模板讲清。
10.1 Cron 是什么
Hermes 的 cron 不是简单的"每隔多久跑一条命令"。它的核心抽象是:
一个 cronjob = 一个调度规则 + 一个新的 Agent 会话 + 一组可选技能 + 一个或多个投递目标
每次到点:
- Hermes 创建一个 fresh agent session(独立上下文、独立 task_id);
- 加载该 job 关联的技能(可 0 个或 N 个);
- 按你的 prompt 让 Agent 自由决策;
- 把最终回复(含附件)投递到指定目标:原始对话、Telegram、Discord、Slack、企业微信、飞书、邮件、本地文件等;
- 记录运行历史到
~/.hermes/hermes.db。
⚠ Cron 内部的 Agent 不能再创建 cron 任务——
cronjob工具会被禁用,避免失控的递归调度。
10.2 创建 cron 的三种方式
10.2.1 在 TUI 用 /cron
/cron add 30m "30 分钟后提醒我去检查构建"
/cron add "every 2h" "每 2 小时检查一次服务器状态"
/cron add "every 1h" "总结新的 RSS 内容" --skill blogwatcher
/cron add "0 9 * * *" "每天早 9 点把昨日 Hacker News 顶 5 条发我 Telegram"
/cron list
/cron pause <id>
/cron resume <id>
/cron run <id> # 立即触发一次
/cron edit <id>
/cron remove <id>
10.2.2 用 hermes cron 命令行
hermes cron create "every 2h" "Check server status"
hermes cron create "every 1h" "Summarize new feed items" --skill blogwatcher
hermes cron create "every 1h" "Use both skills" --skill blogwatcher --skill maps --name "Combo job"
hermes cron list
hermes cron pause <id>
hermes cron remove <id>
10.2.3 自然语言驱动
最爽的方式——让 Hermes 自己去理解:
我希望每个工作日早 9:30,你帮我把昨晚的 GitHub PR 评审提醒整理一下,发到我企业微信。
Hermes 会调用 cronjob 工具自动创建 job、绑定技能、设置投递目标。你可以接着说"换成早 9 点"就会改。
10.3 调度表达式
支持以下几类:
- 相对时间:
30m、2h、3d、90s;表示"X 之后跑一次(一次性任务)"。 every表达式:every 1h、every 30m、every 2 days;周期性。- 标准 cron:
0 9 * * *、*/15 * * * *,5 字段(分时日月周)。 - 自然语言:
every workday at 9:30、each Monday morning、weekdays at 18:00,由模型解析后写成 cron。
时区默认跟随系统;可以全局指定:
cron:timezone: Asia/Shanghai
或单 job:/cron add "every day 9:00" --tz Asia/Shanghai "..."。
10.4 把技能挂上 cron
任意 cron job 可以挂 0 / 1 / N 个技能。技能在每次执行前作为 Level-1 注入,效果等同于"用户在那次会话中执行了 /skill-name"。
/cron add "every 1h" "刷一遍我关注的博客并总结" --skill blogwatcher --skill maps
适合:日常巡检、复杂工作流(让模型不用每次都重新"理解"流程)。
10.5 投递目标(Delivery Targets)
每个 job 可以指定结果发到哪。常见目标:
| URI | 含义 |
|---|---|
origin |
原始对话(你创建 job 的会话) |
telegram://<chat_id> |
Telegram 用户 / 群 |
discord://<channel_id> |
Discord 频道 |
slack://<channel> |
Slack |
wecom://group:<name> / wecom://user:<userid> |
企业微信 |
feishu://group:<id> |
飞书 |
dingtalk://group:<id> |
钉钉 |
email://<to@example.com> |
邮件(用 subject: 字段) |
file:///abs/path |
写本地文件 |
webhook://<url> |
POST 到 URL |
console |
仅打印到 Gateway 日志 |
例:
/cron add "every day 9:00" "把昨晚 PR 列表整理成一份 Markdown" \--skill github-pr-workflow \--target email://me@example.com \--target file:///tmp/daily-pr.md
10.6 配置文件中的 cron
也可以纯 YAML:
cron:timezone: Asia/Shanghaijobs:- name: morning-briefschedule: "0 9 * * 1-5"prompt: |请扫一下昨晚(按 Asia/Shanghai 计算)的:- GitHub @myorg 的 open PR- HackerNews 前 5 条 AI 相关- X(Twitter) @AnthropicAI 最新 5 条汇总成 200 字以内的简报,附原文链接。skills:- blogwatcher- github-pr-workflowtoolsets:- web- file- github-mcptargets:- telegram://1234567890- email://me@example.com- file:///home/me/briefs/{{date}}.md
{{date}} 是 Hermes 内置变量,cron 上下文里还能用 {{datetime}}、{{job_name}}、{{run_id}} 等。
10.7 失败重试与降级
cron:retries: 3retry_backoff_seconds: 60on_failure:deliver_to: telegram://12345 # 失败时单独发我skill: incident-summarizer
10.8 与 Webhook 的协作:事件触发 vs 时间触发
第九章介绍过 Webhook。Cron 是时间触发,Webhook 是事件触发——二者经常配合:
gateway:webhooks:- name: github-pr-openedpath: /webhooks/github-prsecret_env: GITHUB_WEBHOOK_SECRETaction:prompt: |PR {{ json.pull_request.number }} 已开启:{{ json.pull_request.title }}.请按 AGENTS.md 评审,给 reviewer 留 3-5 条建议。toolsets: [web, file, github-mcp]deliver_to: slack://eng-reviews
事件层负责"立刻有反应",cron 层负责"批量回顾 / 周期总结"。
10.9 Kanban:复杂多步流的"持久任务板"
delegate_task 适合"父代理同步等结果";cron 适合"我自己定时跑"。当你需要的是 跨多个代理、可恢复、可被人介入、跨数天/周 的工作流时,用 Kanban。
/kanban
hermes kanban create --board ops "本周巡检:pg 慢查询 / nginx 错误率 / 磁盘"
hermes kanban list
hermes kanban claim <task-id> --as reviewer
hermes kanban complete <task-id>
hermes kanban block <task-id> --reason "等 ops 提供 db 凭据"
模型这一侧通过 kanban_* 工具读写:kanban_show、kanban_complete、kanban_block、kanban_heartbeat、kanban_comment、kanban_create、kanban_link。
典型工作流:
- dispatcher profile 把 epic 拆成 task;
- researcher profile 拿一个 task 调研,附上结论;
- writer profile 拿调研稿写成报告;
- reviewer profile 评审,必要时把任务 block 给人;
- 完成后 cron 触发 publisher profile 把成稿发邮件。
每个 profile 都是一个独立 Hermes 进程,共享 ~/.hermes/kanban.db。详见 user-guide/features/kanban.md 与 kanban-tutorial.md。
10.10 自动化模板(开箱即用)
下面给一组日常很有用的模板,照抄即可。
10.10.1 每日早报(个人)
- name: daily-briefschedule: "0 8 * * *"prompt: |给我一份 200 字以内的早报:- 我关注的 GitHub PR/Issue 状态变化- HackerNews / Reddit r/MachineLearning 顶 5 条- 我订阅的 RSS(见 ~/.hermes/feeds.txt)新增 5 条最后用一句话挑出"今天最值得我做的一件事"。skills: [blogwatcher, github-pr-workflow]targets:- telegram://${MY_CHAT_ID}- file:///home/me/briefs/{{date}}.md
10.10.2 PR Review 机器人
Webhook 触发,配合 GitHub MCP:
gateway:webhooks:- name: pr-reviewpath: /webhooks/pr-reviewsecret_env: GITHUB_WEBHOOK_SECRETaction:prompt: |PR #{{ json.pull_request.number }} ({{ json.pull_request.title }}) 在 {{ json.repository.full_name }} 已开启。按仓库根 AGENTS.md 的评审清单进行评审,输出:- 总体结论(approve / request_changes / comment)- 3-7 条具体建议- 任何安全 / 性能 / 可维护性的隐患toolsets: [web, file, github-mcp]deliver_to: slack://eng-reviews
10.10.3 服务器巡检
- name: server-healthschedule: "*/15 * * * *"prompt: |用 ssh 连到 ops.example.com 检查:- df -h(>80% 报警)- 最近 200 条 nginx error.log(异常率 >0.5% 报警)- systemctl is-active myapp一切正常时**不发任何消息**;有异常时给出诊断与建议。toolsets: [terminal, file]targets:- telegram://${OPS_GROUP}
10.10.4 周度知识库整理
- name: weekly-knowledgeschedule: "0 18 * * 5"prompt: |搜索本周(7 天内)我所有会话,挑出 5 条值得长期记住的经验或决定,以"标题 + 100 字摘要"的方式整理;然后调用 memory 工具决定哪些加入 MEMORY.md。toolsets: [session_search, memory, file]targets:- email://me@example.com
10.10.5 定时备份与同步
- name: backup-hermes-homeschedule: "0 3 * * *"prompt: |用 rsync 把 ~/.hermes/{memories,skills,SOUL.md,config.yaml} 同步到 backup-server:/srv/hermes-backup/{{date}}/然后压缩为 tar.zst 并保留最近 14 天。toolsets: [terminal]targets:- file:///var/log/hermes-backup.log
10.10.6 IM 群定时播报
- name: standup-reminderschedule: "30 9 * * 1-5"prompt: |根据 Kanban 板上"今日待办"任务,给团队拼一段 Markdown 播报:- 每个人各自负责的任务(按 Kanban claim 字段)- 是否有 blocker最后 @ 每个有未完成任务的人。toolsets: [kanban, web]targets:- wecom://group:engineering
10.10.7 Web 监控 + 通知
- name: rss-watchschedule: "*/30 * * * *"prompt: |抓取 https://example.com/blog/feed.xml;与上次结果比对,如有新条目,把每条做 100 字总结后发 Telegram。把已知条目 ID 保存在 ~/.hermes/state/rss.json 里,避免重复推送。toolsets: [web, file]targets:- telegram://${MY_CHAT_ID}
10.11 Cron + Skills + Memory 的化学反应
把三件事打通会让 Hermes 真正有"工作员"的感觉:
- Skill 写"做某件事的 SOP";
- Cron 把 SOP 周期化;
- Memory 让每次执行都借鉴上次的教训。
例如"巡检"技能里加一段:
## Pitfalls
- 上次发现 80% 阈值会误报:临时容量峰值。改用"连续 3 次 >80%"再报警。
下一次巡检,这条经验会自然进入决策。运行多了,Memory 还会反馈到 cron prompt 上:"最近一周磁盘没问题,可减少巡检频率到每小时一次"——你只需点头同意。
10.12 安全与配额
cron 与 webhook 是"代理替你 24×7 干活"的入口,安全要点:
-
永远在 Docker / Daytona / Modal 后端跑非可信任务;
-
cron job 启用
--toolsets只挑必要 toolset; -
用
approval.require_confirmation锁住"破坏性操作",让 Agent 撞到时主动 DM 你; -
给每个 job 设 max_runtime_seconds:
cron:defaults:max_runtime_seconds: 600max_iterations: 30 -
给 Provider 设月度预算告警(OpenRouter、Anthropic 都有),cron 跑飞了能及时止损。
10.13 排错
| 症状 | 排查 |
|---|---|
| 到点不跑 | hermes gateway status cron 是否启用;cron.timezone 是否对;hermes cron list --verbose 看 next_run |
| 跑了但什么也没发 | 投递目标没配;gateway logs 看出站日志 |
| 跑两次 | 多个 Hermes profile 共享同一份 cron 文件——切到不同 profile 或加锁 |
| 提示 "cron tool disabled" | 你试图在 cron 内创建 cron——禁用是有意为之 |
| Webhook 401 | secret 校验失败;hash 算法对齐 |
10.14 本章小结
- Cron + Skill + Memory + Webhook + Kanban 五件套构成 Hermes 的"自动化操作系统";
- 自然语言、
every表达式、5 字段 cron、自然语言时间,全支持; - 投递目标可以是任意平台或本地文件;
- Webhook 负责"事件触发",cron 负责"时间触发",Kanban 负责"跨代理、可恢复、长流程";
- 安全上:默认沙箱、按平台收紧 toolset、审批列表、超时与预算上限。
下一章我们打开几扇"高级感"的窗户:语音、视觉、浏览器与子代理协作。
