Gateway
Heartbeat
Heartbeat запускает периодические ходы агента в основной сессии, чтобы модель могла показать все, что требует внимания, не засыпая вас сообщениями.
Heartbeat — это запланированный ход основной сессии, он не создает записи фоновой задачи. Записи задач предназначены для отделенной работы (запуски ACP, субагенты, изолированные задания cron).
Устранение неполадок: Запланированные задачи
Быстрый старт (для начинающих)
Выберите интервал
Оставьте heartbeats включенными (по умолчанию 30m, или 1h для Anthropic OAuth/аутентификации по токену, включая повторное использование Claude CLI) либо задайте собственный интервал.
Добавьте HEARTBEAT.md (необязательно)
Создайте короткий контрольный список HEARTBEAT.md или блок tasks: в рабочей области агента.
Решите, куда должны отправляться сообщения heartbeat
target: "none" используется по умолчанию; задайте target: "last", чтобы направлять их последнему контакту.
Необязательная настройка
- Включите доставку рассуждений heartbeat для прозрачности.
- Используйте облегченный начальный контекст, если запускам heartbeat нужен только
HEARTBEAT.md. - Включите изолированные сессии, чтобы не отправлять полную историю разговора при каждом heartbeat.
- Ограничьте heartbeats активными часами (локальное время).
Пример конфигурации:
{ agents: { defaults: { heartbeat: { every: "30m", target: "last", // explicit delivery to last contact (default is "none") directPolicy: "allow", // default: allow direct/DM targets; set "block" to suppress lightContext: true, // optional: only inject HEARTBEAT.md from bootstrap files isolatedSession: true, // optional: fresh session each run (no conversation history) skipWhenBusy: true, // optional: also defer when this agent's subagent or nested lanes are busy // activeHours: { start: "08:00", end: "24:00" }, // includeReasoning: true, // optional: send separate `Thinking` message too }, }, },}Значения по умолчанию
- Интервал:
30m(или1h, когда обнаруженным режимом аутентификации является Anthropic OAuth/аутентификация по токену, включая повторное использование Claude CLI). Задайтеagents.defaults.heartbeat.everyилиagents.list[].heartbeat.everyдля отдельного агента; используйте0m, чтобы отключить. - Тело промпта (настраивается через
agents.defaults.heartbeat.prompt):Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK. - Тайм-аут: ходы heartbeat без явного значения используют
agents.defaults.timeoutSeconds, если он задан. Иначе они используют интервал heartbeat с ограничением в 600 секунд. Задайтеagents.defaults.heartbeat.timeoutSecondsилиagents.list[].heartbeat.timeoutSecondsдля отдельного агента, если heartbeat должен выполняться дольше. - Промпт heartbeat отправляется дословно как сообщение пользователя. Системный промпт включает раздел "Heartbeat" только когда heartbeats включены для агента по умолчанию, а запуск помечается внутренне.
- Когда heartbeats отключены с помощью
0m, обычные запуски также исключаютHEARTBEAT.mdиз начального контекста, чтобы модель не видела инструкции, предназначенные только для heartbeat. - Активные часы (
heartbeat.activeHours) проверяются в настроенном часовом поясе. За пределами окна heartbeats пропускаются до следующего тика внутри окна. - Heartbeats автоматически откладываются, пока работа cron активна или стоит в очереди. Задайте
heartbeat.skipWhenBusy: true, чтобы также откладывать агента при наличии его собственных субагентов с ключом сессии или вложенных командных линий; соседние агенты больше не приостанавливаются только потому, что у другого агента выполняется работа субагента.
Для чего нужен промпт heartbeat
Промпт по умолчанию намеренно широкий:
- Фоновые задачи: "Consider outstanding tasks" побуждает агента просмотреть последующие действия (входящие, календарь, напоминания, работу в очереди) и показать все срочное.
- Проверка человека: "Checkup sometimes on your human during day time" побуждает иногда отправлять легкое сообщение "что-нибудь нужно?", но избегает ночного спама благодаря вашему настроенному локальному часовому поясу (см. Часовой пояс).
Heartbeat может реагировать на завершенные фоновые задачи, но сам запуск heartbeat не создает запись задачи.
Если вы хотите, чтобы heartbeat выполнял что-то очень конкретное (например, "check Gmail PubSub stats" или "verify gateway health"), задайте agents.defaults.heartbeat.prompt (или agents.list[].heartbeat.prompt) с пользовательским телом (отправляется дословно).
Контракт ответа
- Если ничего не требует внимания, ответьте
HEARTBEAT_OK. - Запуски heartbeat с доступом к инструментам могут вместо этого вызвать
heartbeat_respondсnotify: false, чтобы не показывать обновление, илиnotify: trueплюсnotificationTextдля оповещения. Если структурированный ответ инструмента присутствует, он имеет приоритет над текстовым запасным вариантом. - Во время запусков heartbeat OpenClaw воспринимает
HEARTBEAT_OKкак подтверждение, когда он находится в начале или конце ответа. Токен удаляется, а ответ отбрасывается, если оставшееся содержимое имеет размер ≤ackMaxChars(по умолчанию 300). - Если
HEARTBEAT_OKнаходится в середине ответа, он не обрабатывается особым образом. - Для оповещений не включайте
HEARTBEAT_OK; возвращайте только текст оповещения.
Вне heartbeats случайный HEARTBEAT_OK в начале/конце сообщения удаляется и журналируется; сообщение, состоящее только из HEARTBEAT_OK, отбрасывается.
Конфигурация
{ agents: { defaults: { heartbeat: { every: "30m", // default: 30m (0m disables) model: "anthropic/claude-opus-4-6", includeReasoning: false, // default: false (deliver separate Thinking message when available) lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files isolatedSession: false, // default: false; true runs each heartbeat in a fresh session (no conversation history) skipWhenBusy: false, // default: false; true also waits for this agent's subagent/nested lanes target: "last", // default: none | options: last | none | <channel id> (core or plugin, e.g. "imessage") to: "+15551234567", // optional channel-specific override accountId: "ops-bot", // optional multi-account channel id prompt: "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.", ackMaxChars: 300, // max chars allowed after HEARTBEAT_OK }, }, },}Область действия и приоритет
agents.defaults.heartbeatзадает глобальное поведение Heartbeat.agents.list[].heartbeatобъединяется поверх; если у какого-либо агента есть блокheartbeat, Heartbeat выполняют только эти агенты.channels.defaults.heartbeatзадает параметры видимости по умолчанию для всех каналов.channels.<channel>.heartbeatпереопределяет параметры канала по умолчанию.channels.<channel>.accounts.<id>.heartbeat(каналы с несколькими аккаунтами) переопределяет настройки для каждого канала.
Heartbeat для отдельных агентов
Если какая-либо запись agents.list[] включает блок heartbeat, Heartbeat выполняют только эти агенты. Блок отдельного агента объединяется поверх agents.defaults.heartbeat (поэтому можно один раз задать общие значения по умолчанию и переопределять их для каждого агента).
Пример: два агента, Heartbeat выполняет только второй агент.
{ agents: { defaults: { heartbeat: { every: "30m", target: "last", // explicit delivery to last contact (default is "none") }, }, list: [ { id: "main", default: true }, { id: "ops", heartbeat: { every: "1h", target: "whatsapp", to: "+15551234567", timeoutSeconds: 45, prompt: "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.", }, }, ], },}Пример активных часов
Ограничьте Heartbeat рабочими часами в определенном часовом поясе:
{ agents: { defaults: { heartbeat: { every: "30m", target: "last", // explicit delivery to last contact (default is "none") activeHours: { start: "09:00", end: "22:00", timezone: "America/New_York", // optional; uses your userTimezone if set, otherwise host tz }, }, }, },}Вне этого окна (до 9:00 или после 22:00 по восточному времени) Heartbeat пропускается. Следующий запланированный тик внутри окна выполнится как обычно.
Настройка 24/7
Если нужно, чтобы Heartbeat выполнялся весь день, используйте один из этих вариантов:
- Полностью опустите
activeHours(без ограничения временным окном; это поведение по умолчанию). - Задайте окно на весь день:
activeHours: { start: "00:00", end: "24:00" }.
Пример с несколькими аккаунтами
Используйте accountId, чтобы выбрать конкретный аккаунт в каналах с несколькими аккаунтами, таких как Telegram:
{ agents: { list: [ { id: "ops", heartbeat: { every: "1h", target: "telegram", to: "12345678:topic:42", // optional: route to a specific topic/thread accountId: "ops-bot", }, }, ], }, channels: { telegram: { accounts: { "ops-bot": { botToken: "YOUR_TELEGRAM_BOT_TOKEN" }, }, }, },}Примечания к полям
everystringИнтервал Heartbeat (строка длительности; единица по умолчанию = минуты).
modelstringНеобязательное переопределение модели для запусков Heartbeat (provider/model).
includeReasoningbooleandefault: falseЕсли включено, также доставляет отдельное сообщение Thinking, когда оно доступно (та же форма, что и у /reasoning on).
lightContextbooleandefault: falseЕсли true, запуски Heartbeat используют облегченный начальный контекст и сохраняют только HEARTBEAT.md из файлов начальной загрузки рабочей области.
isolatedSessionbooleandefault: falseЕсли true, каждый Heartbeat выполняется в новом сеансе без предыдущей истории разговора. Использует тот же шаблон изоляции, что и cron sessionTarget: "isolated". Значительно снижает стоимость токенов для каждого Heartbeat. Сочетайте с lightContext: true для максимальной экономии. Маршрутизация доставки по-прежнему использует контекст основного сеанса.
skipWhenBusybooleandefault: falseЕсли true, запуски Heartbeat откладываются на дополнительных занятых линиях этого агента: его собственном подагенте с ключом сеанса или вложенной командной работе. Линии Cron всегда откладывают Heartbeat даже без этого флага, поэтому хосты с локальными моделями не запускают подсказки Cron и Heartbeat одновременно.
sessionstringНеобязательный ключ сеанса для запусков Heartbeat.
main(по умолчанию): основной сеанс агента.- Явный ключ сеанса (скопируйте из
openclaw sessions --jsonили из CLI сеансов). - Форматы ключей сеансов: см. Сеансы и Группы.
targetstringlast: доставить в последний использованный внешний канал.- явный канал: любой настроенный канал или id Plugin, например
discord,matrix,telegramилиwhatsapp. none(по умолчанию): выполнить Heartbeat, но не доставлять наружу.
directPolicy"allow" | "block"default: allowУправляет поведением доставки напрямую/в личные сообщения. allow: разрешить доставку Heartbeat напрямую/в личные сообщения. block: подавить доставку напрямую/в личные сообщения (reason=dm-blocked).
tostringНеобязательное переопределение получателя (id, зависящий от канала, например E.164 для WhatsApp или id чата Telegram). Для тем/веток Telegram используйте <chatId>:topic:<messageThreadId>.
accountIdstringНеобязательный идентификатор учетной записи для каналов с несколькими учетными записями. Когда target: "last", идентификатор учетной записи применяется к определенному последнему каналу, если он поддерживает учетные записи; иначе он игнорируется. Если идентификатор учетной записи не соответствует настроенной учетной записи для определенного канала, доставка пропускается.
promptstringПереопределяет тело промпта по умолчанию (не объединяется).
ackMaxCharsnumberdefault: 300Максимальное число символов, допустимое после HEARTBEAT_OK перед доставкой.
suppressToolErrorWarningsbooleanЕсли true, подавляет предупреждающие payload-данные об ошибках инструментов во время запусков Heartbeat.
timeoutSecondsnumberdefault: global timeout or min(every, 600)Максимальное число секунд, допустимое для хода агента Heartbeat до его прерывания. Оставьте неустановленным, чтобы использовать agents.defaults.timeoutSeconds, если он задан; иначе будет использоваться частота Heartbeat, ограниченная 600 секундами.
activeHoursobjectОграничивает запуски Heartbeat временным окном. Объект с start (HH:MM, включительно; используйте 00:00 для начала дня), end (HH:MM, не включительно; 24:00 разрешено для конца дня) и необязательным timezone.
- Пропущено или
"user": использует вашagents.defaults.userTimezone, если он задан, иначе откатывается к часовому поясу системы хоста. "local": всегда использует часовой пояс системы хоста.- Любой идентификатор IANA (например,
America/New_York): используется напрямую; если он недействителен, откатывается к поведению"user", описанному выше. startиendне должны быть равны для активного окна; равные значения считаются окном нулевой ширины (всегда вне окна).- Вне активного окна Heartbeat пропускается до следующего тика внутри окна.
Поведение доставки
Маршрутизация сеанса и цели
- Heartbeat по умолчанию запускается в основном сеансе агента (
agent:<id>:<mainKey>) или вglobal, когдаsession.scope = "global". Задайтеsession, чтобы переопределить его конкретным сеансом канала (Discord/WhatsApp/и т. д.). sessionвлияет только на контекст запуска; доставка управляется черезtargetиto.- Чтобы доставить в конкретный канал/получателю, задайте
target+to. Приtarget: "last"доставка использует последний внешний канал для этого сеанса. - Доставки Heartbeat по умолчанию разрешают прямые/DM-цели. Задайте
directPolicy: "block", чтобы подавить отправки прямым целям, при этом все равно выполняя ход Heartbeat. - Если основная очередь, полоса целевого сеанса, полоса cron или активная задача cron заняты, Heartbeat пропускается и повторяется позже.
- Если
skipWhenBusy: true, привязанный к ключу сеанса субагент этого агента и вложенные полосы также откладывают запуски Heartbeat. Занятые полосы других агентов не откладывают этого агента. - Если
targetне разрешается во внешнее назначение, запуск все равно происходит, но исходящее сообщение не отправляется.
Видимость и поведение пропуска
- Если
showOk,showAlertsиuseIndicatorвсе отключены, запуск заранее пропускается какreason=alerts-disabled. - Если отключена только доставка оповещений, OpenClaw все равно может запустить Heartbeat, обновить временные метки задач с наступившим сроком, восстановить временную метку простоя сеанса и подавить внешний payload оповещения.
- Если определенная цель Heartbeat поддерживает индикацию набора текста, OpenClaw показывает набор текста, пока запуск Heartbeat активен. Используется та же цель, в которую Heartbeat отправил бы вывод чата, и это отключается через
typingMode: "never".
Жизненный цикл сеанса и аудит
- Ответы только от Heartbeat не поддерживают сеанс активным. Метаданные Heartbeat могут обновлять строку сеанса, но истечение по простою использует
lastInteractionAtиз последнего реального сообщения пользователя/канала, а ежедневное истечение используетsessionStartedAt. - История Control UI и WebChat скрывает промпты Heartbeat и подтверждения только с OK. Базовая расшифровка сеанса все равно может содержать эти ходы для аудита/повтора.
- Отсоединенные фоновые задачи могут поставить системное событие в очередь и разбудить Heartbeat, когда основной сеанс должен быстро что-то заметить. Такое пробуждение не делает запуск Heartbeat фоновой задачей.
Элементы управления видимостью
По умолчанию подтверждения HEARTBEAT_OK подавляются, а содержимое оповещений доставляется. Это можно настроить для каждого канала или каждой учетной записи:
channels: defaults: heartbeat: showOk: false # Hide HEARTBEAT_OK (default) showAlerts: true # Show alert messages (default) useIndicator: true # Emit indicator events (default) telegram: heartbeat: showOk: true # Show OK acknowledgments on Telegram whatsapp: accounts: work: heartbeat: showAlerts: false # Suppress alert delivery for this accountПриоритет: для учетной записи → для канала → значения по умолчанию канала → встроенные значения по умолчанию.
Что делает каждый флаг
showOk: отправляет подтверждениеHEARTBEAT_OK, когда модель возвращает ответ только с OK.showAlerts: отправляет содержимое оповещения, когда модель возвращает ответ не с OK.useIndicator: создает события индикатора для поверхностей статуса UI.
Если все три равны false, OpenClaw полностью пропускает запуск Heartbeat (без вызова модели).
Примеры для канала и для учетной записи
channels: defaults: heartbeat: showOk: false showAlerts: true useIndicator: true slack: heartbeat: showOk: true # all Slack accounts accounts: ops: heartbeat: showAlerts: false # suppress alerts for the ops account only telegram: heartbeat: showOk: trueРаспространенные шаблоны
| Цель | Конфигурация |
|---|---|
| Поведение по умолчанию (OK без сообщений, оповещения включены) | (конфигурация не требуется) |
| Полностью безмолвно (без сообщений, без индикатора) | channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: false } |
| Только индикатор (без сообщений) | channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: true } |
| OK только в одном канале | channels.telegram.heartbeat: { showOk: true } |
HEARTBEAT.md (необязательно)
Если в рабочей области существует файл HEARTBEAT.md, промпт по умолчанию говорит агенту прочитать его. Думайте о нем как о своем «чеклисте Heartbeat»: небольшом, стабильном и безопасном для учета каждые 30 минут.
При обычных запусках HEARTBEAT.md внедряется только когда руководство Heartbeat включено для агента по умолчанию. Отключение частоты Heartbeat через 0m или установка includeSystemPromptSection: false исключает его из обычного bootstrap-контекста.
В нативном harness Codex содержимое HEARTBEAT.md не внедряется в ход. Если файл существует и содержит не только пробельные символы, инструкции режима совместной работы Heartbeat указывают Codex на файл и говорят прочитать его перед продолжением.
Если HEARTBEAT.md существует, но фактически пуст (только пустые строки, комментарии Markdown/HTML, заголовки Markdown вроде # Heading, маркеры fence или пустые заготовки чеклиста), OpenClaw пропускает запуск Heartbeat, чтобы сэкономить вызовы API. Такой пропуск сообщается как reason=empty-heartbeat-file. Если файл отсутствует, Heartbeat все равно запускается, и модель решает, что делать.
Держите его крошечным (короткий чеклист или напоминания), чтобы избежать раздувания промпта.
Пример HEARTBEAT.md:
# Heartbeat checklist - Quick scan: anything urgent in inboxes?- If it's daytime, do a lightweight check-in if nothing else is pending.- If a task is blocked, write down _what is missing_ and ask Peter next time.Блоки tasks:
HEARTBEAT.md также поддерживает небольшой структурированный блок tasks: для интервальных проверок внутри самого Heartbeat.
Пример:
tasks: - name: inbox-triage interval: 30m prompt: "Check for urgent unread emails and flag anything time sensitive."- name: calendar-scan interval: 2h prompt: "Check for upcoming meetings that need prep or follow-up." # Additional instructions - Keep alerts short.- If nothing needs attention after all due tasks, reply HEARTBEAT_OK.Поведение
- OpenClaw разбирает блок
tasks:и проверяет каждую задачу по ее собственномуinterval. - В промпт Heartbeat для этого тика включаются только задачи, срок которых наступил.
- Если нет задач с наступившим сроком, Heartbeat полностью пропускается (
reason=no-tasks-due), чтобы избежать лишнего вызова модели. - Содержимое
HEARTBEAT.md, не относящееся к задачам, сохраняется и добавляется как дополнительный контекст после списка задач с наступившим сроком. - Временные метки последнего запуска задач хранятся в состоянии сеанса (
heartbeatTaskState), поэтому интервалы переживают обычные перезапуски. - Временные метки задач продвигаются только после того, как запуск Heartbeat завершит свой обычный путь ответа. Пропущенные запуски
empty-heartbeat-file/no-tasks-dueне помечают задачи как завершенные.
Режим задач полезен, когда вы хотите, чтобы один файл Heartbeat содержал несколько периодических проверок без оплаты всех проверок на каждом тике.
Может ли агент обновлять HEARTBEAT.md?
Да — если вы его попросите.
HEARTBEAT.md — это обычный файл в рабочей области агента, поэтому вы можете сказать агенту (в обычном чате) что-то вроде:
- "Update
HEARTBEAT.mdto add a daily calendar check." - "Rewrite
HEARTBEAT.mdso it's shorter and focused on inbox follow-ups."
Если вы хотите, чтобы это происходило проактивно, можно также включить явную строку в свой промпт Heartbeat, например: "If the checklist becomes stale, update HEARTBEAT.md with a better one."
Ручное пробуждение (по требованию)
Вы можете поставить системное событие в очередь и запустить немедленный Heartbeat с помощью:
openclaw system event --text "Check for urgent follow-ups" --mode nowЕсли heartbeat настроен у нескольких агентов, ручное пробуждение немедленно запускает Heartbeat каждого из этих агентов.
Используйте --mode next-heartbeat, чтобы дождаться следующего запланированного тика.
Доставка рассуждений (необязательно)
По умолчанию Heartbeat доставляет только итоговый payload «ответа».
Если нужна прозрачность, включите:
agents.defaults.heartbeat.includeReasoning: true
Когда это включено, Heartbeat также будет доставлять отдельное сообщение с префиксом Thinking (та же форма, что и /reasoning on). Это может быть полезно, когда агент управляет несколькими сеансами/codexes и вы хотите видеть, почему он решил написать вам, но также может раскрывать больше внутренних деталей, чем вам нужно. В групповых чатах лучше оставлять это отключенным.
Учет стоимости
Heartbeat запускает полные ходы агента. Более короткие интервалы расходуют больше токенов. Чтобы снизить стоимость:
- Используйте
isolatedSession: true, чтобы не отправлять полную историю разговора (~100K токенов уменьшаются до ~2-5K за запуск). - Используйте
lightContext: true, чтобы ограничить bootstrap-файлы толькоHEARTBEAT.md. - Задайте более дешевую
model(например,ollama/llama3.2:1b). - Держите
HEARTBEAT.mdнебольшим. - Используйте
target: "none", если вам нужны только обновления внутреннего состояния.
Переполнение контекста после Heartbeat
Если Heartbeat ранее оставил существующий сеанс на локальной модели меньшего размера, например модели Ollama с окном 32k, а следующий ход основного сеанса сообщает о переполнении контекста, сбросьте runtime-модель сеанса обратно на настроенную основную модель. Сообщение сброса OpenClaw указывает на это, когда последняя runtime-модель совпадает с настроенной heartbeat.model.
Текущие Heartbeat сохраняют существующую runtime-модель общего сеанса после завершения запуска. Вы все равно можете использовать isolatedSession: true, чтобы запускать Heartbeat в новом сеансе, сочетать это с lightContext: true для минимального промпта или выбрать модель Heartbeat с достаточно большим окном контекста для общего сеанса.
Связанные материалы
- Автоматизация — все механизмы автоматизации в кратком обзоре
- Фоновые задачи — как отслеживается отсоединенная работа
- Часовой пояс — как часовой пояс влияет на планирование Heartbeat
- Устранение неполадок — отладка проблем автоматизации