Fundamentals

Цикл агента

Агентный цикл — это полный «реальный» запуск агента: прием → сборка контекста → инференс модели → выполнение инструментов → потоковые ответы → сохранение. Это авторитетный путь, который превращает сообщение в действия и финальный ответ, сохраняя согласованное состояние сеанса.

В OpenClaw цикл — это один сериализованный запуск на сеанс, который отправляет события жизненного цикла и потока по мере того, как модель размышляет, вызывает инструменты и передает вывод потоком. В этом документе объясняется, как этот аутентичный цикл связан из конца в конец.

Точки входа

  • Gateway RPC: agent и agent.wait.
  • CLI: команда agent.

Как это работает (общий обзор)

  1. RPC agent проверяет параметры, разрешает сеанс (sessionKey/sessionId), сохраняет метаданные сеанса, сразу возвращает { runId, acceptedAt }.
  2. agentCommand запускает агента:
    • разрешает модель + значения по умолчанию для thinking/verbose/trace
    • загружает снимок Skills
    • вызывает runEmbeddedAgent (среда выполнения агента OpenClaw)
    • отправляет завершение/ошибку жизненного цикла, если встроенный цикл сам не отправил такое событие
  3. runEmbeddedAgent:
    • сериализует запуски через очереди на сеанс + глобальные очереди
    • разрешает модель + профиль аутентификации и создает сеанс OpenClaw
    • подписывается на события среды выполнения и передает потоком дельты ассистента/инструмента
    • обеспечивает тайм-аут -> прерывает запуск при превышении
    • для ходов app-server Codex прерывает принятый ход, который перестает выдавать прогресс app-server до терминального события
    • возвращает полезные нагрузки + метаданные использования
  4. subscribeEmbeddedAgentSession связывает события среды выполнения агента с потоком OpenClaw 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 мс.
  • Блокировки записи сеанса по умолчанию не реентерабельны. Если помощник намеренно вкладывает получение той же блокировки, сохраняя одного логического писателя, он должен явно включить это с allowReentrant: true.

Подготовка сеанса + рабочей области

  • Рабочая область разрешается и создается; изолированные запуски могут перенаправляться в корень изолированной рабочей области.
  • Skills загружаются (или повторно используются из снимка) и внедряются в окружение и промпт.
  • Файлы bootstrap/context разрешаются и внедряются в отчет системного промпта.
  • Получается блокировка записи сеанса; SessionManager открывается и подготавливается перед потоковой передачей. Любой последующий путь перезаписи транскрипта, Compaction или усечения должен получить ту же блокировку перед открытием или изменением файла транскрипта.

Сборка промпта + системный промпт

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

Точки хуков (где можно перехватить)

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

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

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

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

См. Хуки для настройки и примеров.

Хуки Plugin (жизненный цикл агента + gateway)

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

  • before_model_resolve: выполняется до сеанса (без messages), чтобы детерминированно переопределить провайдера/модель до разрешения модели.
  • before_prompt_build: выполняется после загрузки сеанса (с messages), чтобы внедрить prependContext, systemPrompt, prependSystemContext или appendSystemContext перед отправкой промпта. Используйте prependContext для динамического текста на ход, а поля системного контекста — для стабильных указаний, которые должны находиться в пространстве системного промпта.
  • before_agent_start: хук обратной совместимости, который может выполняться в любой фазе; предпочитайте явные хуки выше.
  • before_agent_reply: выполняется после встроенных действий и до вызова LLM, позволяя Plugin забрать ход и вернуть синтетический ответ или полностью заглушить ход.
  • agent_end: инспектирует финальный список сообщений и метаданные запуска после завершения.
  • before_compaction / after_compaction: наблюдают или аннотируют циклы Compaction.
  • before_tool_call / after_tool_call: перехватывают параметры/результаты инструмента.
  • before_install: инспектирует подготовленные материалы установки skill или Plugin после применения политики установки оператора, когда хуки Plugin загружены в текущий процесс OpenClaw.
  • tool_result_persist: синхронно преобразует результаты инструментов до их записи в принадлежащий OpenClaw транскрипт сеанса.
  • message_received / message_sending / message_sent: хуки входящих + исходящих сообщений.
  • session_start / session_end: границы жизненного цикла сеанса.
  • gateway_start / gateway_stop: события жизненного цикла gateway.

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

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

См. Хуки Plugin для API хуков и деталей регистрации.

Harnesses могут адаптировать эти хуки по-разному. Harness app-server Codex сохраняет хуки Plugin OpenClaw как контракт совместимости для документированных зеркалируемых поверхностей, тогда как нативные хуки Codex остаются отдельным низкоуровневым механизмом Codex.

Потоковая передача + частичные ответы

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

Выполнение инструментов + инструменты сообщений

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

Формирование ответа + подавление

  • Финальные полезные нагрузки собираются из:
    • текста ассистента (и опционального рассуждения)
    • встроенных сводок инструментов (когда verbose + разрешено)
    • текста ошибки ассистента, когда модель ошибается
  • Точный тихий токен NO_REPLY / no_reply фильтруется из исходящих полезных нагрузок.
  • Дубликаты инструментов сообщений удаляются из финального списка полезных нагрузок.
  • Если не осталось отображаемых полезных нагрузок и инструмент завершился ошибкой, отправляется резервный ответ об ошибке инструмента (если инструмент сообщений уже не отправил видимый пользователю ответ).

Compaction + повторы

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

Потоки событий (сегодня)

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

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

  • Дельты ассистента буферизуются в чат-сообщения delta.
  • Чат-сообщение final отправляется при завершении/ошибке жизненного цикла.

Тайм-ауты

  • agent.wait по умолчанию: 30 с (только ожидание). Параметр timeoutMs переопределяет.
  • Среда выполнения агента: agents.defaults.timeoutSeconds по умолчанию 172800 с (48 часов); обеспечивается таймером прерывания в runEmbeddedAgent.
  • Среда выполнения Cron: изолированный timeoutSeconds хода агента принадлежит cron. Планировщик запускает этот таймер при начале выполнения, прерывает базовый запуск в настроенный срок, затем выполняет ограниченную очистку перед записью тайм-аута, чтобы устаревший дочерний сеанс не мог удерживать полосу заблокированной.
  • Диагностика активности сеанса: при включенной диагностике diagnostics.stuckSessionWarnMs классифицирует долгие сеансы processing, у которых нет наблюдаемого ответа, инструмента, статуса, блока или прогресса ACP. Активные встроенные запуски, вызовы модели и вызовы инструментов сообщаются как session.long_running; принадлежащие системе тихие вызовы модели также остаются session.long_running до diagnostics.stuckSessionAbortMs, чтобы медленные или непотоковые провайдеры не считались зависшими слишком рано. Активная работа без недавнего прогресса сообщается как session.stalled; принадлежащие системе вызовы модели переключаются на session.stalled при достижении или после достижения порога прерывания, а устаревшая активность модели/инструмента без владельца не скрывается как long-running. session.stuck зарезервирован для восстанавливаемого устаревшего учета сеанса, включая неактивные поставленные в очередь сеансы с устаревшей активностью модели/инструмента без владельца. Устаревший учет сеанса освобождает затронутую полосу сеанса сразу после прохождения ворот восстановления; зависшие встроенные запуски прерываются и дренируются только после diagnostics.stuckSessionAbortMs (по умолчанию: минимум 5 минут и 3x порога предупреждения), чтобы работа в очереди могла возобновиться без отсечения просто медленных запусков. Восстановление отправляет структурированные исходы requested/completed, а диагностическое состояние помечается как idle только если то же поколение processing все еще актуально. Повторяющиеся диагностики session.stuck используют backoff, пока сеанс остается неизменным.
  • Тайм-аут простоя модели: OpenClaw прерывает запрос к модели, когда до истечения окна простоя не приходят фрагменты ответа. models.providers.<id>.timeoutSeconds расширяет этот сторожевой таймер простоя для медленных локальных/self-hosted провайдеров, но он все равно ограничен любым меньшим agents.defaults.timeoutSeconds или тайм-аутом конкретного запуска, потому что они контролируют весь запуск агента. В остальных случаях OpenClaw использует agents.defaults.timeoutSeconds, когда он настроен, с ограничением 120 с по умолчанию. Запуски облачных моделей, инициированные Cron, без явного тайм-аута модели или агента используют тот же сторожевой таймер простоя по умолчанию; с явным тайм-аутом запуска cron остановки потока облачной модели ограничены 60 с, чтобы настроенные fallback-модели могли выполниться до внешнего срока cron. Запуски локальных или self-hosted моделей, инициированные Cron, отключают неявный сторожевой таймер, если не настроен явный тайм-аут, а явные тайм-ауты запуска cron остаются окном простоя для локальных/self-hosted провайдеров, поэтому медленным локальным провайдерам следует задавать models.providers.<id>.timeoutSeconds.
  • Тайм-аут HTTP-запроса провайдера: models.providers.<id>.timeoutSeconds применяется к HTTP fetch запросам модели этого провайдера, включая подключение, заголовки, тело, тайм-аут запроса SDK, общую обработку прерывания guarded-fetch и сторожевой таймер простоя потока модели. Используйте это для медленных локальных/self-hosted провайдеров, таких как Ollama, перед повышением тайм-аута всей среды выполнения агента, и держите тайм-аут агента/среды выполнения как минимум таким же высоким, когда запрос модели должен выполняться дольше.

Где все может завершиться раньше

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

Связанные материалы

Was this useful?
On this page

On this page