定时任务
使用自然语言或 cron 表达式自动调度任务。Hermes 通过统一的 cronjob 工具暴露 cron 管理,使用 action 风格操作而非独立的 schedule/list/remove 工具。
Cron 能做什么
Section titled “Cron 能做什么”定时任务可以:
- 调度一次性或循环任务
- 暂停、恢复、编辑、触发和移除任务
- 为任务附加零个、一个或多个技能
- 将结果投递回原始聊天、本地文件或配置的平台目标
- 在全新的 Agent 会话中以正常静态工具列表运行
- 在无 Agent 模式下运行——定时运行的脚本,其 stdout 原样投递,零 LLM 参与(见下方无 Agent 模式)
所有这些功能都通过 cronjob 工具对 Hermes 本身可用,因此你可以用自然语言创建、暂停、编辑和移除任务——无需 CLI。
创建定时任务
Section titled “创建定时任务”在聊天中使用 /cron
Section titled “在聊天中使用 /cron”/cron add 30m "提醒我检查构建"/cron add "every 2h" "检查服务器状态"/cron add "every 1h" "总结新的订阅内容" --skill blogwatcher/cron add "every 1h" "使用两个技能并合并结果" --skill blogwatcher --skill maps从独立 CLI
Section titled “从独立 CLI”hermes cron create "every 2h" "Check server status"hermes cron create "every 1h" "Summarize new feed items" --skill blogwatcherhermes cron create "every 1h" "Use both skills and combine the result" \ --skill blogwatcher \ --skill maps \ --name "Skill combo"通过自然对话
Section titled “通过自然对话”直接对 Hermes 说:
每天早上9点,检查 Hacker News 上的 AI 新闻并在 Telegram 上给我发摘要。
Hermes 会在内部使用统一的 cronjob 工具。
技能支持的 Cron 任务
Section titled “技能支持的 Cron 任务”Cron 任务可以在运行提示之前加载一个或多个技能。
cronjob( action="create", skill="blogwatcher", prompt="Check the configured feeds and summarize anything new.", schedule="0 9 * * *", name="Morning feeds",)技能按顺序加载。提示成为叠加在这些技能之上的任务指令。
cronjob( action="create", skills=["blogwatcher", "maps"], prompt="Look for new local events and interesting nearby places, then combine them into one short brief.", schedule="every 6h", name="Local brief",)当你希望定时 Agent 继承可复用的工作流,而无需将完整技能文本塞入 cron 提示时,这很有用。
在项目目录中运行任务
Section titled “在项目目录中运行任务”Cron 任务默认与任何仓库脱离运行——不加载 AGENTS.md、CLAUDE.md 或 .cursorrules,terminal/file/code-exec 工具从网关启动的任何工作目录运行。传递 --workdir(CLI)或 workdir=(工具调用)来改变这一点:
# 独立 CLIhermes cron create "every 1d at 09:00" \ "Audit open PRs, summarize CI health, and post to #eng" \ --workdir /home/me/projects/acme# 从聊天中,通过 cronjob 工具cronjob( action="create", schedule="every 1d at 09:00", workdir="/home/me/projects/acme", prompt="Audit open PRs, summarize CI health, and post to #eng",)设置 workdir 后:
- 该目录中的 AGENTS.md、CLAUDE.md 和 .cursorrules 注入系统提示
- terminal、read_file、write_file、patch、search_files 和 execute_code 都使用该目录作为工作目录
- 路径必须是已存在的绝对目录——相对路径和缺失目录在创建/更新时被拒绝
在指定 Profile 中运行 Cron 任务
Section titled “在指定 Profile 中运行 Cron 任务”默认情况下,cron 任务继承创建它的 Hermes profile。传递 --profile <name>(CLI)或 profile=(cronjob 工具)将任务重定向到不同的 profile——调度器解析该 profile 的 HERMES_HOME,在运行期间临时切换到其中,加载其 .env + config.yaml 并在那里执行任务:
hermes cron create "every 1d at 03:00" \ "Tail the security log and flag anomalies" \ --profile night-ops使用 --profile default 显式指定根 Hermes profile。命名 profile 必须已存在;调度器拒绝即时创建 profile。要清除 profile 绑定,传递空字符串(--profile "" 或 profile="")。
你不需要删除并重建任务来修改它们。
任务引用:<job_id> 占位符(以及生命周期操作中)也接受任务的名称(不区分大小写)——当你记住 morning-digest 而不是十六进制 ID 时很方便。精确的 job ID 优先于名称匹配;如果引用不是 ID 且名称匹配多个任务,命令会拒绝并打印候选 ID 供你消歧。
/cron edit <job_id> --schedule "every 4h"/cron edit <job_id> --prompt "Use the revised task"/cron edit <job_id> --skill blogwatcher --skill maps/cron edit <job_id> --remove-skill blogwatcher/cron edit <job_id> --clear-skills独立 CLI
Section titled “独立 CLI”hermes cron edit <job_id> --schedule "every 4h"hermes cron edit <job_id> --prompt "Use the revised task"hermes cron edit <job_id> --skill blogwatcher --skill mapshermes cron edit <job_id> --add-skill mapshermes cron edit <job_id> --remove-skill blogwatcherhermes cron edit <job_id> --clear-skills注意:
- 重复的
--skill替换任务的附加技能列表 --add-skill追加到现有列表而不替换--remove-skill移除特定附加技能--clear-skills移除所有附加技能
生命周期管理
Section titled “生命周期管理”Cron 任务现在拥有比仅创建/移除更完整的生命周期。
/cron list/cron pause <job_id>/cron resume <job_id>/cron run <job_id>/cron remove <job_id>独立 CLI
Section titled “独立 CLI”hermes cron listhermes cron pause <job_id_or_name>hermes cron resume <job_id_or_name>hermes cron run <job_id_or_name>hermes cron remove <job_id_or_name>hermes cron edit <job_id_or_name> [...flags]hermes cron statushermes cron tick操作说明:
- pause — 保留任务但停止调度
- resume — 重新启用任务并计算下次运行时间
- run — 在下次调度器滴答时触发任务
- remove — 完全删除
- edit — 修改调度、提示、profile、投递等
Cron 执行由网关守护进程处理。网关每 60 秒滴答调度器,在隔离的 Agent 会话中运行所有到期任务。
hermes gateway install # 安装为用户服务sudo hermes gateway install --system # Linux: 启动时系统服务(服务器用)hermes gateway # 或在前台运行
hermes cron listhermes cron status网关调度器行为
Section titled “网关调度器行为”每次滴答时 Hermes:
- 从
~/.hermes/cron/jobs.json加载任务 - 检查
next_run_at是否在当前时间之前 - 为每个到期任务启动全新的 AIAgent 会话
- 可选地将一个或多个附加技能注入到新会话中
- 运行提示直到完成
- 投递最终响应
- 更新运行元数据和下次调度时间
~/.hermes/cron/.tick.lock 处的文件锁防止重叠的调度器滴答重复运行同一批任务。
调度任务时,你指定输出去向:
| 选项 | 说明 | 示例 |
|---|---|---|
"origin" | 回到任务创建处 | 消息平台上的默认值 |
"local" | 仅保存到本地文件 | CLI 上的默认值 |
"telegram" | Telegram 主频道 | 使用 TELEGRAM_HOME_CHANNEL |
"telegram:123456" | 按 ID 指定 Telegram 聊天 | 直接投递 |
"telegram:-100123:17585" | 指定 Telegram 话题 | chat_id:thread_id 格式 |
"discord" | Discord 主频道 | 使用 DISCORD_HOME_CHANNEL |
"discord:#engineering" | 按名称指定 Discord 频道 | 按频道名称 |
"slack" | Slack 主频道 | |
"whatsapp" | WhatsApp 主页 | |
"signal" | Signal | |
"matrix" | Matrix 主房间 | |
"email" | 邮件 | |
"sms" | 通过 Twilio 的 SMS | |
"dingtalk" | 钉钉 | |
"feishu" | 飞书/Lark | |
"wecom" | 企业微信 | |
"weixin" | 微信 | |
"all" | 扇出到所有已连接的主频道 | 在触发时解析 |
"telegram,discord" | 扇出到特定频道集合 | 逗号分隔列表 |
"origin,all" | 投递到原始位置加所有其他连接频道 | 组合任意标记 |
Agent 的最终响应会自动投递。你不需要在 cron 提示中调用 send_message。
如果 Agent 的最终响应以 [SILENT] 开头,投递会被完全抑制。输出仍保存在本地用于审计(在 ~/.hermes/cron/output/ 中),但不会向投递目标发送任何消息。
这对监控任务很有用——只在出问题时才报告:
Check if nginx is running. If everything is healthy, respond with only [SILENT]. Otherwise, report the issue.
失败的任务无论是否有 [SILENT] 标记都会投递——只有成功运行可以被静默。
预运行脚本(通过 script 参数附加)默认超时为 120 秒。如果你的脚本需要更长时间,可以增加:
cron: script_timeout_seconds: 300 # 5 分钟或设置 HERMES_CRON_SCRIPT_TIMEOUT 环境变量。解析顺序为:环境变量 → config.yaml → 120 秒默认。
无 Agent 模式(脚本专用任务)
Section titled “无 Agent 模式(脚本专用任务)”对于不需要 LLM 推理的循环任务——经典看门狗、磁盘/内存告警、心跳、CI Ping——在创建时传递 no_agent=True。调度器按时运行你的脚本并直接投递其 stdout,完全跳过 Agent:
hermes cron create "every 5m" \ --no-agent \ --script memory-watchdog.sh \ --deliver telegram \ --name "memory-watchdog"语义:
- 脚本 stdout(修剪后)→ 原样投递为消息
- 空 stdout → 静默滴答,不投递。这就是看门狗模式:“只在出问题时才说话”
- 非零退出或超时 → 投递错误告警,确保看门狗不会静默失败
{"wakeAgent": false}在最后一行 → 静默滴答- 无 Token 消耗、无模型、无提供商回退——任务从不触碰推理层
.sh / .bash 文件在 /bin/bash 下运行;其他文件在当前 Python 解释器下运行。脚本必须存放在 ~/.hermes/scripts/ 中。
Agent 自动为你设置
Section titled “Agent 自动为你设置”cronjob 工具的 schema 直接向 Hermes 暴露 no_agent,所以你可以在聊天中描述一个看门狗,让 Agent 来配置:
每 5 分钟检查一次,如果 RAM 超过 85% 就在 Telegram 通知我。
Hermes 会通过 write_file 将检查脚本写入 ~/.hermes/scripts/,然后调用:
cronjob(action="create", schedule="every 5m", script="memory-watchdog.sh", no_agent=True, deliver="telegram", name="memory-watchdog")当消息内容完全由脚本决定时(看门狗、阈值告警、心跳),它会自动选择 no_agent=True。
上下文链接(context_from)
Section titled “上下文链接(context_from)”Cron 任务在隔离会话中运行,没有之前运行的记忆。但有时一个任务的输出正是下一个任务需要的。context_from 参数自动建立这种连接——任务 B 的提示在运行时将任务 A 的最近输出作为上下文前置。
# 任务 1:收集原始数据cronjob( action="create", prompt="Fetch the top 10 AI/ML stories from Hacker News. Save them to ~/.hermes/data/briefs/raw.md in markdown format with title, URL, and score.", schedule="0 7 * * *", name="AI News Collector",)
# 任务 2:筛选 — 接收任务 1 的输出作为上下文# 从 cronjob(action="list") 获取任务 1 的 IDcronjob( action="create", prompt="Read ~/.hermes/data/briefs/raw.md. Score each story 1–10 for engagement potential and novelty. Output the top 5 to ~/.hermes/data/briefs/ranked.md.", schedule="30 7 * * *", context_from="<job1_id>", name="AI News Triage",)
# 任务 3:发布 — 接收任务 2 的输出作为上下文cronjob( action="create", prompt="Read ~/.hermes/data/briefs/ranked.md. Write 3 tweet drafts (hook + body + hashtags). Deliver to telegram:7976161601.", schedule="0 8 * * *", context_from="<job2_id>", name="AI News Brief",)工作原理:
- 当任务 2 触发时,Hermes 从
~/.hermes/cron/output/{job1_id}/*.md读取任务 1 的最近输出 - 该输出自动前置到任务 2 的提示中
- 任务 2 不需要硬编码”读取这个文件”——它将内容作为上下文接收
- 链条可以是任意长度:任务 1 → 任务 2 → 任务 3 → …
context_from 接受的格式:
| 格式 | 示例 |
|---|---|
| 单个任务 ID(字符串) | context_from="a1b2c3d4" |
| 多个任务 ID(列表) | context_from=["job_a", "job_b"] |
相对延迟(一次性)
Section titled “相对延迟(一次性)”| 表达式 | 含义 |
|---|---|
30m | 30 分钟后运行一次 |
2h | 2 小时后运行一次 |
1d | 1 天后运行一次 |
| 表达式 | 含义 |
|---|---|
every 2h | 每 2 小时 |
every 1d at 09:00 | 每天 9:00 |
0 9 * * * | 标准 cron:每天 9:00 |
0 9 * * 1 | 标准 cron:每周一 9:00 |
Cron 任务继承你配置的后备提供商和凭据池轮换。如果主 API Key 被限速或提供商返回错误,cron Agent 可以:
- 如果你配置了
fallback_providers(或旧的fallback_model),回退到备用提供商 - 轮换到同一提供商凭据池中的下一个凭据
这意味着高频率或在高峰期运行的 cron 任务更有弹性——单个被限速的 Key 不会让整个运行失败。
# 在 ~/.hermes/config.yaml 中cron: wrap_response: false # 投递时不包装响应头尾 script_timeout_seconds: 300 # 脚本超时(秒)