Concepts and configuration

Отказоустойчивое переключение модели

OpenClaw обрабатывает сбои в два этапа:

  1. Ротация профилей аутентификации внутри текущего провайдера.
  2. Резервное переключение модели на следующую модель в agents.defaults.model.fallbacks.

В этом документе объясняются правила runtime и данные, которые их поддерживают.

Поток runtime

Для обычного текстового запуска OpenClaw оценивает кандидатов в таком порядке:

  • Разрешить состояние сессии

    Разрешить активную модель сессии и предпочтение профиля аутентификации.

  • Построить цепочку кандидатов

    Построить цепочку моделей-кандидатов из текущего выбора модели и политики резервного переключения для источника этого выбора. Настроенные значения по умолчанию, основные модели Cron-задач и автоматически выбранные резервные модели могут использовать настроенные резервные варианты; явные пользовательские выборы в сессии являются строгими.

  • Попробовать текущего провайдера

    Попробовать текущего провайдера с правилами ротации/охлаждения профилей аутентификации.

  • Перейти дальше при ошибках, требующих failover

    Если этот провайдер исчерпан с ошибкой, подходящей для failover, перейти к следующей модели-кандидату.

  • Сохранить резервное переопределение

    Сохранить выбранное резервное переопределение до начала повторной попытки, чтобы другие читатели сессии видели того же провайдера/модель, которых runner собирается использовать. Сохраненное переопределение модели помечается как modelOverrideSource: "auto".

  • Точно откатить при сбое

    Если резервный кандидат дает сбой, откатить только поля переопределения сессии, принадлежащие fallback, когда они все еще соответствуют этому неудачному кандидату.

  • Выбросить FallbackSummaryError, если все исчерпано

    Если каждый кандидат дает сбой, выбросить FallbackSummaryError с подробностями по каждой попытке и ближайшим истечением охлаждения, когда оно известно.

  • Это намеренно уже, чем «сохранить и восстановить всю сессию». Runner ответов сохраняет только поля выбора модели, которыми он владеет для fallback:

    • providerOverride
    • modelOverride
    • modelOverrideSource
    • authProfileOverride
    • authProfileOverrideSource
    • authProfileOverrideCompactionCount

    Это не позволяет неудачной повторной попытке fallback перезаписать более новые несвязанные мутации сессии, такие как ручные изменения /model или обновления ротации сессии, произошедшие во время выполнения попытки.

    Политика источника выбора

    OpenClaw отделяет выбранного провайдера/модель от причины выбора. Этот источник управляет тем, разрешена ли цепочка fallback:

    • Настроенное значение по умолчанию: agents.defaults.model.primary использует agents.defaults.model.fallbacks.
    • Основная модель агента: agents.list[].model является строгой, если только объект модели этого агента не включает собственные fallbacks. Используйте fallbacks: [], чтобы сделать строгое поведение явным, или укажите непустой список, чтобы включить для этого агента резервное переключение моделей.
    • Автоматическое резервное переопределение: runtime fallback записывает providerOverride, modelOverride, modelOverrideSource: "auto" и выбранную исходную модель перед повторной попыткой. Это автоматическое переопределение может продолжать идти по настроенной цепочке fallback без проверки основной модели при каждом сообщении, но OpenClaw периодически снова проверяет настроенный источник и очищает автоматическое переопределение, когда он восстанавливается. /new, /reset и sessions.reset также очищают переопределения с источником auto. Запуски Heartbeat без явного heartbeat.model очищают прямые автоматические переопределения, когда их источник больше не соответствует текущему настроенному значению по умолчанию.
    • Пользовательское переопределение сессии: /model, средство выбора модели, session_status(model=...) и sessions.patch записывают modelOverrideSource: "user". Это точный выбор сессии. Если выбранный провайдер/модель дает сбой до создания ответа, OpenClaw сообщает о сбое вместо ответа от несвязанного настроенного fallback.
    • Устаревшее переопределение сессии: более старые записи сессий могут иметь modelOverride без modelOverrideSource. OpenClaw трактует их как пользовательские переопределения, чтобы явный старый выбор не был незаметно преобразован в поведение fallback.
    • Модель payload Cron: payload.model / --model Cron-задачи является основной моделью задания, а не пользовательским переопределением сессии. Она использует настроенные fallback, если задание не предоставляет payload.fallbacks; payload.fallbacks: [] делает запуск Cron строгим.

    Интервал проверки основной модели для автоматического fallback составляет пять минут и не настраивается. OpenClaw запоминает недавние проверки для каждой сессии и основной модели, чтобы отказавшая основная модель не повторялась на каждом ходе. OpenClaw отправляет видимое уведомление, когда сессия переходит на fallback, и еще одно уведомление, когда она возвращается к выбранной основной модели; уведомление не повторяется на каждом закрепленном fallback-ходе.

    Кэш пропуска сбоев аутентификации

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

    Операторы, которые предпочитают подавлять такие повторяющиеся сбои аутентификации, могут включить это с помощью:

    bash
    OPENCLAW_FALLBACK_SKIP_TTL_MS=60000

    Когда это включено, OpenClaw записывает в памяти маркер пропуска, ограниченный сессией, для неосновного кандидата fallback после сбоя класса auth. Маркер ключуется по id сессии, провайдеру и модели. Основные кандидаты никогда не пропускаются, поэтому явный пользовательский выбор модели по-прежнему показывает реальную ошибку аутентификации. Кэш является локальным для процесса и очищается при перезапуске Gateway.

    Значение является TTL в миллисекундах. 0 или неустановленное значение отключает кэш. Положительные значения ограничиваются диапазоном от 1 секунды до 10 минут.

    Пользовательские уведомления fallback

    Когда сессия переходит на автоматически выбранный fallback, OpenClaw отправляет уведомление о статусе в той же поверхности ответа:

    text
    ↪️ Model Fallback: <fallback> (selected <primary>; <reason>)

    Когда последующая проверка проходит успешно и сессия возвращается к выбранной основной модели, OpenClaw отправляет:

    text
    ↪️ Model Fallback cleared: <primary> (was <fallback>)

    Эти уведомления являются операционными сообщениями, а не содержимым ассистента. Они доставляются один раз при каждом изменении состояния, включая ходы только с побочными эффектами, когда это возможно, но закрепленные fallback-ходы их не повторяют. Доставка обходит обычное подавление ответа источнику, уведомление не занимает первый слот ответа ассистента для каналов с тредами и исключается из text-to-speech и извлечения commitment.

    Хранилище аутентификации (ключи + OAuth)

    OpenClaw использует профили аутентификации как для API-ключей, так и для OAuth-токенов.

    • Секреты и состояние runtime-маршрутизации аутентификации находятся в ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite.
    • Конфигурация auth.profiles / auth.order — это только метаданные + маршрутизация (без секретов).
    • Устаревший файл OAuth только для импорта: ~/.openclaw/credentials/oauth.json (импортируется в хранилище аутентификации конкретного агента при первом использовании).
    • Устаревшие файлы auth-profiles.json, auth-state.json и файлы auth.json конкретных агентов импортируются командой openclaw doctor --fix.

    Подробнее: OAuth

    Типы учетных данных:

    • type: "api_key"{ provider, key }
    • type: "oauth"{ provider, access, refresh, expires, email? } (+ projectId/enterpriseUrl для некоторых провайдеров)

    ID профилей

    Входы OAuth создают отдельные профили, чтобы несколько аккаунтов могли сосуществовать.

    • По умолчанию: provider:default, когда email недоступен.
    • OAuth с email: provider:<email> (например, google-antigravity:user@gmail.com).

    Профили находятся в хранилище профилей аутентификации openclaw-agent.sqlite конкретного агента.

    Порядок ротации

    Когда у провайдера есть несколько профилей, OpenClaw выбирает порядок так:

  • Явная конфигурация

    auth.order[provider] (если задано).

  • Настроенные профили

    auth.profiles, отфильтрованные по провайдеру.

  • Сохраненные профили

    Записи профилей аутентификации в SQLite конкретного агента для провайдера.

  • Если явный порядок не настроен, OpenClaw использует порядок round-robin:

    • Основной ключ: тип профиля (OAuth перед API-ключами).
    • Вторичный ключ: usageStats.lastUsed (сначала самые старые, внутри каждого типа).
    • Профили в охлаждении/отключенные профили перемещаются в конец, упорядоченные по ближайшему истечению.

    Закрепление в сессии (удобно для кэша)

    OpenClaw закрепляет выбранный профиль аутентификации за сессией, чтобы сохранять кэши провайдера прогретыми. Он не ротирует профиль при каждом запросе. Закрепленный профиль используется повторно, пока:

    • сессия не сброшена (/new / /reset)
    • Compaction не завершится (счетчик Compaction увеличится)
    • профиль не находится в охлаждении/отключенном состоянии

    Ручной выбор через /model …@<profileId> задает пользовательское переопределение для этой сессии и не ротируется автоматически до начала новой сессии.

    Подписка OpenAI Codex плюс резервный API-ключ

    Для моделей агентов OpenAI аутентификация и runtime разделены. openai/gpt-* остается на harness Codex, а аутентификация может ротироваться между профилем подписки Codex и резервным API-ключом OpenAI.

    Используйте auth.order.openai для пользовательского порядка:

    json5
    {  auth: {    order: {      openai: ["openai:user@example.com", "openai:api-key-backup"],    },  },}

    Используйте openai:* как для OAuth-профилей ChatGPT/Codex, так и для профилей API-ключей OpenAI. Когда подписка достигает лимита использования Codex, OpenClaw записывает точное время сброса, если Codex его предоставляет, пробует следующий упорядоченный профиль аутентификации и сохраняет запуск внутри harness Codex. После того как время сброса проходит, профиль подписки снова становится допустимым, и следующий автоматический выбор может вернуться к нему.

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

    Охлаждения

    Когда профиль дает сбой из-за ошибок аутентификации/rate limit (или timeout, похожего на rate limiting), OpenClaw помечает его как находящийся в охлаждении и переходит к следующему профилю.

    Что попадает в корзину rate limit / timeout

    Эта корзина rate limit шире, чем простой 429: она также включает сообщения провайдеров, такие как Too many concurrent requests, ThrottlingException, concurrency limit reached, workers_ai ... quota limit exceeded, throttled, resource exhausted, и периодические лимиты окна использования, такие как weekly/monthly limit reached.

    Ошибки формата/недопустимого запроса обычно являются терминальными, потому что повторная отправка того же payload завершилась бы тем же образом, поэтому OpenClaw показывает их вместо ротации профилей аутентификации. Известные пути исправления через повтор могут явно подключаться: например, сбои проверки ID вызова инструмента Cloud Code Assist очищаются и повторяются один раз через политику allowFormatRetry. OpenAI-совместимые ошибки stop reason, такие как Unhandled stop reason: error, stop reason: error и reason: error, классифицируются как сигналы timeout/failover.

    Общий серверный текст также может попасть в эту корзину timeout, когда источник соответствует известному transient-паттерну. Например, простое сообщение stream-wrapper runtime модели An unknown error occurred считается подходящим для failover для каждого провайдера, потому что общий runtime модели выдает его, когда потоки провайдера завершаются с stopReason: "aborted" или stopReason: "error" без конкретных деталей. JSON-payload api_error с transient-серверным текстом, таким как internal server error, unknown error, 520, upstream error или backend error, также рассматриваются как подходящие для failover timeouts.

    Специфичный для OpenRouter общий upstream-текст, такой как простое Provider returned error, рассматривается как timeout только тогда, когда контекст провайдера действительно OpenRouter. Общий внутренний текст fallback, такой как LLM request failed with an unknown error., остается консервативным и сам по себе не запускает failover.

    Ограничения retry-after SDK

    Некоторые SDK провайдеров иначе могут ожидать длительное окно Retry-After, прежде чем вернуть управление OpenClaw. Для SDK на базе Stainless, таких как Anthropic и OpenAI, OpenClaw по умолчанию ограничивает внутренние для SDK ожидания retry-after-ms / retry-after 60 секундами и сразу выводит более долгие повторяемые ответы наружу, чтобы этот путь переключения при сбое мог выполниться. Настройте или отключите ограничение с помощью OPENCLAW_SDK_RETRY_MAX_WAIT_SECONDS; см. Поведение повторных попыток.

    Периоды ожидания, привязанные к модели

    Периоды ожидания из-за ограничений частоты также могут быть привязаны к модели:

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

    Периоды ожидания используют экспоненциальную задержку:

    • 1 минута
    • 5 минут
    • 25 минут
    • 1 час (предел)

    Состояние хранится в SQLite-состоянии авторизации для отдельного агента в usageStats:

    json
    {  "usageStats": {    "provider:profile": {      "lastUsed": 1736160000000,      "cooldownUntil": 1736160600000,      "errorCount": 2    }  }}

    Отключения из-за биллинга

    Сбои биллинга/кредитов (например, "insufficient credits" / "credit balance too low") считаются подходящими для переключения при сбое, но обычно они не являются временными. Вместо короткого периода ожидания OpenClaw помечает профиль как отключенный (с более длительной задержкой) и переключается на следующий профиль/провайдера.

    Состояние хранится в SQLite-состоянии авторизации для отдельного агента:

    json
    {  "usageStats": {    "provider:profile": {      "disabledUntil": 1736178000000,      "disabledReason": "billing"    }  }}

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

    • Задержка биллинга начинается с 5 часов, удваивается при каждом биллинговом сбое и ограничивается 24 часами.
    • Счетчики задержки сбрасываются, если профиль не давал сбоев в течение 24 часов (настраивается).
    • Повторные попытки при перегрузке допускают 1 ротацию профиля того же провайдера перед резервной моделью.
    • Повторные попытки при перегрузке по умолчанию используют задержку 0 мс.

    Резервная модель

    Если все профили для провайдера дают сбой, OpenClaw переходит к следующей модели в agents.defaults.model.fallbacks. Это применяется к сбоям авторизации, ограничениям частоты и тайм-аутам, которые исчерпали ротацию профилей (другие ошибки не продвигают резервную цепочку). Ошибки провайдера, которые не раскрывают достаточно подробностей, все равно точно помечаются в состоянии резервного перехода: empty_response означает, что провайдер не вернул пригодного сообщения или статуса, no_error_details означает, что провайдер явно вернул Unknown error (no error details in response), а unclassified означает, что OpenClaw сохранил сырой предпросмотр, но ни один классификатор пока ему не соответствует.

    Ошибки перегрузки и ограничения частоты обрабатываются агрессивнее, чем биллинговые периоды ожидания. По умолчанию OpenClaw допускает одну повторную попытку с профилем авторизации того же провайдера, а затем без ожидания переключается на следующую настроенную резервную модель. Сигналы занятости провайдера, такие как ModelNotReadyException, попадают в этот набор перегрузки. Настройте это с помощью auth.cooldowns.overloadedProfileRotations, auth.cooldowns.overloadedBackoffMs и auth.cooldowns.rateLimitedProfileRotations.

    Когда запуск начинается с настроенной основной модели по умолчанию, основной модели задания cron, основной модели агента с явными резервными моделями или автоматически выбранного резервного переопределения, OpenClaw может пройти по соответствующей настроенной резервной цепочке. Основные модели агента без явных резервных моделей и явные пользовательские выборы (например, /model ollama/qwen3.5:27b, средство выбора модели, sessions.patch или разовые переопределения CLI провайдера/модели) являются строгими: если этот провайдер/модель недоступны или дают сбой до формирования ответа, OpenClaw сообщает о сбое вместо ответа от несвязанной резервной модели.

    Правила цепочки кандидатов

    OpenClaw строит список кандидатов из текущего запрошенного provider/model и настроенных резервных моделей.

    Правила
    • Запрошенная модель всегда первая.
    • Явно настроенные резервные модели дедуплицируются, но не фильтруются по списку разрешенных моделей. Они трактуются как явное намерение оператора.
    • Если текущий запуск уже находится на настроенной резервной модели в том же семействе провайдеров, OpenClaw продолжает использовать полную настроенную цепочку.
    • Когда явное резервное переопределение не передано, настроенные резервные модели пробуются перед настроенной основной моделью, даже если запрошенная модель использует другого провайдера.
    • Когда явное резервное переопределение не передано резервному runner, настроенная основная модель добавляется в конец, чтобы цепочка могла вернуться к обычному значению по умолчанию после исчерпания более ранних кандидатов.
    • Когда вызывающий код передает fallbacksOverride, runner использует ровно запрошенную модель плюс этот список переопределения. Пустой список отключает резервную модель и предотвращает добавление настроенной основной модели как скрытой цели повторной попытки.

    Какие ошибки продвигают резервную цепочку

    Продолжается при

    • сбоях авторизации
    • ограничениях частоты и исчерпании периода ожидания
    • ошибках перегрузки/занятости провайдера
    • ошибках переключения при сбое, похожих на тайм-аут
    • отключениях из-за биллинга
    • LiveSessionModelSwitchError, которая нормализуется в путь переключения при сбое, чтобы устаревшая сохраненная модель не создавала внешний цикл повторных попыток
    • других нераспознанных ошибках, когда еще остаются кандидаты

    Не продолжается при

    • явных прерываниях, которые не похожи на тайм-аут/переключение при сбое
    • ошибках переполнения контекста, которые должны оставаться внутри логики Compaction/повторных попыток (например, request_too_large, INVALID_ARGUMENT: input exceeds the maximum number of tokens, input token count exceeds the maximum number of input tokens, The input is too long for the model или ollama error: context length exceeded)
    • финальной неизвестной ошибке, когда кандидатов больше нет

    Пропуск периода ожидания и поведение проб

    Когда каждый профиль авторизации для провайдера уже находится в периоде ожидания, OpenClaw не пропускает этого провайдера автоматически навсегда. Он принимает решение для каждого кандидата:

    Решения для каждого кандидата
    • Постоянные сбои авторизации сразу пропускают всего провайдера.
    • Отключения из-за биллинга обычно пропускаются, но основной кандидат все еще может проверяться с ограничением частоты, чтобы восстановление было возможно без перезапуска.
    • Основной кандидат может проверяться ближе к истечению периода ожидания, с ограничением частоты для каждого провайдера.
    • Родственные резервные модели того же провайдера могут быть попробованы несмотря на период ожидания, когда сбой выглядит временным (rate_limit, overloaded или неизвестный). Это особенно важно, когда ограничение частоты привязано к модели и родственная модель все еще может восстановиться немедленно.
    • Временные пробы периода ожидания ограничены одной на провайдера за один резервный запуск, чтобы один провайдер не задерживал межпровайдерное резервное переключение.

    Переопределения сеанса и живое переключение модели

    Изменения модели сеанса являются общим состоянием. Активный runner, команда /model, обновления compaction/сеанса и согласование live-сеанса читают или записывают части одной и той же записи сеанса.

    Это значит, что резервные повторные попытки должны координироваться с живым переключением модели:

    • Только явные пользовательские изменения модели помечают ожидающее живое переключение. Это включает /model, session_status(model=...) и sessions.patch.
    • Системные изменения модели, такие как резервная ротация, переопределения Heartbeat или compaction, сами по себе никогда не помечают ожидающее живое переключение.
    • Пользовательские переопределения модели трактуются как точные выборы для политики резервного переключения, поэтому недоступный выбранный провайдер показывается как сбой, а не маскируется agents.defaults.model.fallbacks.
    • Перед запуском резервной повторной попытки runner ответа сохраняет выбранные поля резервного переопределения в запись сеанса.
    • Автоматические резервные переопределения остаются выбранными в последующих ходах, чтобы OpenClaw не проверял заведомо неисправную основную модель при каждом сообщении. OpenClaw периодически снова проверяет настроенный источник и очищает автоматическое переопределение, когда он восстанавливается; /new, /reset и sessions.reset сразу очищают автоматически полученные переопределения.
    • Ответы пользователю объявляют о резервных переходах и восстановлении с очисткой резервного состояния один раз на каждое изменение состояния. Ходы с закрепленной резервной моделью не повторяют уведомление.
    • /status показывает выбранную модель и, когда резервное состояние отличается, активную резервную модель и причину.
    • Согласование live-сеанса предпочитает сохраненные переопределения сеанса устаревшим полям модели runtime.
    • Если ошибка live-переключения указывает на более позднего кандидата в активной резервной цепочке, OpenClaw переходит прямо к этой выбранной модели, а не проходит сначала по несвязанным кандидатам.
    • Если резервная попытка завершается сбоем, runner откатывает только поля переопределения, которые он записал, и только если они все еще соответствуют этому неудавшемуся кандидату.

    Это предотвращает классическую гонку:

  • Основная модель дает сбой

    Выбранная основная модель дает сбой.

  • Резервный вариант выбран в памяти

    Резервный кандидат выбран в памяти.

  • Хранилище сеанса все еще указывает старую основную модель

    Хранилище сеанса все еще отражает старую основную модель.

  • Live-согласование читает устаревшее состояние

    Согласование live-сеанса читает устаревшее состояние сеанса.

  • Повторная попытка возвращена назад

    Повторная попытка возвращается к старой модели до начала резервной попытки.

  • Сохраненное резервное переопределение закрывает это окно, а узкий откат сохраняет новые ручные или runtime-изменения сеанса нетронутыми.

    Наблюдаемость и сводки сбоев

    runWithModelFallback(...) записывает сведения по каждой попытке, которые используются в журналах и пользовательских сообщениях о периодах ожидания:

    • предпринятая попытка provider/model
    • причина (rate_limit, overloaded, billing, auth, model_not_found и похожие причины переключения при сбое)
    • необязательный статус/код
    • человекочитаемая сводка ошибки

    Структурированные журналы model_fallback_decision также включают плоские поля fallbackStep*, когда кандидат дает сбой, пропускается или более поздняя резервная модель успешно срабатывает. Эти поля явно фиксируют предпринятый переход (fallbackStepFromModel, fallbackStepToModel, fallbackStepFromFailureReason, fallbackStepFromFailureDetail, fallbackStepFinalOutcome), чтобы экспортеры журналов и диагностики могли восстановить сбой основной модели, даже когда финальная резервная модель тоже дает сбой.

    Когда все кандидаты дают сбой, OpenClaw выбрасывает FallbackSummaryError. Внешний runner ответа может использовать это, чтобы построить более конкретное сообщение, например "all models are temporarily rate-limited", и включить ближайшее истечение периода ожидания, когда оно известно.

    Эта сводка периода ожидания учитывает модель:

    • ограничения частоты, привязанные к несвязанным моделям, игнорируются для предпринятой цепочки provider/model
    • если оставшаяся блокировка является совпадающим ограничением частоты, привязанным к модели, OpenClaw сообщает последнее совпадающее истечение, которое все еще блокирует эту модель

    Связанная конфигурация

    См. Конфигурация Gateway для:

    • auth.profiles / auth.order
    • auth.cooldowns.billingBackoffHours / auth.cooldowns.billingBackoffHoursByProvider
    • auth.cooldowns.billingMaxHours / auth.cooldowns.failureWindowHours
    • auth.cooldowns.overloadedProfileRotations / auth.cooldowns.overloadedBackoffMs
    • auth.cooldowns.rateLimitedProfileRotations
    • маршрутизация agents.defaults.model.primary / agents.defaults.model.fallbacks
    • маршрутизация agents.defaults.imageModel

    См. Модели для более общего обзора выбора моделей и резервных вариантов.

    Was this useful?
    On this page

    On this page