Automations 的运行方式

Automations 的运行方式

Gateway 调度器如何运行一个任务、两次运行之间保留什么、一个重复请求如何变成存储的调度计划。本文是定时任务指南的一部分。

运行模型

  • 自动化运行在 Gateway 进程内,不在模型内。Gateway 必须在运行,计划才会触发。
  • 任务定义、运行时状态与运行历史持久化在 OpenClaw 的共享 SQLite 状态数据库中,重启不会丢失计划。
  • 自动化运行记录在 cron 运行历史中。
  • 立即运行(run-now)请求在入队时完成授权。若它面向发起请求的对话,则在当前回合结束后启动,使用任务当前的调度权限;启动前移除或禁用任务仍会停止它。跳过的运行与智能体执行前的失败会向所属对话追加一条包含原因与下一步的通知。
  • 仅渠道的配置重载不会影响无关的计划运行。执行前的相关策略变更可以把同一出现重新准入至多两次(短退避+新权限);取消、任务或来源权限被撤销、以及可能已执行过 provider/工具/投递/hook 工作的运行不会被该策略重放。已注册的 bootstrap 钩子即使随后被跳过也保守地计为可能的工作。
  • 主会话系统事件走普通会话准入,并保持运行直到该回合完全落定。被接管前重启会记录一次 interrupted 失败——既不报告成功,也不重放提醒。
  • 运行中的自动化可以通过其作用域内的自动化工具移除自己并完成最终回复;从另一个回合移除或禁用、或按停止键,仍会取消活动运行。显式禁用已暂停的任务也会取消手动强制的运行;无关编辑不影响该运行。
  • 智能体、命令与脚本任务把结果写入接收它的聊天或主题一次(包括没有创建对话的任务)。配置了不同投递目的地时结果发给该目的地;无外部路由时发给创建对话。执行上下文保持分离。见投递相关说明与官方 delivery 子页。
  • 一次性任务(--at)在成功完成后自动删除:投递"已确认、非请求、有意抑制或显式 best-effort"均算成功。失败或结果未知的必需投递会保留任务(禁用状态)供检查而不重放负载。传 --keep-after-run 可连成功任务一起保留。
  • 单次运行的运行时预算:设了 --timeout-seconds 用它;否则隔离/分离的 agent-turn 任务由调度器自身的 60 分钟看门狗限定,命令任务默认 10 分钟,脚本负载默认 5 分钟。该调度器时限独立于单次模型尝试预算(agents.defaults.timeoutSeconds,默认 48 小时)——启动 fallback 不会重置它。准备、执行与投递都计入该时限,包括从未报告 runner 启动的停滞。对会话或执行通道容量的显式等待会暂停预算;准入后继续剩余时间。
  • Gateway 启动时,需要智能体执行的过期任务会被重新调度而不是立即重放,使模型/工具执行不阻塞调度器启动(包括迁移来的 monitor 与主会话系统事件)。启动补跑延迟在标签或负载内容对账以及再次重启后仍保留;更改调度计划则开始新的调度决策。
  • 其智能体仍在准备中的任务保持排队而不阻塞健康的智能体;其 Gateway 准备完成后恢复。
  • 执行前被延迟的定时任务保留其待处理出现,30 秒后重试,延迟翻倍上限 5 分钟。等待不占用运行槽位、不改变上一次运行的结果。任务状态记录原因、等待开始时间、尝试次数与下次重试;五次延迟后 Automations 页显示警告。重试替换该次事件的未启动回执而不是追加跳过回执。重启保留等待;完成、取消或调度变更清除它。
  • 一次成功或跳过的计划运行期间经过的 cron 槽位不会在重启时重放;该运行结束后错过的槽位仍可补跑。强制运行仍保留其计划出现。
  • 正常调度器 tick 上,即使存储的下次运行时间在未来,cron 任务也能恢复错过的槽位(除非启用 cron.skipMissedJobs)。该恢复不会在存储期限前唤醒原本空闲的调度器。
  • 运行中的 Gateway 在期限后醒来时,cron worker 用其存储的期限与运行请求合并错过的定时器 tick。worker 拥有调度、队列容量与持久结果;Gateway 启动已提交的请求并在关机时加入 worker。
  • 若你用系统 cron 或其他外部调度器驱动 openclaw agent,即使 CLI 已处理 SIGTERM/SIGINT,也请包一层硬杀升级:Gateway 支持的运行会请求 Gateway 中止已接受的运行,--local 运行收到同一中止信号。GNU timeout 建议 timeout -k 60 600 openclaw agent ... 而非裸 timeout 600 ...(-k 值是进程无法及时排空时的兜底);systemd 单元用 SIGTERM 停止信号加宽限期(TimeoutStopSec)再最终 kill。原 Gateway 运行仍活跃时复用 --run-id 会把重复报告为 in-flight 而不是启动第二次运行。

隔离运行加固

  • 计划运行拥有从准入到结果持久化与清理的独立执行生命周期。定时器 tick、启动补跑与事件源观察器不继承创建/更新它们的对话的请求状态。手动运行请求经持久入队要求当前调用者权限;被接受的运行在任务的调度权限与最终资格检查下启动。
  • 隔离运行在完成时尽力关闭其 cron:<jobId> 会话跟踪的浏览器标签/进程,并经与主会话/自定义会话运行相同的共享清理路径处置为该任务创建的捆绑 MCP 运行时实例。清理失败被忽略,运行结果优先。
  • 运行的延续会话在后代子代理仍在运行或其完成投递待定期间保持可用(包括保留清理期间),清理不会搁浅它们的结果。
  • 持有窄作用域自动化自清理授权的隔离运行可读取调度器状态、只含自己任务的自过滤列表与该任务的运行历史,且只能移除自己的任务。
  • 隔离运行防护过期确认回复:若首个结果只是中间状态更新(“在做了”、“正在汇总"等暗示)且没有后代子代理仍对最终答案负责,OpenClaw 会在投递前再提示一次以取得实际结果。运行总计包含两次完成的提示、按各自模型计价;会话上下文用量仍反映最终模型请求。
  • 结构化执行拒绝元数据(含嵌套错误以 SYSTEM_RUN_DENIED 或 INVALID_REQUEST 开头的 node-host UNAVAILABLE 包装)会被识别——被阻止的命令不会报告为绿色运行,普通助手措辞也不会被误判为拒绝。
  • 运行级智能体失败即使没有回复负载也计为任务错误:模型/provider 失败递增错误计数并触发失败通知,而不是把任务清为成功。
  • 任务命中 timeoutSeconds 时调度器中止运行并给短清理窗口;未排空则 Gateway 侧清理强制清除该运行的会话所有权后再记录超时,排队聊天不会卡在过期的处理会话后。
  • 必需的预检内存检查点与压缩计为活跃工作而非停滞的 runner 准备,占用同一单次运行墙钟时限。
  • 准备/启动停滞获得阶段特定超时(如 cron: isolated agent setup timed out before runner start、cron: isolated agent run stalled before execution start (last phase: context-engine))。这些看门狗覆盖嵌入式与 CLI 支持的 provider(甚至在其外部 CLI 进程启动前),并独立于较长的 timeoutSeconds 值设上限,使冷启动/认证/上下文失败快速暴露。

运行对账

Cron 拥有自己运行的恢复与历史;空的客户端进程不能证明 Gateway 运行已停止。

cron worker 把执行与主投递结果连同任务状态与历史一起记录;运行后通知在其后发生,通知失败不能撤销已记录的结果。

重启恢复把已记录的终态结果匹配到确切运行身份并恢复它——不再运行负载或投递。没有已记录终态结果时,活动运行变为 interrupted 且投递 Unknown。启用、未变更、时间调度的 agent-turn 任务在投递前被打断会获得一次全新重试(一次性任务同样)。重试恢复当前任务权限并要求智能体先对账先前工作再继续;任意被打断的工具效果不保证恰好一次。可能已投递、命令/脚本负载、事件或进程退出调度的运行不会被自动重放——手动重试前先检查其历史与接收者。早期手动运行即使启动前等过了期限也保留其独立的计划出现;被打断的手动运行仍算失败且不重试。单独重调度的一次性任务保留其新出现。

周期任务的重启重试保留既有错误退避下限,其保存的下次运行时间包含该延迟;打断不增加失败连击。一次性任务的重启重试保留其短重触发延迟。

排队的定时请求可在重启后恢复;负载瞬时丢失的排队手动或事件请求记录 skipped 结果而不是重构负载。补跑限制与延迟仍为过期调度限速。带 deleteAfterRun 的终态结果仅在完成为 succeeded 时删除任务。

若已完成运行的历史已保存但任务更新失败,之后被确认的调度或节奏编辑会经恢复保留其下次检查。恢复保留已完成的历史并结清旧运行而不再次执行其负载;保存未变更的调度不改变该已完成运行的恢复方式。

被打断的运行在历史中显示为失败;同一打断再次恢复不会新增历史条目。

把重复任务晋升为自动化

多数自动化应该从智能体已经做过的工作开始。当你几次要求 substantially 相同的工作时,智能体会主动提议把它变成计划,而不是只再跑一次。晋升优于从零建任务:提案继承一次你已经读过的运行——在它按计划到来之前,你就知道输出长什么样。

这里没有重复检测引擎,也没有新的存储历史。智能体从对话本身识别重复,并在提议新任务前先用 automations(action: "list") 检查既有任务,避免重复创建已有例程。当自动化工具可用时提示词包含此指引,并告诉智能体仅在其当前动作含 list、add、run、remove 时提议晋升;只读恢复等受限工具变体不支持此流程。这是模型指引——工具策略与审批仍然管辖实际动作。

确认前,智能体会用平实的话复述计划与任务,例如:“每个工作日 07:00(Europe/Vienna),我汇总隔夜更新并发到这里。“你要确认的是这句话,不是 cron 表达式。

确认后智能体:

  1. 创建任务,投递默认发到你提问的对话:其渠道与线程;无外部路由时是一次对话 commit。
  2. 立即以 run 的 force 模式跑一次作为可见测试,投递到同一对话——在首次计划出现前你就看到真实输出。
  3. 测试失败则移除任务并告知你。

任务以启用状态创建(而非"禁用待批准”)——这是有意的安全选择。调度器监督启用的任务:失败会触发失败通知,反复错误后自动禁用并记录原因、通知 owner。没有任何东西监督禁用的任务——一个等待永不到来确认而禁用的任务对所有守卫不可见、从默认 automations list 隐藏、永远不会触发也不会解释自己:这种静默无结果比一个会运行并可见抱怨的任务更糟。

你的确认仍然把守创建,不会有任何东西在你背后被调度;测试运行是带真实投递的真实运行而非渲染预览——你批准的就是计划将产出的。

译注:本页对应官方文档 How automations work,按官方仓库固定提交 bf26a4c(2026-11-06 检出)逐节核对;正式发布前字段与行为应以官方最新文档复核。