Skip to content

第十二章 定时任务与自动化

Hermes 内置了 Cron 调度器,允许用户用自然语言定义定时任务——例如"每天早上 9 点总结昨天的新闻",Agent 会按时执行并将结果投递到指定平台。

12.1 Cron 调度器架构

cron/scheduler.py 实现了基于 tick 的调度器:

文件锁机制

python
import fcntl

def acquire_lock():
    """文件锁防止多进程并发执行"""
    lock_file = open(get_hermes_home() / "cron" / ".scheduler.lock", "w")
    fcntl.flock(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)
    return lock_file

为什么用文件锁而不是数据库锁?

  • 调度器可能在多个进程中运行(CLI + Gateway)
  • 文件锁是操作系统级别的,最可靠
  • 简单无依赖

12.2 作业定义与执行

cron/jobs.py 定义了作业的数据结构和执行逻辑:

作业格式

yaml
# ~/.hermes/cron/jobs.yaml
jobs:
  - id: daily-news
    schedule: "0 9 * * *"          # Cron 表达式:每天 9:00
    prompt: "总结昨天最重要的 AI 新闻"
    platform: telegram              # 投递平台
    chat_id: "-1001234567890"       # 投递目标
    timezone: "Asia/Shanghai"       # 时区
    enabled: true

  - id: weekly-audit
    schedule: "0 18 * * 5"          # 每周五 18:00
    prompt: "审查本周代码变更,生成报告"
    platform: slack
    chat_id: "C12345678"
    enabled: true

执行流程

12.3 投递机制

作业执行完成后,结果可以通过多种方式投递:

投递方式说明配置
原始平台回到创建任务的聊天delivery: origin
本地文件保存为文件delivery: local
Home Channel配置的默认频道delivery: home
指定目标明确指定平台和聊天platform + chat_id

Home Channel 配置

yaml
# ~/.hermes/config.yaml
gateway:
  home_channel:
    platform: telegram
    chat_id: "-1001234567890"

通过 /sethome 命令在任意平台设置 Home Channel。

12.4 并发安全

多进程场景

安全保证

  1. 文件锁:同一时刻只有一个进程执行调度
  2. 作业级锁:同一作业不会并发执行(即使跨进程)
  3. 平台验证:执行前检查目标平台是否在线,避免消息丢失
  4. 错误恢复:执行失败不阻塞后续作业,记录错误供排查

作业生命周期

12.5 完整使用示例

创建定时任务

bash
# 在 Hermes 对话中
/cron add "0 9 * * *" "总结昨天最重要的 AI 新闻"

Agent 会自动:

  1. 解析 cron 表达式(每天 9:00)
  2. 记录投递平台和聊天 ID(当前对话)
  3. 写入 ~/.hermes/cron/jobs.yaml

查看已有任务

bash
/cron list

输出示例:

ID            Schedule      Platform   Chat ID         Enabled   Last Run
daily-news    0 9 * * *     telegram   -1001234567890  ✅        2024-04-20 09:00
weekly-audit  0 18 * * 5    slack      C12345678       ✅        2024-04-19 18:00

手动触发

bash
/cron run daily-news

禁用/删除

bash
/cron disable daily-news
/cron remove daily-news

12.6 Cron 表达式速查

格式:分 时 日 月 周

表达式含义
0 9 * * *每天 9:00
*/30 * * * *每 30 分钟
0 18 * * 1-5工作日 18:00
0 0 1 * *每月 1 号零点
0 8,12,18 * * *每天 8:00、12:00、18:00

时区:默认使用系统时区,可通过 timezone 字段覆盖:

yaml
timezone: "Asia/Shanghai"

源码导航

  • 调度器 → cron/scheduler.py
  • 作业定义 → cron/jobs.py
  • Cron 工具 → tools/cronjob_tools.py

下一章:附录 A 源码导航地图

基于 MIT 许可发布