- 現在のプロバイダー内での認証プロファイルローテーション。
agents.defaults.model.fallbacksの次のモデルへのモデルフォールバック。
ランタイムフロー
候補チェーンを構築
現在のモデル選択と、その選択ソースに対するフォールバックポリシーから、モデル候補チェーンを構築します。設定済みのデフォルト、cron ジョブのプライマリ、自動選択されたフォールバックモデルは、設定済みフォールバックを使用できます。明示的なユーザーセッション選択は厳密です。
フォールバックオーバーライドを永続化
再試行が始まる前に、選択されたフォールバックオーバーライドを永続化します。これにより、他のセッション読み取り側は、ランナーがこれから使用するものと同じプロバイダー/モデルを確認できます。永続化されたモデルオーバーライドには
modelOverrideSource: "auto" が付けられます。失敗時は限定的にロールバック
フォールバック候補が失敗した場合、フォールバックが所有するセッションオーバーライドフィールドがその失敗した候補とまだ一致しているときに限り、それらだけをロールバックします。
providerOverride, modelOverride, modelOverrideSource, authProfileOverride, authProfileOverrideSource, authProfileOverrideCompactionCount。これにより、失敗したフォールバック再試行が、その試行の実行中に発生した手動の /model 変更やセッションローテーション更新など、より新しい無関係なセッション変更を上書きすることを防ぎます。
選択ソースポリシー
選択ソースは、フォールバックチェーンを許可するかどうかを制御します。- 設定済みデフォルト:
agents.defaults.model.primaryはagents.defaults.model.fallbacksを使用します。 - エージェントプライマリ:
agents.list[].modelは、そのエージェントのモデルオブジェクトに独自のfallbacksが含まれていない限り厳密です。厳密な動作を明示するにはfallbacks: []を使用し、そのエージェントをモデルフォールバックにオプトインするには空でないリストを使用します。 - 自動フォールバックオーバーライド: ランタイムフォールバックは、再試行前に
providerOverride,modelOverride,modelOverrideSource: "auto"と、選択された元のモデルを書き込みます。このオーバーライドは、メッセージごとにプライマリをプローブせずに、設定済みフォールバックチェーンを歩き続けます。ただし OpenClaw は設定済みの元モデルを5分ごとにプローブし(設定不可)、回復するとオーバーライドをクリアします。/new,/reset,sessions.resetも自動ソースのオーバーライドをクリアします。明示的なheartbeat.modelなしで実行される Heartbeat は、元モデルが現在の設定済みデフォルトと一致しなくなった場合に、直接的な自動オーバーライドをクリアします。 - ユーザーセッションオーバーライド:
/model、モデルピッカー、session_status(model=...)、sessions.patchはmodelOverrideSource: "user"を書き込みます。これは正確なセッション選択です。選択されたプロバイダー/モデルが返信を生成する前に失敗した場合、OpenClaw は無関係な設定済みフォールバックから回答するのではなく、その失敗を報告します。 - レガシーセッションオーバーライド: 古いセッションエントリには、
modelOverrideSourceなしでmodelOverrideがある場合があります。OpenClaw はこれらをユーザーオーバーライドとして扱うため、明示的な古い選択がサイレントにフォールバック動作へ変換されることはありません。 - Cron ペイロードモデル: cron ジョブの
payload.model/--modelはジョブプライマリであり、ユーザーセッションオーバーライドではありません。ジョブがpayload.fallbacksを提供しない限り、設定済みフォールバックを使用します。payload.fallbacks: []は cron 実行を厳密にします。
認証失敗スキップキャッシュ
デフォルトでは、新しいターンごとに既存のフォールバック再試行動作が維持されます。OpenClaw は、最近auth または auth_permanent で失敗した非プライマリ候補を含め、設定済みの各フォールバック候補を再度試行します。
繰り返しの認証失敗を抑制するには、次でオプトインします。
0 または未設定はキャッシュを無効にします。正の値は1秒から10分の間にクランプされます。
ユーザーに表示されるフォールバック通知
セッションが自動選択されたフォールバックに移動すると、OpenClaw は同じ返信サーフェスにステータス通知を送信します。認証ストレージ(キー + OAuth)
OpenClaw は API キーと OAuth トークンの両方に認証プロファイルを使用します。- シークレットとランタイム認証ルーティング状態は
~/.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によってインポートされます。
type: "api_key"→{ provider, key }type: "oauth"→{ provider, access, refresh, expires, email? }(一部のプロバイダーでは +projectId/enterpriseUrl)type: "token"→ 静的なベアラー形式のトークン。任意で期限切れを設定できます。OpenClaw は更新しません(aws-sdkやその他の認証情報チェーン認証モードで使用)
プロファイル ID
OAuth ログインは、複数のアカウントが共存できるように個別のプロファイルを作成します。- デフォルト: メールアドレスが利用できない場合は
provider:default。 - メールアドレス付き OAuth:
provider:<email>(例:google-antigravity:user@gmail.com)。
openclaw-agent.sqlite 認証プロファイルストアにあります。
ローテーション順序
プロバイダーに複数のプロファイルがある場合、OpenClaw は次のような順序を選択します。
明示的な順序が設定されていない場合、OpenClaw はラウンドロビン順序を使用します。
- プライマリキー: プロファイルタイプ(OAuth、次に静的トークン、次に API キー)。
- セカンダリキー:
usageStats.lastUsed(各タイプ内で古いものが先)。 - クールダウン中/無効化されたプロファイルは末尾に移動され、最も早い期限順に並べられます。
セッションのスティッキネス(キャッシュに適した動作)
OpenClaw はプロバイダーキャッシュを温めたままにするため、選択された認証プロファイルをセッションごとに固定します。リクエストごとにはローテーションしません。固定されたプロファイルは、次のいずれかが起きるまで再利用されます。- セッションがリセットされる(
/new//reset) - Compaction が完了する(compaction count が増加する)
- プロファイルがクールダウン中/無効化されている
/model …@<profileId> による手動選択は、そのセッションのユーザーオーバーライドを設定し、新しいセッションが始まるまで自動ローテーションされません。
自動固定プロファイル(セッションルーターによって選択されたもの)は設定として扱われます。最初に試行されますが、OpenClaw はレート制限/タイムアウト時に別のプロファイルへローテーションする場合があります。元のプロファイルが再び利用可能になると、新しい実行は、選択されたモデルやランタイムを変更せずに再びそれを優先できます。ユーザー固定プロファイルはそのプロファイルにロックされたままです。失敗し、モデルフォールバックが設定されている場合、OpenClaw はプロファイルを切り替えるのではなく次のモデルに移動します。
OpenAI Codex サブスクリプションと API キーバックアップ
OpenAI エージェントモデルでは、認証とランタイムは別です。openai/gpt-* は Codex ハーネス上に残り、認証は Codex サブスクリプションプロファイルと OpenAI API キーバックアップの間でローテーションできます。
ユーザーに表示される順序には auth.order.openai を使用します。
openai:* を使用します。サブスクリプションが Codex 使用量制限に達した場合、Codex がリセット時刻を提供すると OpenClaw はその正確な時刻を記録し、順序内の次の認証プロファイルを試行し、実行を Codex ハーネス内に保ちます。リセット時刻が過ぎると、サブスクリプションプロファイルは再び対象となり、次の自動選択でそこに戻ることができます。
そのセッションで1つのアカウント/キーを強制したい場合にのみ、ユーザー固定プロファイルを使用します。ユーザー固定プロファイルは意図的に厳密であり、別のプロファイルへサイレントに移動することはありません。
クールダウン
認証/レート制限エラー(またはレート制限のように見えるタイムアウト)によりプロファイルが失敗した場合、OpenClaw はそのプロファイルをクールダウン中としてマークし、次のプロファイルへ移動します。レート制限 / タイムアウトバケットに入るもの
レート制限 / タイムアウトバケットに入るもの
そのレート制限バケットは単純な
429 より広く、Too many concurrent requests, ThrottlingException, concurrency limit reached, workers_ai ... quota limit exceeded, throttled, resource exhausted などのプロバイダーメッセージや、weekly limit reached または monthly limit exhausted などの周期的な使用量ウィンドウ制限も含みます。フォーマット/無効リクエストエラーは通常終端的です。同じペイロードを再試行しても同じように失敗するため、OpenClaw は認証プロファイルをローテーションするのではなく、それらを表示します。既知の再試行修復パスは明示的にオプトインできます。たとえば Cloud Code Assist ツール呼び出し ID 検証失敗はサニタイズされ、allowFormatRetry ポリシーを通じて1回再試行されます。Unhandled stop reason: error, stop reason: error, reason: error などの OpenAI 互換停止理由エラーは、タイムアウト/フェイルオーバー信号として分類されます。ソースが既知の一時的パターンと一致する場合、汎用サーバーテキストもそのタイムアウトバケットに入ることがあります。たとえば、素のモデルランタイムストリームラッパーメッセージ An unknown error occurred は、すべてのプロバイダーでフェイルオーバー相当として扱われます。これは、共有モデルランタイムが、具体的な詳細なしで stopReason: "aborted" または stopReason: "error" によりプロバイダーストリームが終了したときにそのメッセージを発行するためです。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. のような汎用的な内部フォールバックテキストは保守的な扱いのままで、それ自体ではフェイルオーバーをトリガーしません。SDK retry-after 上限
SDK retry-after 上限
一部のプロバイダー SDK は、OpenClaw に制御を戻す前に長い
Retry-After ウィンドウの間スリープすることがあります。Anthropic や OpenAI などの Stainless ベース SDK では、OpenClaw は SDK 内部の retry-after-ms / retry-after 待機をデフォルトで 60 秒に上限設定し、より長い再試行可能なレスポンスを即座に表面化させることで、このフェイルオーバーパスを実行できるようにします。上限は OPENCLAW_SDK_RETRY_MAX_WAIT_SECONDS で調整または無効化できます。再試行動作を参照してください。モデルスコープのクールダウン
モデルスコープのクールダウン
レート制限のクールダウンは、モデルスコープにすることもできます。
- OpenClaw は、失敗したモデル id が分かっている場合、レート制限失敗に対して
cooldownModelを記録します。 - クールダウンが別のモデルにスコープされている場合、同じプロバイダー上の兄弟モデルは引き続き試行できます。
- 請求/無効化ウィンドウは、モデルをまたいでプロファイル全体を引き続きブロックします。
- 1 回目の失敗: 30 秒
- 2 回目の失敗: 1 分
- 3 回目以降の失敗: 5 分(上限)
auth.cooldowns.failureWindowHours、デフォルト 24)が経過すると、カウンターはリセットされます。
状態は、エージェントごとの SQLite 認証状態の usageStats に保存されます。
請求による無効化
請求/クレジット失敗(たとえば “insufficient credits” / “credit balance too low”)はフェイルオーバー対象として扱われますが、通常は一時的なものではありません。短いクールダウンではなく、OpenClaw はプロファイルを disabled(より長いバックオフ付き)としてマークし、次のプロファイル/プロバイダーへローテーションします。請求の形をしたレスポンスがすべて
402 とは限らず、HTTP 402 がすべてここに到達するわけでもありません。OpenClaw は、プロバイダーが代わりに 401 または 403 を返した場合でも、明示的な請求テキストを請求レーンに保持しますが、プロバイダー固有のマッチャーは、それを所有するプロバイダーにスコープされたままです(たとえば OpenRouter 403 Key limit exceeded)。一方で、一時的な 402 の使用ウィンドウおよび組織/ワークスペースの支出上限エラーは、メッセージが再試行可能に見える場合(たとえば weekly usage limit exhausted、daily limit reached, resets tomorrow、または organization spending limit exceeded)、rate_limit として分類されます。これらは、長い請求無効化パスではなく、短いクールダウン/フェイルオーバーパスに残ります。auth.cooldowns.*):
| キー | デフォルト | 目的 |
|---|---|---|
billingBackoffHours | 5 | 基本の請求バックオフ。請求失敗ごとに倍増 |
billingMaxHours | 24 | 請求バックオフの上限 |
authPermanentBackoffMinutes | 10 | 信頼度の高い永続的な認証失敗の基本バックオフ |
authPermanentMaxMinutes | 60 | そのバックオフの上限 |
failureWindowHours | 24 | このウィンドウ内に失敗が発生しない場合、失敗カウンターをリセット |
overloadedProfileRotations | 1 | 過負荷時のモデルフォールバック前に許可される同一プロバイダーのプロファイルローテーション |
overloadedBackoffMs | 0 | 過負荷ローテーション再試行前の固定遅延 |
rateLimitedProfileRotations | 1 | レート制限時のモデルフォールバック前に許可される同一プロバイダーのプロファイルローテーション |
モデルフォールバック
プロバイダーのすべてのプロファイルが失敗した場合、OpenClaw はagents.defaults.model.fallbacks の次のモデルへ移動します。これは、認証失敗、レート制限、およびプロファイルローテーションを使い切ったタイムアウトに適用されます(その他のエラーではフォールバックは進みません)。十分な詳細を公開しないプロバイダーエラーも、フォールバック状態では正確にラベル付けされます。empty_response はプロバイダーが使用可能なメッセージまたはステータスを返さなかったことを意味し、no_error_details はプロバイダーが明示的に Unknown error (no error details in response) を返したことを意味し、unclassified は OpenClaw が生のプレビューを保持したものの、まだどの分類器にも一致していないことを意味します。
ModelNotReadyException などのプロバイダー混雑シグナルは過負荷バケットに入り、レート制限と同じ 1 回ローテーションしてからフォールバックするポリシーに従います(上のデフォルト表を参照)。
実行が、設定されたデフォルトのプライマリ、cron ジョブのプライマリ、明示的なフォールバックを持つエージェントのプライマリ、または自動選択されたフォールバックオーバーライドから開始される場合、OpenClaw は一致する設定済みフォールバックチェーンをたどることができます。明示的なフォールバックを持たないエージェントのプライマリ、および明示的なユーザー選択(たとえば /model ollama/qwen3.5:27b、モデルピッカー、sessions.patch、または 1 回限りの CLI プロバイダー/モデルオーバーライド)は厳密です。そのプロバイダー/モデルに到達できない、または返信を生成する前に失敗した場合、OpenClaw は無関係なフォールバックから回答するのではなく、失敗を報告します。
候補チェーンのルール
OpenClaw は、現在リクエストされているprovider/model と設定済みフォールバックから候補リストを構築します。
ルール
ルール
- リクエストされたモデルは常に最初です。
- 明示的に設定されたフォールバックは重複排除されますが、モデル許可リストではフィルタリングされません。これらは明示的なオペレーターの意図として扱われます。
- 現在の実行が同じプロバイダーファミリー内の設定済みフォールバック上にすでにある場合、OpenClaw は設定済みチェーン全体を使い続けます。
- 明示的なフォールバックオーバーライドが指定されていない場合、リクエストされたモデルが別のプロバイダーを使用していても、設定済みフォールバックが設定済みプライマリより先に試行されます。
- フォールバックランナーに明示的なフォールバックオーバーライドが指定されていない場合、チェーンの末尾に設定済みプライマリが追加されるため、前の候補を使い切った後に通常のデフォルトへ戻ることができます。
- 呼び出し元が
fallbacksOverrideを指定した場合、ランナーはリクエストされたモデルとそのオーバーライドリストを正確に使用します。空のリストはモデルフォールバックを無効化し、設定済みプライマリが隠れた再試行ターゲットとして追加されるのを防ぎます。
フォールバックを進めるエラー
- 継続する場合
- 継続しない場合
- 認証失敗
- レート制限とクールダウン枯渇
- 過負荷/プロバイダー混雑エラー
- タイムアウト型のフェイルオーバーエラー
- 請求による無効化
LiveSessionModelSwitchError。これはフェイルオーバーパスに正規化され、古い永続化モデルが外側の再試行ループを作らないようにします- 候補がまだ残っている場合の、その他の未認識エラー
クールダウンのスキップとプローブ動作
プロバイダーのすべての認証プロファイルがすでにクールダウン中の場合、OpenClaw はそのプロバイダーを永久に自動スキップするわけではありません。候補ごとに判断します。候補ごとの判断
候補ごとの判断
- 永続的な認証失敗は、プロバイダー全体を即座にスキップします。
- 請求による無効化は通常スキップしますが、プライマリ候補はスロットル付きで引き続きプローブできるため、再起動なしで回復できます。
- プライマリ候補は、クールダウン期限の近くで、プロバイダーごとのスロットル付きでプローブされることがあります。
- 失敗が一時的に見える場合(
rate_limit、overloaded、または不明)、同一プロバイダーのフォールバック兄弟はクールダウン中でも試行できます。これは、レート制限がモデルスコープで、兄弟モデルが即座に回復できる可能性がある場合に特に重要です。 - 一時的なクールダウンプローブは、単一のプロバイダーがプロバイダー横断フォールバックを停滞させないよう、フォールバック実行ごとにプロバイダーあたり 1 回に制限されます。
セッションオーバーライドとライブモデル切り替え
セッションモデル変更は共有状態です。アクティブなランナー、/model コマンド、Compaction/セッション更新、ライブセッション照合はすべて、同じセッションエントリの一部を読み書きします。
つまり、フォールバック再試行はライブモデル切り替えと連携する必要があります。
- 明示的なユーザー主導のモデル変更だけが、保留中のライブ切り替えをマークします。これには
/model、session_status(model=...)、sessions.patchが含まれます。 - フォールバックローテーション、Heartbeat オーバーライド、Compaction などのシステム主導のモデル変更は、それ自体では保留中のライブ切り替えをマークしません。
- ユーザー主導のモデルオーバーライドは、フォールバックポリシーでは正確な選択として扱われるため、到達不能な選択済みプロバイダーは
agents.defaults.model.fallbacksによって隠されるのではなく、失敗として表面化します。 - フォールバック再試行が開始される前に、返信ランナーは選択されたフォールバックオーバーライドフィールドをセッションエントリに永続化します。
- 自動フォールバックオーバーライドは後続ターンでも選択されたままになるため、OpenClaw は既知の不良プライマリをメッセージごとにプローブしません。OpenClaw は設定済みの起点を定期的に再プローブし、回復したら自動オーバーライドをクリアします。
/new、/reset、sessions.resetは自動由来のオーバーライドを即座にクリアします。 - ユーザーへの返信では、フォールバック遷移とフォールバック解除による回復を、状態変更ごとに 1 回通知します。固定されたフォールバックのターンでは通知を繰り返しません。
/statusは選択されたモデルを表示し、フォールバック状態が異なる場合は、アクティブなフォールバックモデルと理由を表示します。- ライブセッション照合では、古いランタイムモデルフィールドよりも、永続化されたセッションオーバーライドを優先します。
- ライブ切り替えエラーがアクティブなフォールバックチェーン内の後続候補を指している場合、OpenClaw は無関係な候補を先にたどるのではなく、その選択済みモデルへ直接ジャンプします。
- フォールバック試行が失敗した場合、ランナーは自分が書き込んだオーバーライドフィールドだけをロールバックし、それらがまだその失敗した候補と一致している場合に限ります。
永続化されたフォールバックオーバーライドがそのウィンドウを閉じ、狭いロールバックによって、より新しい手動またはランタイムのセッション変更をそのまま保持します。
可観測性と失敗サマリー
runWithModelFallback(...) は、ログとユーザー向けクールダウンメッセージに渡される試行ごとの詳細を記録します。
- 試行されたプロバイダー/モデル
- 理由(
rate_limit、overloaded、billing、auth、model_not_found、および同様のフェイルオーバー理由) - 任意のステータス/コード
- 人間が読めるエラー概要
model_fallback_decision ログには、候補が失敗した、スキップされた、または後続のフォールバックが成功した場合に、フラットな fallbackStep* フィールドも含まれます。これらのフィールドは、試行された遷移を明示します(fallbackStepFromModel、fallbackStepToModel、fallbackStepFromFailureReason、fallbackStepFromFailureDetail、fallbackStepFinalOutcome)。これにより、最終的なフォールバックも失敗した場合でも、ログおよび診断エクスポーターはプライマリの失敗を再構築できます。
すべての候補が失敗すると、OpenClaw は FallbackSummaryError をスローします。外側の返信ランナーはこれを使用して、「すべてのモデルが一時的にレート制限されています」のような、より具体的なメッセージを作成し、既知の場合は最短のクールダウン期限を含めることができます。
そのクールダウン概要はモデルを認識します。
- 関係のないモデルスコープのレート制限は、試行されたプロバイダー/モデルチェーンでは無視されます
- 残っているブロックが一致するモデルスコープのレート制限である場合、OpenClaw はそのモデルをまだブロックしている最後の一致期限を報告します
関連設定
以下については Gateway 設定 を参照してください。auth.profiles/auth.orderauth.cooldowns.billingBackoffHours/auth.cooldowns.billingBackoffHoursByProviderauth.cooldowns.billingMaxHours/auth.cooldowns.failureWindowHoursauth.cooldowns.authPermanentBackoffMinutes/auth.cooldowns.authPermanentMaxMinutesauth.cooldowns.overloadedProfileRotations/auth.cooldowns.overloadedBackoffMsauth.cooldowns.rateLimitedProfileRotationsagents.defaults.model.primary/agents.defaults.model.fallbacksagents.defaults.imageModelルーティング