Failover del modello
OpenClaw gestisce i guasti in due fasi:- Rotazione del profilo di autenticazione all’interno del provider corrente.
- Fallback del modello al modello successivo in
agents.defaults.model.fallbacks.
Flusso di runtime
Per una normale esecuzione testuale, OpenClaw valuta i candidati in questo ordine:- Il modello di sessione attualmente selezionato.
- I
agents.defaults.model.fallbacksconfigurati in ordine. - Il modello primario configurato alla fine, quando l’esecuzione è partita da un override.
- Risolve il modello di sessione attivo e la preferenza del profilo di autenticazione.
- Costruisce la catena dei candidati modello.
- Prova il provider corrente con le regole di rotazione/cooldown del profilo di autenticazione.
- Se quel provider è esaurito con un errore che giustifica il failover, passa al candidato modello successivo.
- Rende persistente l’override di fallback selezionato prima che inizi il retry, in modo che altri lettori della sessione vedano lo stesso provider/modello che il runner sta per usare.
- Se il candidato di fallback fallisce, esegue il rollback solo dei campi di override della sessione posseduti dal fallback quando corrispondono ancora a quel candidato fallito.
- Se tutti i candidati falliscono, genera un
FallbackSummaryErrorcon dettagli per tentativo e la scadenza di cooldown più vicina quando è nota.
providerOverridemodelOverrideauthProfileOverrideauthProfileOverrideSourceauthProfileOverrideCompactionCount
/model o aggiornamenti di rotazione della sessione
avvenuti mentre il tentativo era in esecuzione.
Archiviazione dell’autenticazione (chiavi + OAuth)
OpenClaw usa profili di autenticazione sia per le chiavi API sia per i token OAuth.- I segreti sono archiviati in
~/.openclaw/agents/<agentId>/agent/auth-profiles.json(legacy:~/.openclaw/agent/auth-profiles.json). - La configurazione
auth.profiles/auth.ordercontiene solo metadati + instradamento (nessun segreto). - File OAuth legacy solo per importazione:
~/.openclaw/credentials/oauth.json(importato inauth-profiles.jsonal primo utilizzo).
type: "api_key"→{ provider, key }type: "oauth"→{ provider, access, refresh, expires, email? }(+projectId/enterpriseUrlper alcuni provider)
ID profilo
I login OAuth creano profili distinti in modo che più account possano coesistere.- Predefinito:
provider:defaultquando non è disponibile alcuna email. - OAuth con email:
provider:<email>(ad esempiogoogle-antigravity:user@gmail.com).
~/.openclaw/agents/<agentId>/agent/auth-profiles.json sotto profiles.
Ordine di rotazione
Quando un provider ha più profili, OpenClaw sceglie un ordine come questo:- Configurazione esplicita:
auth.order[provider](se impostata). - Profili configurati:
auth.profilesfiltrati per provider. - Profili archiviati: voci in
auth-profiles.jsonper il provider.
- Chiave primaria: tipo di profilo (OAuth prima delle chiavi API).
- Chiave secondaria:
usageStats.lastUsed(meno recente per primo, all’interno di ciascun tipo). - I profili in cooldown/disabilitati vengono spostati in fondo, ordinati per scadenza più vicina.
Persistenza di sessione (favorevole alla cache)
OpenClaw blocca il profilo di autenticazione scelto per sessione per mantenere calde le cache del provider. Non ruota a ogni richiesta. Il profilo bloccato viene riutilizzato finché:- la sessione non viene reimpostata (
/new//reset) - non viene completata una compattazione (il conteggio di compattazione incrementa)
- il profilo non entra in cooldown/non viene disabilitato
/model …@<profileId> imposta un override dell’utente per quella sessione
e non viene ruotata automaticamente finché non inizia una nuova sessione.
I profili bloccati automaticamente (selezionati dal router di sessione) sono trattati come una preferenza:
vengono provati per primi, ma OpenClaw può ruotare verso un altro profilo in caso di rate limit/timeout.
I profili bloccati dall’utente restano vincolati a quel profilo; se falliscono e sono configurati fallback di modello,
OpenClaw passa al modello successivo invece di cambiare profilo.
Perché OAuth può “sembrare perso”
Se hai sia un profilo OAuth sia un profilo con chiave API per lo stesso provider, il round-robin può alternare tra loro da un messaggio all’altro a meno che non siano bloccati. Per forzare un singolo profilo:- Bloccalo con
auth.order[provider] = ["provider:profileId"], oppure - Usa un override per sessione tramite
/model …con un override del profilo (quando supportato dalla tua UI/superficie chat).
Cooldown
Quando un profilo fallisce a causa di errori di autenticazione/rate limit (o di un timeout che sembra un rate limit), OpenClaw lo mette in cooldown e passa al profilo successivo. Quel bucket di rate limit è più ampio del semplice429: include anche messaggi del provider
come Too many concurrent requests, ThrottlingException,
concurrency limit reached, workers_ai ... quota limit exceeded,
throttled, resource exhausted e limiti periodici di finestra d’uso come
weekly/monthly limit reached.
Gli errori di formato/richiesta non valida (ad esempio i fallimenti di
validazione dell’ID tool call di Cloud Code Assist) sono trattati come idonei al failover e usano gli stessi cooldown.
Gli errori OpenAI-compatible di stop reason come Unhandled stop reason: error,
stop reason: error e reason: error sono classificati come segnali di timeout/failover.
Anche testo generico di errore server con ambito provider può finire in quel bucket di timeout quando
la sorgente corrisponde a un pattern transitorio noto. Ad esempio, il semplice
An unknown error occurred di Anthropic e i payload JSON api_error con testo transitorio del server
come internal server error, unknown error, 520, upstream error
o backend error sono trattati come timeout idonei al failover. Anche il testo generico upstream specifico di
OpenRouter come Provider returned error viene trattato come
timeout solo quando il contesto del provider è effettivamente OpenRouter. Il testo generico di fallback interno
come LLM request failed with an unknown error. resta
conservativo e non attiva il failover da solo.
I cooldown dei rate limit possono anche avere ambito modello:
- OpenClaw registra
cooldownModelper i fallimenti da rate limit quando l’ID del modello che ha fallito è noto. - Un modello fratello sullo stesso provider può ancora essere provato quando il cooldown è limitato a un modello diverso.
- Le finestre di billing/disabilitazione continuano invece a bloccare l’intero profilo su tutti i modelli.
- 1 minuto
- 5 minuti
- 25 minuti
- 1 ora (limite massimo)
auth-profiles.json sotto usageStats:
Disabilitazioni per billing
I fallimenti di billing/credito (ad esempio “insufficient credits” / “credit balance too low”) sono trattati come idonei al failover, ma di solito non sono transitori. Invece di un breve cooldown, OpenClaw contrassegna il profilo come disabilitato (con un backoff più lungo) e passa al profilo/provider successivo. Non tutte le risposte che sembrano di billing sono402, e non tutti gli HTTP 402 finiscono
qui. OpenClaw mantiene il testo di billing esplicito nel percorso billing anche quando un
provider restituisce invece 401 o 403, ma i matcher specifici del provider restano
limitati al provider che li possiede (ad esempio OpenRouter 403 Key limit exceeded). Nel frattempo, gli errori temporanei 402 di finestra d’uso e
di limite di spesa di organizzazione/workspace sono classificati come rate_limit quando
il messaggio sembra ritentabile (ad esempio weekly usage limit exhausted, daily limit reached, resets tomorrow o organization spending limit exceeded).
Questi restano nel percorso di cooldown breve/failover invece del lungo
percorso di disabilitazione per billing.
Lo stato è archiviato in auth-profiles.json:
- Il backoff di billing parte da 5 ore, raddoppia a ogni errore di billing e ha un limite massimo di 24 ore.
- I contatori di backoff si azzerano se il profilo non fallisce per 24 ore (configurabile).
- I retry per overload consentono 1 rotazione dello stesso provider su un altro profilo prima del fallback del modello.
- I retry per overload usano per impostazione predefinita un backoff di 0 ms.
Fallback del modello
Se tutti i profili per un provider falliscono, OpenClaw passa al modello successivo inagents.defaults.model.fallbacks. Questo si applica a errori di autenticazione, rate limit e
timeout che hanno esaurito la rotazione del profilo (gli altri errori non fanno avanzare il fallback).
Gli errori di overload e rate limit sono gestiti in modo più aggressivo rispetto ai cooldown di billing. Per impostazione predefinita, OpenClaw consente un retry sullo stesso provider con un altro profilo di autenticazione,
poi passa al fallback di modello configurato successivo senza attendere.
I segnali di provider occupato come ModelNotReadyException finiscono in quel bucket di overload.
Regola questo comportamento con auth.cooldowns.overloadedProfileRotations,
auth.cooldowns.overloadedBackoffMs e
auth.cooldowns.rateLimitedProfileRotations.
Quando un’esecuzione parte con un override di modello (hook o CLI), i fallback terminano comunque su
agents.defaults.model.primary dopo aver provato eventuali fallback configurati.
Regole della catena di candidati
OpenClaw costruisce la lista dei candidati dalprovider/model
attualmente richiesto più i fallback configurati.
Regole:
- Il modello richiesto è sempre il primo.
- I fallback esplicitamente configurati vengono deduplicati ma non filtrati dalla allowlist dei modelli. Sono trattati come un’esplicita intenzione dell’operatore.
- Se l’esecuzione corrente è già su un fallback configurato nella stessa famiglia di provider, OpenClaw continua a usare l’intera catena configurata.
- Se l’esecuzione corrente è su un provider diverso dalla configurazione e quel modello corrente non fa già parte della catena di fallback configurata, OpenClaw non aggiunge fallback configurati non correlati da un altro provider.
- Quando l’esecuzione è partita da un override, il primario configurato viene aggiunto alla fine in modo che la catena possa tornare al normale valore predefinito una volta esauriti i candidati precedenti.
Quali errori fanno avanzare il fallback
Il fallback del modello continua in presenza di:- errori di autenticazione
- rate limit ed esaurimento del cooldown
- errori di overload/provider occupato
- errori di failover con forma di timeout
- disabilitazioni per billing
LiveSessionModelSwitchError, che viene normalizzato in un percorso di failover così che un modello persistente obsoleto non crei un ciclo di retry esterno- altri errori non riconosciuti quando ci sono ancora candidati rimanenti
- interruzioni esplicite che non hanno forma di timeout/failover
- errori di overflow del contesto che devono restare nella logica di compattazione/retry
(ad esempio
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 modeloollama error: context length exceeded) - un errore finale sconosciuto quando non restano candidati
Comportamento di salto del cooldown vs probe
Quando tutti i profili di autenticazione per un provider sono già in cooldown, OpenClaw non salta automaticamente quel provider per sempre. Prende una decisione per candidato:- I fallimenti persistenti di autenticazione saltano immediatamente l’intero provider.
- Le disabilitazioni per billing di solito vengono saltate, ma il candidato primario può ancora essere sondato con una limitazione di frequenza, in modo che il recupero sia possibile senza riavviare.
- Il candidato primario può essere sondato vicino alla scadenza del cooldown, con una limitazione per provider.
- I modelli fratelli di fallback sullo stesso provider possono essere provati nonostante il cooldown quando il
guasto sembra transitorio (
rate_limit,overloadedo sconosciuto). Questo è particolarmente rilevante quando un rate limit è limitato al modello e un modello fratello può ancora recuperare immediatamente. - I probe di cooldown transitori sono limitati a uno per provider per esecuzione di fallback, così che un singolo provider non blocchi il fallback tra provider diversi.
Override di sessione e live model switching
Le modifiche al modello di sessione sono stato condiviso. Il runner attivo, il comando/model,
gli aggiornamenti di compattazione/sessione e la riconciliazione della sessione live leggono o scrivono
tutti parti della stessa voce di sessione.
Questo significa che i retry di fallback devono coordinarsi con il live model switching:
- Solo le modifiche esplicite al modello guidate dall’utente contrassegnano un pending live switch. Questo
include
/model,session_status(model=...)esessions.patch. - Le modifiche al modello guidate dal sistema come rotazione di fallback, override heartbeat o compattazione non contrassegnano mai da sole un pending live switch.
- Prima che inizi un retry di fallback, il reply runner rende persistenti i campi di override del fallback selezionato nella voce di sessione.
- La riconciliazione della sessione live preferisce gli override persistenti della sessione rispetto ai campi runtime del modello obsoleti.
- Se il tentativo di fallback fallisce, il runner esegue il rollback solo dei campi di override che ha scritto, e solo se corrispondono ancora a quel candidato fallito.
- Il primario fallisce.
- Il candidato di fallback viene scelto in memoria.
- L’archivio della sessione dice ancora il vecchio primario.
- La riconciliazione della sessione live legge lo stato obsoleto della sessione.
- Il retry viene riportato al vecchio modello prima che inizi il tentativo di fallback.
Osservabilità e riepiloghi dei guasti
runWithModelFallback(...) registra dettagli per tentativo che alimentano i log e
la messaggistica di cooldown rivolta all’utente:
- provider/modello tentato
- motivo (
rate_limit,overloaded,billing,auth,model_not_founde motivi di failover simili) - stato/codice facoltativo
- riepilogo dell’errore leggibile da umani
FallbackSummaryError. Il
reply runner esterno può usarlo per costruire un messaggio più specifico, come “tutti i modelli
sono temporaneamente soggetti a rate limit”, e includere la scadenza di cooldown più vicina quando è nota.
Quel riepilogo del cooldown è consapevole del modello:
- i rate limit limitati a un modello ma non correlati vengono ignorati per la catena provider/modello tentata
- se il blocco rimanente è un rate limit limitato a un modello corrispondente, OpenClaw segnala l’ultima scadenza corrispondente che continua a bloccare quel modello
Configurazione correlata
Vedi Configurazione del Gateway per: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.imageModelrouting