Hermes 101|12|Cron

Cron 把 Agent 接到时间轴上:schedule 决定何时醒来,script 和 context_from 决定醒来前看到什么。

Hermes 101|12|Cron

普通 Agent 是被动的:用户发消息,它才开始工作。Cron 改变了这个关系。它让 Agent 能按时间醒来,主动检查、总结、提醒或发布结果。

Hermes Cron 不是系统 crontab 的薄包装,而是一套接入 Agent Runtime 的计划任务系统。

Hermes Cron 的一次 tick

读完本文,你应该能回答

  • Cron job 为什么应该启动新的 Agent session?
  • script gate、no-agent 模式和 context_from 分别适合什么场景?
  • 定时任务如何避免递归调度、上下文污染和无意义打扰?
  • mini-agent-harness 如何把 Agent 接到时间轴上?

本篇在系列中的位置

Gateway 让 Agent 响应外部消息,本篇让 Agent 按时间自动醒来。它把 Runtime 从交互式系统推进到持续运行系统;下一篇 Delegation 会讨论一个任务如何拆给多个隔离子 Agent。

贯穿案例

贯穿这个系列,可以一直带着同一个任务来读:用户说“帮我修复这个 repo 里的 failing tests”。不同章节会回答同一个任务在运行时的不同问题:入口怎样进入、上下文怎样准备、模型怎样决定下一步、工具怎样执行、状态怎样保存、失败后怎样恢复。

定义

Hermes Cron 是由 Gateway 驱动的计划任务运行时。它持久化 job,按 schedule tick,执行 script 或新的 Agent session,并通过 delivery router 投递结果。

一个 Cron job 至少包含三件事:什么时候运行、运行什么、结果送到哪里。对应到字段就是 scheduleprompt/script/no_agentdeliver

新 Agent Session

默认模式下,每次 Cron run 都会启动一个新的 Agent session。它不继承当前聊天历史,也不自动继承上一次 run 的临时上下文。所以 Cron prompt 必须自包含。

这是一个重要边界。计划任务不能依赖“我刚才说过什么”,因为它可能在几小时后、几天后、无人在线时运行。

Script Gate

Cron 可以先运行脚本。脚本 stdout 会被注入 prompt,让 Agent 基于实时数据做总结或判断。

如果脚本最后一行输出 {"wakeAgent": false},Hermes 会跳过本轮 Agent 调用。这适合轮询类任务:只有发现变化时才唤醒模型。

No-Agent 模式

Hermes Cron 还有一个很工程化的分支:no_agent=True

Agent Cron 与 No-Agent Cron

No-agent 模式不启动 LLM,脚本就是任务本身。stdout 非空就原样投递;stdout 为空就静默;脚本失败或 timeout 则发送错误告警,避免 watchdog 坏掉却无人知道。

这让 Cron 既能做 AI 总结,也能做传统监控。

Cron 模式选择表

Cron 最容易写错的地方,是不区分“要不要 Agent 思考”。

场景 推荐模式 原因
每天总结 RSS / 博客 Agent job 需要筛选、归纳、重写
磁盘空间低于阈值才提醒 no_agent + script 判断逻辑固定,没必要消耗模型
先抓数据,再由 Agent 分析 script + Agent prompt script 做采集,Agent 做解释
A job 的结果喂给 B job context_from 保持 job 解耦,避免同一 prompt 过重
在某个 repo 里定期检查 workdir 让 job 自动加载项目上下文

如果一个任务输出格式固定、没有推理需求,就不要启动 Agent;如果任务需要判断什么重要、如何表达给人,就应该让 Agent 参与。

context_from

Cron job 之间可以显式串联。B 的 context_from 指向 A,B 运行时会读取 A 最近一次完成输出,并放到自己的 prompt 前。

这比“让 Agent 自己记住上次结果”更可靠,因为数据流是显式的:collect、filter、summarize、deliver 可以拆成多个独立 job。

workdir

当 job 设置 workdir,Hermes 会在对应项目目录运行,并加载项目上下文文件。终端、文件、代码执行工具也会以该目录为工作目录。

这让 Cron 可以成为项目级自动化:每天跑一次报告、监控仓库状态、定期检查接口、生成 changelog,而不是只能做全局提醒。

可迁移伪实现:Cron

下面的伪代码是机制抽象,不对应 Hermes 的真实 API 或文件结构。最小版本可以这样设计:

type Job = {
  id: string
  schedule: Schedule
  nextRunAt: Date
  prompt?: string
  script?: string
  noAgent?: boolean
  deliver: "local" | "console"
  contextFrom?: string[]
}

async function tick() {
  const due = store.jobsDueNow()
  for (const job of due) {
    store.advanceNextRun(job)
    const result = await runJob(job)
    store.saveOutput(job.id, result)
    if (result.shouldDeliver) delivery.send(job.deliver, result.message)
  }
}

async function runJob(job: Job) {
  if (job.noAgent) return runScriptOnly(job.script!)
  const scriptOutput = job.script ? await runScript(job.script) : ""
  const upstream = await loadContextFrom(job.contextFrom ?? [])
  return agent.run([scriptOutput, upstream, job.prompt].join("\n\n"))
}

第一版不需要支持所有平台。先把 schedule、job store、script-only、Agent run、delivery 五个边界做清楚。

小结

Cron 的核心不是“定时调用模型”,而是把 Agent Runtime 接到时间轴上。Schedule 决定何时醒来,script 和 context_from 决定醒来前看到什么,Agent 或 no-agent 决定怎样执行,delivery 决定结果送到哪里。

参考资料