Technical Guide
13. Cron:定时任务怎么保存、触发和投递
从 cron/jobs.py 和 scheduler 看 Hermes 如何管理每日提醒、日报、备份和自动化任务。
这篇解决什么问题
Hermes 不只能被动等你发消息。
Cron 让它可以按时间自动运行:日报、提醒、备份、监控、定时总结,都属于这一类。
这一篇看 Cron 的源码设计。
关键文件
先看:
cron/jobs.py
cron/scheduler.py
cron/scheduler_provider.py
hermes_cli/cron.py
tools/cronjob_tool.py
其中 cron/jobs.py 文件注释写得很清楚:
Jobs are stored in ~/.hermes/cron/jobs.json
Output is saved to ~/.hermes/cron/output/{job_id}/{timestamp}.md
这两个路径是理解 Cron 的入口。
一个 job 里有什么
一个 Hermes cron job 通常包含:
job_id
name
schedule
prompt
skills
deliver
enabled / paused state
next_run_at
last_run_at
last_status
高级一点还可以有:
script
no_agent
workdir
context_from
enabled_toolsets
model override
这意味着 Cron 不是简单 crontab。它可以带 Skill、指定工作目录、限制工具、接上游任务输出。
schedule 支持什么
Hermes 支持多种写法:
30m
every 2h
0 9 * * *
2026-07-01T09:00:00
实际解析和 next_run 计算在 cron 相关代码里处理。
为什么 jobs.json 需要锁
cron/jobs.py 里有文件锁和进程内锁。
原因是:Gateway 里的 scheduler、CLI 手动 pause/resume/run、并发 tick 都可能同时修改 jobs.json。
如果没有锁,一个任务刚被暂停,另一个进程又把旧状态写回去,就会出现“看起来暂停了但还在跑”。
所以 Cron 存储层要比普通 JSON 文件读写谨慎得多。
Cron 执行链路
简化流程:
scheduler tick
→ 读取 jobs.json
→ 找到 due jobs
→ 标记运行状态
→ 创建独立 agent session
→ 注入 prompt / skills / workdir / tools
→ 执行任务
→ 保存 output
→ 投递到 deliver 目标
→ 更新 next_run_at 和 last_status
如果 no_agent=True,脚本输出就是最终消息,不再调用 LLM。
deliver 为什么重要
Cron 任务没人在线等结果。
所以必须知道结果投递到哪里:
origin 当前会话来源
local 只保存本地
all 所有 home channel
具体平台 chat id
你之前的早中晚目标提醒,就是典型 Cron:不需要联网、不需要工具,只需要按时把固定提醒发回当前飞书聊天。
如果 Cron 失败怎么查
先看:
hermes cron list
hermes cron status
再看:
~/.hermes/cron/output/<job_id>/
~/.hermes/logs/
如果是模型 401,通常不是 Cron 本身坏,而是 provider/API key 不可用。
下一篇看什么
下一篇看 Gateway。
Cron 是时间入口,Gateway 是平台入口。它们最终都会把任务送进 Agent。