Model failover
OpenClaw は失敗を 2 段階で処理します:- 現在のプロバイダー内での Auth profile のローテーション。
agents.defaults.model.fallbacks内の次のモデルへの モデルフォールバック。
実行時フロー
通常のテキスト実行では、OpenClaw は候補を次の順序で評価します:- 現在選択されているセッションモデル。
- 設定された
agents.defaults.model.fallbacksを順番に。 - 実行がオーバーライドから始まった場合は、最後に設定済みのプライマリモデル。
- アクティブなセッションモデルと auth-profile の優先設定を解決する。
- モデル候補チェーンを構築する。
- auth-profile のローテーション / クールダウンルールで現在のプロバイダーを試す。
- そのプロバイダーがフォールバックに値するエラーで使い尽くされたら、次の モデル候補に移動する。
- リトライ開始前に選択されたフォールバックオーバーライドを永続化し、他の セッション読み取り側がランナーがこれから使用するのと同じプロバイダー / モデルを見るようにする。
- フォールバック候補が失敗した場合、その失敗した候補とまだ一致しているときに限り、 フォールバック所有のセッションオーバーライドフィールドだけをロールバックする。
- すべての候補が失敗した場合、各試行の詳細と、判明している場合は最も早い
クールダウン満了時刻を含む
FallbackSummaryErrorを投げる。
providerOverridemodelOverrideauthProfileOverrideauthProfileOverrideSourceauthProfileOverrideCompactionCount
/model 変更や
セッションローテーション更新など、新しい無関係なセッション変更を上書きするのを防ぎます。
Auth ストレージ(キー + OAuth)
OpenClaw は API キーと OAuth トークンの両方に auth profile を使用します。- シークレットは
~/.openclaw/agents/<agentId>/agent/auth-profiles.jsonに保存されます(レガシー:~/.openclaw/agent/auth-profiles.json)。 - config の
auth.profiles/auth.orderは メタデータ + ルーティングのみ です(シークレットは含みません)。 - レガシーのインポート専用 OAuth ファイル:
~/.openclaw/credentials/oauth.json(初回利用時にauth-profiles.jsonにインポートされます)。
type: "api_key"→{ provider, key }type: "oauth"→{ provider, access, refresh, expires, email? }(一部のプロバイダーではprojectId/enterpriseUrlを追加)
Profile ID
OAuth ログインでは、複数アカウントが共存できるように個別の profile が作成されます。- デフォルト: メールアドレスが利用できない場合は
provider:default - メールアドレス付き OAuth:
provider:<email>(例:google-antigravity:user@gmail.com)
~/.openclaw/agents/<agentId>/agent/auth-profiles.json の profiles 配下に保存されます。
ローテーション順序
あるプロバイダーに複数の profile がある場合、OpenClaw は次のように順序を決定します:- 明示的な config:
auth.order[provider](設定されている場合) - 設定済み profile: プロバイダーで絞り込んだ
auth.profiles - 保存済み profile: そのプロバイダーの
auth-profiles.json内のエントリー
- 主キー: profile のタイプ(API キーより OAuth を優先)
- 副キー:
usageStats.lastUsed(各タイプ内で最も古いものから) - クールダウン中 / 無効化済み profile は末尾に移動され、最も早い満了時刻順に並べられます。
セッション固定性(キャッシュに優しい)
OpenClaw は、プロバイダーキャッシュを温かいまま保つために、選択した auth profile をセッションごとに固定 します。 リクエストごとにローテーションはしません。固定された profile は次の場合まで再利用されます:- セッションがリセットされる(
/new//reset) - compaction が完了する(compaction 回数が増える)
- profile がクールダウン中または無効化される
/model …@<profileId> による手動選択は、そのセッションの ユーザーオーバーライド を設定し、
新しいセッションが開始されるまで自動ローテーションされません。
自動的に固定された profile(セッションルーターによって選択されたもの)は 優先設定 として扱われます:
最初に試されますが、レート制限 / タイムアウト時には OpenClaw が別の profile にローテーションすることがあります。
ユーザー固定の profile はその profile に固定されたままです。これが失敗し、モデルフォールバックが
設定されている場合、OpenClaw は profile を切り替える代わりに次のモデルへ移動します。
OAuth が「失われたように見える」理由
同じプロバイダーに対して OAuth profile と API キー profile の両方がある場合、 固定されていないとラウンドロビンによりメッセージ間でそれらが切り替わることがあります。単一の profile を強制するには:auth.order[provider] = ["provider:profileId"]で固定する、または/model …に profile オーバーライドを付けたセッションごとのオーバーライドを使用する (UI / チャットサーフェスが対応している場合)。
クールダウン
auth / レート制限エラー(またはレート制限のように見えるタイムアウト)によって profile が失敗すると、 OpenClaw はそれをクールダウン状態にし、次の profile に進みます。 このレート制限バケットは単なる429 より広く、Too many concurrent requests、ThrottlingException、
concurrency limit reached、workers_ai ... quota limit exceeded、
throttled、resource exhausted、および
weekly/monthly limit reached のような定期的な利用枠制限も含みます。
形式エラー / 無効リクエストエラー(たとえば Cloud Code Assist の tool call ID
検証失敗)はフォールバックに値するものとして扱われ、同じクールダウンが使われます。
Unhandled stop reason: error、
stop reason: error、reason: error のような OpenAI 互換の stop-reason エラーは、
タイムアウト / フォールバックシグナルとして分類されます。
プロバイダースコープの一般的なサーバーテキストも、ソースが既知の一時的パターンに一致する場合、
このタイムアウトバケットに入ることがあります。たとえば Anthropic の素の
An unknown error occurred や、internal server error、unknown error, 520、
upstream error、backend error のような一時的なサーバーテキストを含む JSON の api_error ペイロードは、
フォールバックに値するタイムアウトとして扱われます。OpenRouter 固有の
一般的な上流テキスト、たとえば素の Provider returned error も、
実際にプロバイダーコンテキストが OpenRouter のときに限りタイムアウトとして扱われます。
LLM request failed with an unknown error. のような一般的な内部フォールバックテキストは、
保守的に扱われ、それだけではフォールバックをトリガーしません。
レート制限クールダウンはモデルスコープにもできます:
- OpenClaw は、失敗したモデル ID が分かっている場合、レート制限失敗に対して
cooldownModelを記録します。 - 同じプロバイダー上の兄弟モデルは、クールダウンが別のモデルにスコープされている場合でも試行できます。
- 課金 / 無効化ウィンドウは、引き続きその profile を全モデルでブロックします。
- 1 分
- 5 分
- 25 分
- 1 時間(上限)
auth-profiles.json の usageStats 配下に保存されます:
課金による無効化
課金 / クレジット失敗(たとえば「insufficient credits」や「credit balance too low」)は フォールバックに値するものとして扱われますが、通常は一時的ではありません。短いクールダウンの代わりに、 OpenClaw はその profile を disabled としてマークし(より長いバックオフ付きで)、 次の profile / プロバイダーにローテーションします。 すべての課金っぽいレスポンスが402 というわけではなく、すべての HTTP 402 が
ここに入るわけでもありません。OpenClaw は、プロバイダーが代わりに 401 や 403 を返した場合でも、
明示的な課金テキストは課金レーンに残しますが、プロバイダー固有のマッチャーは
それを所有するプロバイダーにスコープされたままです(たとえば OpenRouter の 403 Key limit exceeded)。一方で、一時的な 402 の利用枠ウィンドウや
organization / workspace の支出制限エラーは、メッセージが再試行可能に見える場合、
rate_limit として分類されます(たとえば weekly usage limit exhausted、daily limit reached, resets tomorrow、organization spending limit exceeded)。
これらは、長い課金無効化パスではなく、短いクールダウン / フォールバック経路に残ります。
状態は auth-profiles.json に保存されます:
- 課金バックオフは 5 時間 から始まり、課金失敗ごとに倍増し、24 時間 で上限になります。
- profile が 24 時間 失敗していなければ、バックオフカウンターはリセットされます(設定可能)。
- 過負荷リトライでは、モデルフォールバックの前に 同一プロバイダーの profile ローテーションを 1 回 許可します。
- 過負荷リトライはデフォルトで 0 ms バックオフ を使用します。
モデルフォールバック
あるプロバイダーのすべての profile が失敗した場合、OpenClaw はagents.defaults.model.fallbacks 内の次のモデルに移動します。これは auth 失敗、レート制限、
および profile ローテーションを使い切ったタイムアウトに適用されます
(他のエラーではフォールバックは進みません)。
過負荷エラーとレート制限エラーは、課金クールダウンよりも積極的に処理されます。
デフォルトでは、OpenClaw は同一プロバイダーの auth-profile リトライを 1 回許可し、
その後は待たずに次の設定済みモデルフォールバックに切り替えます。
ModelNotReadyException のようなプロバイダー多忙シグナルは、その過負荷バケットに入ります。
これは auth.cooldowns.overloadedProfileRotations、
auth.cooldowns.overloadedBackoffMs、および
auth.cooldowns.rateLimitedProfileRotations で調整できます。
モデルオーバーライド(hooks または CLI)で実行が始まった場合でも、
設定済みフォールバックを試した後は、最終的に agents.defaults.model.primary で終了します。
候補チェーンのルール
OpenClaw は、現在要求されているprovider/model と設定済みのフォールバックから候補リストを構築します。
ルール:
- 要求されたモデルは常に先頭です。
- 明示的に設定されたフォールバックは重複排除されますが、モデルの allowlist ではフィルタリングされません。これらは明示的な運用者の意図として扱われます。
- 現在の実行がすでに同じプロバイダーファミリー内の設定済みフォールバック上にある場合、 OpenClaw は設定済みチェーン全体を使い続けます。
- 現在の実行が config と異なるプロバイダー上にあり、その現在の モデルが設定済みフォールバックチェーンの一部でない場合、OpenClaw は 別プロバイダーの無関係な設定済みフォールバックを追加しません。
- 実行がオーバーライドから始まった場合、設定済みのプライマリが末尾に追加されるため、 先行候補を使い切った後にチェーンは通常のデフォルトへ戻ることができます。
どのエラーでフォールバックが進むか
モデルフォールバックは次の場合に継続します:- auth 失敗
- レート制限とクールダウン枯渇
- 過負荷 / プロバイダー多忙エラー
- タイムアウト型のフォールバックエラー
- 課金による無効化
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) - 候補が残っていない最終的な未知のエラー
クールダウン時のスキップとプローブの動作
あるプロバイダーのすべての auth profile がすでにクールダウン中であっても、 OpenClaw はそのプロバイダーを永続的に自動スキップするわけではありません。候補ごとに次の判断を行います:- 永続的な auth 失敗では、そのプロバイダー全体を即座にスキップします。
- 課金による無効化では通常スキップしますが、再起動なしで回復可能にするため、 プライマリ候補はスロットル付きでなおプローブされることがあります。
- プライマリ候補は、プロバイダーごとのスロットル付きで、クールダウン満了近くにプローブされる場合があります。
- 同一プロバイダーの兄弟フォールバックは、失敗が一時的に見える場合
(
rate_limit、overloaded、または unknown)には、クールダウン中でも試行されることがあります。 これは、レート制限がモデルスコープで、兄弟モデルがすぐに回復する可能性がある場合に特に重要です。 - 一時的なクールダウンプローブは、単一のプロバイダーがクロスプロバイダーのフォールバックを停滞させないよう、 フォールバック実行ごとにプロバイダーあたり 1 回に制限されます。
セッションオーバーライドとライブモデル切り替え
セッションモデルの変更は共有状態です。アクティブなランナー、/model コマンド、
compaction / セッション更新、ライブセッション再調整はすべて、
同じセッションエントリーの一部を読み書きします。
つまり、フォールバックリトライはライブモデル切り替えと協調する必要があります:
- 保留中のライブ切り替えをマークするのは、明示的なユーザー主導のモデル変更だけです。
これには
/model、session_status(model=...)、sessions.patchが含まれます。 - フォールバックローテーション、heartbeat オーバーライド、 compaction のようなシステム主導のモデル変更は、それ自体では保留中のライブ切り替えをマークしません。
- フォールバックリトライが始まる前に、reply ランナーは選択された フォールバックオーバーライドフィールドをセッションエントリーに永続化します。
- ライブセッション再調整は、古い実行時モデルフィールドよりも 永続化されたセッションオーバーライドを優先します。
- フォールバック試行が失敗した場合、ランナーは自分が書いたオーバーライドフィールドのみを、 しかもそれがその失敗した候補とまだ一致している場合にのみロールバックします。
- プライマリが失敗する。
- フォールバック候補がメモリ内で選択される。
- セッションストアにはまだ古いプライマリが記録されている。
- ライブセッション再調整がその古いセッション状態を読み取る。
- フォールバック試行が始まる前に、リトライが古いモデルに戻される。
可観測性と失敗サマリー
runWithModelFallback(...) は、ログとユーザー向けのクールダウンメッセージに使われる
試行ごとの詳細を記録します:
- 試行した provider/model
- reason(
rate_limit、overloaded、billing、auth、model_not_found、 および類似のフォールバック理由) - 任意の status/code
- 人間が読めるエラーサマリー
FallbackSummaryError を投げます。外側の
reply ランナーはこれを使って、「all models
are temporarily rate-limited」のようなより具体的なメッセージを構築し、
判明している場合は最も早いクールダウン満了時刻を含めることができます。
そのクールダウンサマリーはモデル認識型です:
- 試行された provider/model チェーンに無関係なモデルスコープのレート制限は無視されます
- 残っているブロックがそのモデルに一致するモデルスコープのレート制限である場合、 OpenClaw はそのモデルをまだブロックしている最後の一致する満了時刻を報告します
関連する config
以下については Gateway configuration を参照してください:auth.profiles/auth.orderauth.cooldowns.billingBackoffHours/auth.cooldowns.billingBackoffHoursByProviderauth.cooldowns.billingMaxHours/auth.cooldowns.failureWindowHoursauth.cooldowns.overloadedProfileRotations/auth.cooldowns.overloadedBackoffMsauth.cooldowns.rateLimitedProfileRotationsagents.defaults.model.primary/agents.defaults.model.fallbacksagents.defaults.imageModelルーティング