Автоматизация

Cron-задачи

Cron или Heartbeat? См. Cron vs Heartbeat для рекомендаций, когда использовать каждый из них.

Cron — это встроенный планировщик Шлюза. Он сохраняет задания, пробуждает агента в нужное время и может при необходимости доставлять вывод обратно в чат. Если вам нужно «запускать это каждое утро» или «пнуть агента через 20 минут», cron — это механизм для этого. Устранение неполадок: /automation/troubleshooting

Кратко

  • Cron работает внутри Шлюза (а не внутри модели).
  • Задания сохраняются в ~/.openclaw/cron/, поэтому перезапуски не приводят к потере расписаний.
  • Два стиля выполнения:
    • Основная сессия: поставить системное событие в очередь, затем выполнить при следующем сердцебиении.
    • Изолированный: выполнить выделенный ход агента в cron:<jobId>, с доставкой (по умолчанию объявление или без).
  • Пробуждения являются первоклассными: задание может запросить «пробудиться сейчас» или «при следующем сердцебиении».
  • Отправка вебхука настраивается для каждого задания через delivery.mode = "webhook" + delivery.to = "<url>".
  • Устаревший запасной вариант сохраняется для сохранённых заданий с notify: true, когда установлен cron.webhook; перенесите эти задания в режим доставки вебхуком.

Быстрый старт (практично)

Создайте одноразовое напоминание, проверьте его существование и запустите немедленно:

openclaw cron add \
  --name "Reminder" \
  --at "2026-02-01T16:00:00Z" \
  --session main \
  --system-event "Reminder: check the cron docs draft" \
  --wake now \
  --delete-after-run

openclaw cron list
openclaw cron run <job-id>
openclaw cron runs --id <job-id>

Запланируйте повторяющееся изолированное задание с доставкой:

openclaw cron add \
  --name "Morning brief" \
  --cron "0 7 * * *" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Summarize overnight updates." \
  --announce \
  --channel slack \
  --to "channel:C1234567890"

Эквиваленты вызова инструментов (инструмент cron Шлюза)

Для канонических JSON-структур и примеров см. JSON-схема для вызовов инструментов.

Где хранятся cron-задания

Cron-задания по умолчанию сохраняются на хосте Шлюза в ~/.openclaw/cron/jobs.json. Шлюз загружает файл в память и записывает его обратно при изменениях, поэтому ручное редактирование безопасно только при остановленном Шлюзе. Предпочитайте openclaw cron add/edit или API вызова инструмента cron для изменений.

Обзор для начинающих

Представьте cron-задание как: когда запускать + что делать.

  1. Выберите расписание
    • Одноразовое напоминание → schedule.kind = "at" (CLI: --at)
    • Повторяющееся задание → schedule.kind = "every" или schedule.kind = "cron"
    • Если ваша временная метка ISO не содержит часового пояса, она обрабатывается как UTC.
  2. Выберите, где оно выполняется
    • sessionTarget: "main" → выполнить во время следующего сердцебиения с основным контекстом.
    • sessionTarget: "isolated" → выполнить выделенный ход агента в cron:<jobId>.
  3. Выберите полезную нагрузку
    • Основная сессия → payload.kind = "systemEvent"
    • Изолированная сессия → payload.kind = "agentTurn"

Опционально: одноразовые задания (schedule.kind = "at") по умолчанию удаляются после успешного выполнения. Установите deleteAfterRun: false, чтобы сохранить их (они отключатся после успеха).

Концепции

Задания

Cron-задание — это сохранённая запись с:

  • расписанием (когда оно должно выполняться),
  • полезной нагрузкой (что оно должно делать),
  • опциональным режимом доставки (announce, webhook или none).
  • опциональной привязкой к агенту (agentId): выполнить задание под определённым агентом; если отсутствует или неизвестен, шлюз возвращается к агенту по умолчанию.

Задания идентифицируются стабильным jobId (используется CLI/API Шлюза). В вызовах инструментов агента jobId является каноническим; устаревший id принимается для совместимости. Одноразовые задания по умолчанию автоматически удаляются после успеха; установите deleteAfterRun: false, чтобы сохранить их.

Расписания

Cron поддерживает три вида расписаний:

  • at: одноразовая временная метка через schedule.at (ISO 8601).
  • every: фиксированный интервал (мс).
  • cron: 5-полевое cron-выражение (или 6-полевое с секундами) с опциональным часовым поясом IANA.

Cron-выражения используют croner. Если часовой пояс опущен, используется локальный часовой пояс хоста Шлюза. Чтобы уменьшить пиковые нагрузки в начале часа на многих шлюзах, OpenClaw применяет детерминированное окно смещения до 5 минут для повторяющихся выражений начала часа (например, 0 * * * *, 0 */2 * * *). Выражения с фиксированным часом, такие как 0 7 * * *, остаются точными. Для любого cron-расписания вы можете установить явное окно смещения с помощью schedule.staggerMs (0 сохраняет точное время). Сокращения CLI:

  • --stagger 30s (или 1m, 5m) для установки явного окна смещения.
  • --exact для принудительной установки staggerMs = 0.

Основное vs изолированное выполнение

Задания основной сессии (системные события)

Основные задания ставят системное событие в очередь и опционально пробуждают исполнитель сердцебиения. Они должны использовать payload.kind = "systemEvent".

  • wakeMode: "now" (по умолчанию): событие запускает немедленное выполнение сердцебиения.
  • wakeMode: "next-heartbeat": событие ждёт следующего запланированного сердцебиения.

Это лучший вариант, когда вам нужен обычный промпт сердцебиения + контекст основной сессии. См. Heartbeat.

Изолированные задания (выделенные cron-сессии)

Изолированные задания выполняют выделенный ход агента в сессии cron:<jobId>. Ключевые особенности:

  • Промпт имеет префикс [cron:<jobId> <job name>] для отслеживаемости.
  • Каждый запуск начинается с нового идентификатора сессии (без переноса предыдущего разговора).
  • Поведение по умолчанию: если delivery опущен, изолированные задания объявляют сводку (delivery.mode = "announce").
  • delivery.mode выбирает, что происходит:
    • announce: доставить сводку в целевой канал и опубликовать краткую сводку в основной сессии.
    • webhook: отправить POST полезной нагрузки завершённого события в delivery.to, когда завершённое событие включает сводку.
    • none: только внутреннее (без доставки, без сводки в основной сессии).
  • wakeMode контролирует, когда публикуется сводка в основной сессии:
    • now: немедленное сердцебиение.
    • next-heartbeat: ждёт следующего запланированного сердцебиения.

Используйте изолированные задания для шумных, частых или «фоновых задач», которые не должны засорять историю основного чата.

Формы полезной нагрузки (что выполняется)

Поддерживаются два вида полезной нагрузки:

  • systemEvent: только основная сессия, направляется через промпт сердцебиения.
  • agentTurn: только изолированная сессия, выполняет выделенный ход агента.

Общие поля agentTurn:

  • message: обязательный текстовый промпт.
  • model / thinking: опциональные переопределения (см. ниже).
  • timeoutSeconds: опциональное переопределение таймаута.
  • lightContext: опциональный облегчённый режим начальной загрузки для заданий, которым не требуется инъекция файлов начальной загрузки рабочей области.

Конфигурация доставки:

  • delivery.mode: none | announce | webhook.
  • delivery.channel: last или конкретный канал.
  • delivery.to: целевой объект, специфичный для канала (объявление) или URL вебхука (режим вебхука).
  • delivery.bestEffort: избегать сбоя задания, если доставка объявления не удалась.

Доставка объявления подавляет отправку инструментов сообщений для запуска; используйте delivery.channel/delivery.to для нацеливания на чат. Когда delivery.mode = "none", сводка не публикуется в основной сессии. Если delivery опущен для изолированных заданий, OpenClaw по умолчанию использует announce.

Поток доставки объявления

Когда delivery.mode = "announce", cron доставляет напрямую через адаптеры исходящих каналов. Основной агент не запускается для создания или пересылки сообщения. Детали поведения:

  • Содержимое: доставка использует исходящие полезные нагрузки (текст/медиа) изолированного запуска с обычным разбиением на части и форматированием канала.
  • Ответы только для сердцебиения (HEARTBEAT_OK без реального содержимого) не доставляются.
  • Если изолированный запуск уже отправил сообщение в ту же цель через инструмент сообщения, доставка пропускается, чтобы избежать дублирования.
  • Отсутствующие или недействительные цели доставки приводят к сбою задания, если не установлено delivery.bestEffort = true.
  • Краткая сводка публикуется в основной сессии только когда delivery.mode = "announce".
  • Сводка в основной сессии учитывает wakeMode: now запускает немедленное сердцебиение, а next-heartbeat ждёт следующего запланированного сердцебиения.

Поток доставки вебхука

Когда delivery.mode = "webhook", cron отправляет полезную нагрузку завершённого события в delivery.to, когда завершённое событие включает сводку. Детали поведения:

  • Конечная точка должна быть действительным HTTP(S) URL.
  • В режиме вебхука не предпринимается попытка доставки в канал.
  • В режиме вебхука сводка в основной сессии не публикуется.
  • Если установлен cron.webhookToken, заголовок авторизации: Authorization: Bearer <cron.webhookToken>.
  • Устаревший запасной вариант: сохранённые устаревшие задания с notify: true всё ещё отправляют в cron.webhook (если настроен), с предупреждением, чтобы вы могли перенести их в delivery.mode = "webhook".

Переопределения модели и мышления

Изолированные задания (agentTurn) могут переопределять модель и уровень мышления:

  • model: Строка провайдер/модель (например, anthropic/claude-sonnet-4-20250514) или псевдоним (например, opus)
  • thinking: Уровень мышления (off, minimal, low, medium, high, xhigh; только для моделей GPT-5.2 + Codex)

Примечание: Вы можете установить model и для заданий основной сессии, но это изменит общую модель основной сессии. Мы рекомендуем переопределения модели только для изолированных заданий, чтобы избежать неожиданных сдвигов контекста. Приоритет разрешения:

  1. Переопределение в полезной нагрузке задания (наивысший)
  2. Значения по умолчанию для конкретного хука (например, hooks.gmail.model)
  3. Значение по умолчанию конфигурации агента

Облегчённый контекст начальной загрузки

Изолированные задания (agentTurn) могут установить lightContext: true для запуска с облегчённым контекстом начальной загрузки.

  • Используйте это для запланированных задач, которым не требуется инъекция файлов начальной загрузки рабочей области.
  • На практике встроенная среда выполнения работает с bootstrapContextMode: "lightweight", что намеренно оставляет контекст начальной загрузки cron пустым.
  • Эквиваленты CLI: openclaw cron add --light-context ... и openclaw cron edit --light-context.

Доставка (канал + цель)

Изолированные задания могут доставлять вывод в канал через конфигурацию верхнего уровня delivery:

  • delivery.mode: announce (доставка в канал), webhook (HTTP POST) или none.
  • delivery.channel: whatsapp / telegram / discord / slack / mattermost (плагин) / signal / imessage / last.
  • delivery.to: целевой получатель, специфичный для канала.

Доставка announce действительна только для изолированных заданий (sessionTarget: "isolated"). Доставка webhook действительна как для основных, так и для изолированных заданий. Если delivery.channel или delivery.to опущены, cron может вернуться к «последнему маршруту» основной сессии (последнее место, где ответил агент). Напоминания о формате цели:

  • Цели Slack/Discord/Mattermost (плагин) должны использовать явные префиксы (например, channel:<id>, user:<id>), чтобы избежать неоднозначности.
  • Темы Telegram должны использовать форму :topic: (см. ниже).

Цели доставки Telegram (темы / форумные треды)

Telegram поддерживает темы форума через message_thread_id. Для доставки cron вы можете закодировать тему/тред в поле to:

  • -1001234567890 (только идентификатор чата)
  • -1001234567890:topic:123 (предпочтительно: явный маркер темы)
  • -1001234567890:123 (сокращённо: числовой суффикс)

Цели с префиксами, такие как telegram:... / telegram:group:..., также принимаются:

  • telegram:group:-1001234567890:topic:123

JSON-схема для вызовов инструментов

Используйте эти структуры при прямом вызове инструментов Шлюза cron.* (вызовы инструментов агента или RPC). Флаги CLI принимают человекочитаемые длительности, такие как 20m, но вызовы инструментов должны использовать строку ISO 8601 для schedule.at и миллисекунды для schedule.everyMs.

Параметры cron.add

Одноразовое задание основной сессии (системное событие):

{
  "name": "Reminder",
  "schedule": { "kind": "at", "at": "2026-02-01T16:00:00Z" },
  "sessionTarget": "main",
  "wakeMode": "now",
  "payload": { "kind": "systemEvent", "text": "Reminder text" },
  "deleteAfterRun": true
}

Повторяющееся изолированное задание с доставкой:

{
  "name": "Morning brief",
  "schedule": { "kind": "cron", "expr": "0 7 * * *", "tz": "America/Los_Angeles" },
  "sessionTarget": "isolated",
  "wakeMode": "next-heartbeat",
  "payload": {
    "kind": "agentTurn",
    "message": "Summarize overnight updates.",
    "lightContext": true
  },
  "delivery": {
    "mode": "announce",
    "channel": "slack",
    "to": "channel:C1234567890",
    "bestEffort": true
  }
}

Примечания:

  • schedule.kind: at (at), every (everyMs) или cron (expr, опционально tz).
  • schedule.at принимает ISO 8601 (часовой пояс опционален; обрабатывается как UTC при опускании).
  • everyMs — это миллисекунды.
  • sessionTarget должен быть "main" или "isolated" и должен соответствовать payload.kind.
  • Опциональные поля: agentId, description, enabled, deleteAfterRun (по умолчанию true для at), delivery.
  • wakeMode по умолчанию "now" при опускании.

Параметры cron.update

{
  "jobId": "job-123",
  "patch": {
    "enabled": false,
    "schedule": { "kind": "every", "everyMs": 3600000 }
  }
}

Примечания:

  • jobId является каноническим; id принимается для совместимости.
  • Используйте agentId: null в патче, чтобы очистить привязку к агенту.

Параметры cron.run и cron.remove

{ "jobId": "job-123", "mode": "force" }
{ "jobId": "job-123" }

Хранилище и история

  • Хранилище заданий: ~/.openclaw/cron/jobs.json (JSON, управляемый Шлюзом).
  • История запусков: ~/.openclaw/cron/runs/<jobId>.jsonl (JSONL, автоматически очищается по размеру и количеству строк).
  • Сессии изолированных cron-запусков в sessions.json очищаются по cron.sessionRetention (по умолчанию 24h; установите false для отключения).
  • Переопределить путь к хранилищу: cron.store в конфигурации.

Политика повторных попыток

Когда задание завершается с ошибкой, OpenClaw классифицирует ошибки как временные (повторяемые) или постоянные (отключаемые немедленно).

Временные ошибки (повторяются)

  • Ограничение скорости (429, слишком много запросов, ресурсы исчерпаны)
  • Перегрузка провайдера (например, Anthropic 529 overloaded_error, сводки при перегрузке)
  • Сетевые ошибки (таймаут, ECONNRESET, сбой fetch, сокет)
  • Ошибки сервера (5xx)
  • Ошибки, связанные с Cloudflare

Постоянные ошибки (без повторных попыток)

  • Ошибки аутентификации (неверный ключ API, неавторизован)
  • Ошибки конфигурации или валидации
  • Другие нетранзиентные ошибки

Поведение по умолчанию (без конфигурации)

Одноразовые задания (schedule.kind: "at"):

  • При временной ошибке: повторять до 3 раз с экспоненциальной задержкой (30с → 1м → 5м).
  • При постоянной ошибке: отключить немедленно.
  • При успехе или пропуске: отключить (или удалить, если deleteAfterRun: true).

Повторяющиеся задания (cron / every):

  • При любой ошибке: применить экспоненциальную задержку (30с → 1м → 5м → 15м → 60м) перед следующим запланированным запуском.
  • Задание остаётся включённым; задержка сбрасывается после следующего успешного запуска.

Настройте cron.retry, чтобы переопределить эти значения по умолчанию (см. Конфигурация).

Конфигурация

{
  cron: {
    enabled: true, // по умолчанию true
    store: "~/.openclaw/cron/jobs.json",
    maxConcurrentRuns: 1, // по умолчанию 1
    // Опционально: переопределить политику повторных попыток для одноразовых заданий
    retry: {
      maxAttempts: 3,
      backoffMs: [60000, 120000, 300000],
      retryOn: ["rate_limit", "overloaded", "network", "server_error"],
    },
    webhook: "https://example.invalid/legacy", // устаревший запасной вариант для сохранённых заданий с notify:true
    webhookToken: "replace-with-dedicated-webhook-token", // опциональный токен Bearer для режима вебхука
    sessionRetention: "24h", // строка длительности или false
    runLog: {
      maxBytes: "2mb", // по умолчанию 2_000_000 байт
      keepLines: 2000, // по умолчанию 2000
    },
  },
}

Поведение очистки журнала запусков:

  • cron.runLog.maxBytes: максимальный размер файла журнала запусков перед очисткой.
  • cron.runLog.keepLines: при очистке сохранять только новейшие N строк.
  • Оба применяются к файлам cron/runs/<jobId>.jsonl.

Поведение вебхука:

  • Предпочтительно: установите delivery.mode: "webhook" с delivery.to: "https://..." для каждого задания.
  • URL вебхуков должны быть действительными http:// или https:// URL.
  • При отправке полезная нагрузка представляет собой JSON события завершения cron.
  • Если установлен cron.webhookToken, заголовок авторизации: Authorization: Bearer <cron.webhookToken>.
  • Если cron.webhookToken не установлен, заголовок Authorization не отправляется.
  • Устаревший запасной вариант: сохранённые устаревшие задания с notify: true всё ещё используют cron.webhook, если он присутствует.

Полностью отключить cron:

  • cron.enabled: false (конфигурация)
  • OPENCLAW_SKIP_CRON=1 (env)

Обслуживание

Cron имеет два встроенных пути обслуживания: хранение сессий изолированных запусков и очистка журналов запусков.

Значения по умолчанию

  • cron.sessionRetention: 24h (установите false для отключения очистки сессий запусков)
  • cron.runLog.maxBytes: 2_000_000 байт
  • cron.runLog.keepLines: 2000

Как это работает

  • Изолированные запуски создают записи сессий (...:cron:<jobId>:run:<uuid>) и файлы транскриптов.
  • Очиститель удаляет устаревшие записи сессий запусков старше cron.sessionRetention.
  • Для удалённых сессий запусков, на которые больше нет ссылок в хранилище сессий, OpenClaw архивирует файлы транскриптов и очищает старые удалённые архивы в том же окне хранения.
  • После каждого добавления запуска проверяется размер cron/runs/<jobId>.jsonl:
    • если размер файла превышает runLog.maxBytes, он обрезается до новейших runLog.keepLines строк.

Предостережения о производительности для планировщиков с высокой нагрузкой

Настройки cron с высокой частотой могут создавать большие объёмы сессий запусков и журналов. Обслуживание встроено, но свободные ограничения всё равно могут создавать ненужную нагрузку на ввод-вывод и работу по очистке. На что обратить внимание:

  • длинные окна cron.sessionRetention с большим количеством изолированных запусков
  • высокие значения cron.runLog.keepLines в сочетании с большими runLog.maxBytes
  • много шумных повторяющихся заданий, пишущих в один и тот же cron/runs/<jobId>.jsonl

Что делать:

  • сохраняйте cron.sessionRetention как можно короче, насколько позволяют ваши потребности в отладке/аудите
  • ограничивайте журналы запусков умеренными значениями runLog.maxBytes и runLog.keepLines
  • перемещайте шумные фоновые задания в изолированный режим с правилами доставки, которые избегают ненужной болтовни
  • периодически проверяйте рост с помощью openclaw cron runs и настраивайте хранение до того, как журналы станут большими

Примеры настройки

Хранить сессии запусков неделю и разрешить большие журналы запусков:

{
  cron: {
    sessionRetention: "7d",
    runLog: {
      maxBytes: "10mb",
      keepLines: 5000,
    },
  },
}

Отключить очистку сессий изолированных запусков, но оставить очистку журналов запусков:

{
  cron: {
    sessionRetention: false,
    runLog: {
      maxBytes: "5mb",
      keepLines: 3000,
    },
  },
}

Настройка для использования cron с высокой нагрузкой (пример):

{
  cron: {
    sessionRetention: "12h",
    runLog: {
      maxBytes: "3mb",
      keepLines: 1500,
    },
  },
}

Быстрый старт CLI

Одноразовое напоминание (UTC ISO, автоматическое удаление после успеха):

openclaw cron add \
  --name "Send reminder" \
  --at "2026-01-12T18:00:00Z" \
  --session main \
  --system-event "Reminder: submit expense report." \
  --wake now \
  --delete-after-run

Одноразовое напоминание (основная сессия, пробуждение немедленно):

openclaw cron add \
  --name "Calendar check" \
  --at "20m" \
  --session main \
  --system-event "Next heartbeat: check calendar." \
  --wake now

Повторяющееся изолированное задание (объявление в WhatsApp):

openclaw cron add \
  --name "Morning status" \
  --cron "0 7 * * *" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Summarize inbox + calendar for today." \
  --announce \
  --channel whatsapp \
  --to "+15551234567"

Повторяющееся cron-задание с явным смещением в 30 секунд:

openclaw cron add \
  --name "Minute watcher" \
  --cron "0 * * * * *" \
  --tz "UTC" \
  --stagger 30s \
  --session isolated \
  --message "Run minute watcher checks." \
  --announce

Повторяющееся изолированное задание (доставка в тему Telegram):

openclaw cron add \
  --name "Nightly summary (topic)" \
  --cron "0 22 * * *" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Summarize today; send to the nightly topic." \
  --announce \
  --channel telegram \
  --to "-1001234567890:topic:123"

Изолированное задание с переопределением модели и мышления:

openclaw cron add \
  --name "Deep analysis" \
  --cron "0 6 * * 1" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Weekly deep analysis of project progress." \
  --model "opus" \
  --thinking high \
  --announce \
  --channel whatsapp \
  --to "+15551234567"

Выбор агента (многоагентные настройки):

# Закрепить задание за агентом "ops" (возвращается к умолчанию, если этот агент отсутствует)
openclaw cron add --name "Ops sweep" --cron "0 6 * * *" --session isolated --message "Check ops queue" --agent ops

# Переключить или очистить агента у существующего задания
openclaw cron edit <jobId> --agent ops
openclaw cron edit <jobId> --clear-agent

Ручной запуск (force — по умолчанию, используйте --due для запуска только когда пришло время):

openclaw cron run <jobId>
openclaw cron run <jobId> --due

Редактирование существующего задания (патч полей):

openclaw cron edit <jobId> \
  --message "Updated prompt" \
  --model "opus" \
  --thinking low

Принудить существующее cron-задание к запуску точно по расписанию (без смещения):

openclaw cron edit <jobId> --exact

История запусков:

openclaw cron runs --id <jobId> --limit 50

Немедленное системное событие без создания задания:

openclaw system event --mode now --text "Next heartbeat: check battery."

Поверхность API Шлюза

  • cron.list, cron.status, cron.add, cron.update, cron.remove
  • cron.run (force или due), cron.runs Для немедленных системных событий без задания используйте openclaw system event.

Устранение неполадок

«Ничего не запускается»

  • Проверьте, включён ли cron: cron.enabled и OPENCLAW_SKIP_CRON.
  • Проверьте, что Шлюз работает непрерывно (cron работает внутри процесса Шлюза).
  • Для расписаний cron: подтвердите часовой пояс (--tz) по сравнению с часовым поясом хоста.

Повторяющееся задание продолжает задерживаться после сбоев

  • OpenClaw применяет экспоненциальную задержку повторных попыток для повторяющихся заданий после последовательных ошибок: 30с, 1м, 5м, 15м, затем 60м между попытками.
  • Задержка автоматически сбрасывается после следующего успешного запуска.
  • Одноразовые (at) задания повторяют временные ошибки (ограничение скорости, перегрузка, сеть, server_error) до 3 раз с задержкой; постоянные ошибки от