Fundamentals

Цикл агента

Цикл агента — это сериализованный запуск в рамках отдельного сеанса, который преобразует сообщение в действия и ответ: приём, сборка контекста, инференс модели, выполнение инструментов, потоковая передача, сохранение.

Точки входа

  • RPC Gateway: agent и agent.wait.
  • CLI: openclaw agent.

Последовательность запуска

  1. RPC agent проверяет параметры, определяет сеанс (sessionKey/sessionId), сохраняет метаданные сеанса и немедленно возвращает { runId, acceptedAt }.
  2. agentCommand выполняет итерацию: определяет модель и значения по умолчанию для thinking/verbose/trace, загружает снимок Skills, вызывает runEmbeddedAgent и отправляет резервное событие завершения/ошибки жизненного цикла, если встроенный цикл ещё не отправил его.
  3. runEmbeddedAgent: сериализует запуски через очереди сеанса и глобальную очередь, определяет модель и профиль аутентификации, создаёт сеанс OpenClaw, подписывается на события среды выполнения, передаёт изменения ассистента/инструментов в потоковом режиме, обеспечивает соблюдение тайм-аута запуска (прерывая его по истечении времени) и возвращает полезные данные вместе с метаданными использования. Для итераций сервера приложений Codex он также прерывает принятую итерацию, если сервер приложений перестаёт сообщать о ходе её выполнения до получения терминального события.
  4. subscribeEmbeddedAgentSession передаёт события среды выполнения в поток agent: события инструментов — в stream: "tool", изменения ассистента — в stream: "assistant", события жизненного цикла — в stream: "lifecycle" (phase: "start" | "end" | "error").
  5. agent.wait (waitForAgentRun) ожидает завершения/ошибки жизненного цикла в runId и возвращает { status: ok|error|timeout, startedAt, endedAt, error? }.

Очереди и параллелизм

Запуски сериализуются по ключу сеанса (линия сеанса) и при необходимости через глобальную линию, что предотвращает состояния гонки между инструментами и сеансами. Каналы обмена сообщениями выбирают режим очереди (steer/followup/collect/interrupt), который передаёт данные в эту систему линий; см. Очередь команд.

Запись расшифровки дополнительно защищена блокировкой записи сеанса для файла сеанса. Блокировка учитывает процессы и реализована на уровне файлов, поэтому она обнаруживает процессы записи, которые обходят внутрипроцессную очередь или выполняются в другом процессе. Процессы записи ожидают до session.writeLock.acquireTimeoutMs (по умолчанию 60000 мс; переопределяется переменной среды OPENCLAW_SESSION_WRITE_LOCK_ACQUIRE_TIMEOUT_MS), после чего сообщают, что сеанс занят.

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

Подготовка сеанса и рабочего пространства

  • Рабочее пространство определяется и создаётся; запуски в песочнице могут перенаправляться в корень рабочего пространства песочницы.
  • Skills загружаются (или повторно используются из снимка) и внедряются в переменные среды и промпт.
  • Файлы начальной загрузки и контекста определяются и внедряются в системный промпт.
  • До начала потоковой передачи получается блокировка записи сеанса и подготавливается целевое хранилище расшифровки сеанса. Любой последующий путь перезаписи, Compaction или усечения расшифровки должен получить ту же блокировку до изменения строк расшифровки в SQLite.

Сборка промпта

Системный промпт создаётся из базового промпта OpenClaw, промпта Skills, контекста начальной загрузки и переопределений для конкретного запуска. Применяются ограничения конкретной модели и резерв токенов для Compaction. Сведения о том, что видит модель, см. в разделе Системный промпт.

Хуки

В OpenClaw есть две системы хуков:

  • Внутренние хуки (хуки Gateway): событийные сценарии для команд и событий жизненного цикла.
  • Хуки плагинов: точки расширения внутри жизненного цикла агента/инструмента и конвейера Gateway.

Внутренние хуки (хуки Gateway)

  • agent:bootstrap: выполняется при создании файлов начальной загрузки до окончательного формирования системного промпта. Используйте его для добавления или удаления файлов контекста начальной загрузки.
  • Хуки команд: /new, /reset, /stop и другие события команд (см. документацию по хукам).

Инструкции по настройке и примеры см. в разделе Хуки.

Хуки плагинов

Они выполняются внутри цикла агента или конвейера Gateway:

Хук Когда выполняется
before_model_resolve До начала сеанса (без messages) для детерминированного переопределения поставщика/модели до их определения.
before_prompt_build После загрузки сеанса (с messages) для внедрения prependContext, systemPrompt, prependSystemContext или appendSystemContext перед отправкой. Используйте prependContext для динамического текста каждой итерации, а поля системного контекста — для стабильных инструкций, которые должны находиться в системном промпте.
before_agent_start Устаревший хук совместимости, который может выполняться на любом из этапов; отдавайте предпочтение явным хукам выше.
before_agent_reply После встроенных действий, до вызова LLM. Позволяет плагину перехватить итерацию и вернуть синтетический ответ либо полностью подавить его.
agent_end После завершения, с окончательным списком сообщений и метаданными запуска.
before_compaction / after_compaction Наблюдает за циклами Compaction или добавляет к ним аннотации.
before_tool_call / after_tool_call Перехватывает параметры и результаты инструментов.
before_install После применения политики оператора по установке к подготовленным материалам для установки Skills/плагина, когда хуки плагинов загружены в текущем процессе.
tool_result_persist Синхронно преобразует результаты инструментов до их записи в расшифровку сеанса, принадлежащую OpenClaw.
message_received / message_sending / message_sent Хуки входящих и исходящих сообщений.
session_start / session_end Границы жизненного цикла сеанса.
gateway_start / gateway_stop События жизненного цикла Gateway.

Правила принятия решений хуками для защитных обработчиков исходящих сообщений/инструментов:

  • before_tool_call: { block: true } является терминальным и останавливает обработчики с более низким приоритетом. { block: false } не выполняет действий и не снимает ранее установленную блокировку.
  • before_install: те же семантики терминального результата и отсутствия действий, что и выше. Для решений оператора о разрешении/блокировке установки, которые должны охватывать пути установки и обновления через CLI, используйте security.installPolicy, а не before_install.
  • message_sending: { cancel: true } является терминальным и останавливает обработчики с более низким приоритетом. { cancel: false } не выполняет действий и не отменяет ранее заданную отмену.

API хуков и сведения о регистрации см. в разделе Хуки плагинов.

Среды-обвязки могут адаптировать эти хуки. Обвязка сервера приложений Codex сохраняет хуки плагинов OpenClaw как контракт совместимости для документированных зеркальных поверхностей; нативные хуки Codex являются отдельным низкоуровневым механизмом Codex.

Потоковая передача

  • Изменения ассистента передаются из среды выполнения агента в виде событий assistant.
  • Блочная потоковая передача может отправлять частичные ответы при text_end или message_end.
  • Потоковая передача рассуждений может выполняться отдельным потоком или в составе блочных ответов.
  • Описание разбиения на фрагменты и поведения блочных ответов см. в разделе Потоковая передача.

Выполнение инструментов

  • События запуска/обновления/завершения инструмента отправляются в поток tool.
  • Перед журналированием/отправкой размеры результатов инструментов и содержащиеся в них изображения приводятся к безопасному виду.
  • Отправки через инструмент обмена сообщениями отслеживаются, чтобы подавлять дублирующие подтверждения ассистента.

Формирование ответа

Итоговые полезные данные формируются из текста ассистента (и при необходимости рассуждений), встроенных сводок инструментов (если включён подробный режим и это разрешено) и текста ошибки ассистента при ошибке модели.

  • Точный токен молчания NO_REPLY отфильтровывается из исходящих полезных данных.
  • Дубликаты инструмента обмена сообщениями удаляются из итогового списка полезных данных.
  • Если отображаемых полезных данных не осталось и инструмент завершился с ошибкой, отправляется резервный ответ об ошибке инструмента, если инструмент обмена сообщениями ещё не отправил видимый пользователю ответ.

Compaction и повторные попытки

Автоматическая Compaction отправляет события потока compaction и может инициировать повторную попытку. При повторной попытке буферы в памяти и сводки инструментов сбрасываются, чтобы избежать дублирования вывода. См. Compaction.

Потоки событий

  • lifecycle: отправляется функцией subscribeEmbeddedAgentSession (и в качестве резервного варианта — функцией agentCommand).
  • assistant: потоковые изменения из среды выполнения агента.
  • tool: потоковые события инструментов из среды выполнения агента.

Gateway проецирует события жизненного цикла и события запуска/терминального состояния инструментов в ограниченный журнал аудита, содержащий только метаданные. Эта проекция записывает происхождение и коды результатов, не копируя промпты, сообщения, аргументы инструментов, результаты инструментов или необработанные ошибки за пределы пути расшифровки/среды выполнения.

Обработка каналов чата

Изменения ассистента буферизуются в сообщения чата delta. Событие чата final отправляется при завершении/ошибке жизненного цикла.

Тайм-ауты

Тайм-аут По умолчанию Примечания
agent.wait 30s Только ожидание; параметр timeoutMs переопределяет значение. Не останавливает выполняющийся в фоне запуск.
Время выполнения агента (agents.defaults.timeoutSeconds) 172800s (48h) Обеспечивается таймером прерывания runEmbeddedAgent. Задайте 0 для неограниченного бюджета запуска; сторожевые таймеры активности потока модели продолжат действовать.
Изолированный запуск агента Cron управляется Cron Планировщик запускает собственный таймер при начале выполнения, прерывает запуск по истечении настроенного срока, затем выполняет ограниченную по времени очистку перед регистрацией тайм-аута, чтобы устаревший дочерний сеанс не мог заблокировать очередь.
Тайм-аут бездействия модели Облако: 120s; собственный сервер: 300s OpenClaw прерывает запрос к модели, если до истечения интервала бездействия не поступают фрагменты ответа. models.providers.<id>.timeoutSeconds увеличивает этот тайм-аут бездействия для медленных локальных провайдеров и провайдеров на собственном сервере, но он по-прежнему ограничивается любым меньшим конечным значением agents.defaults.timeoutSeconds или тайм-аутом конкретного запуска, поскольку они определяют длительность всего запуска агента. При неограниченном бюджете запуска сторожевой таймер бездействия для соответствующего класса провайдера продолжает действовать. Запуски облачной модели, инициированные Cron без явно заданного тайм-аута модели или агента, используют то же значение по умолчанию; если явно задан тайм-аут запуска Cron, зависание потока облачной модели ограничивается 60s, чтобы настроенные резервные модели успели запуститься до внешнего предельного срока Cron. Запуски, инициированные Cron на действительно локальных конечных точках (кольцевой/частный baseUrl), сохраняют возможность отключения локального тайм-аута бездействия; для провайдеров на собственном сервере с сетевыми baseUrl неявно применяется сторожевой таймер 300s. Если явно задан тайм-аут запуска Cron, зависание локального провайдера или провайдера на собственном сервере ограничивается этим тайм-аутом. Задайте models.providers.<id>.timeoutSeconds для медленных локальных провайдеров.
Тайм-аут HTTP-запроса провайдера models.providers.<id>.timeoutSeconds Охватывает подключение, заголовки, тело, тайм-аут запроса SDK, обработку прерывания защищённой выборки и сторожевой таймер бездействия потока модели для этого провайдера. Используйте для медленных локальных провайдеров и провайдеров на собственном сервере (например, Ollama), прежде чем увеличивать тайм-аут всего времени выполнения агента; если запрос модели должен выполняться дольше, тайм-аут агента или среды выполнения должен быть не меньше.

Диагностика зависших сеансов

Если диагностика включена, diagnostics.stuckSessionWarnMs (по умолчанию 120000 ms) классифицирует длительные сеансы processing, в которых не наблюдается прогресса ответа, инструмента, состояния, блока или ACP:

  • Активные встроенные запуски, вызовы моделей и вызовы инструментов обозначаются как session.long_running. Контролируемые безмолвные вызовы моделей сохраняют состояние session.long_running до diagnostics.stuckSessionAbortMs, чтобы медленные или не использующие потоковую передачу провайдеры не считались зависшими слишком рано.
  • Активная работа без недавнего прогресса обозначается как session.stalled. Контролируемые вызовы моделей переключаются в состояние session.stalled при достижении или превышении порога прерывания; устаревшая активность моделей или инструментов без владельца не скрывается как длительная.
  • session.stuck предназначено для восстанавливаемых устаревших данных учёта сеансов, включая простаивающие сеансы в очереди с устаревшей активностью моделей или инструментов без владельца.

Значение diagnostics.stuckSessionAbortMs по умолчанию составляет не менее 5 минут и втрое превышает порог предупреждения. Устаревшие данные учёта сеанса освобождают затронутую очередь сеанса сразу после успешного прохождения проверок восстановления; зависшие встроенные запуски прерываются с ожиданием завершения только после достижения порога прерывания, поэтому работа из очереди возобновляется, не обрывая просто медленные запуски. При восстановлении формируются структурированные результаты запроса и завершения; диагностическое состояние помечается как бездействующее, только если текущее поколение обработки осталось прежним, а повторная диагностика session.stuck выполняется со всё большей задержкой, пока сеанс не изменяется.

Причины досрочного завершения

  • Тайм-аут агента (прерывание)
  • AbortSignal (отмена)
  • Отключение Gateway или тайм-аут RPC
  • Тайм-аут agent.wait (только ожидание, не останавливает агента)

См. также

Was this useful?
On this page

On this page