Claude Platform Docs
MessaggiSviluppare con Claude

Rifiuti e fallback

Come i modelli Claude Fable, i modelli Claude Opus, Claude Sonnet 5.5 e Claude Haiku 5.5 restituiscono i rifiuti dei classificatori e come ritentare le richieste rifiutate su un modello di fallback.

Claude Fable 5.1, Claude Fable 5, Claude Opus 5.5, Claude Opus 5, Claude Sonnet 5.5 e Claude Haiku 5.5 includono classificatori di sicurezza che possono declinare una richiesta. Quando ciò accade, ricevi una risposta normale, non un errore, con stop_reason: "refusal". Il suo stop_details.category indica l'area di policy (vedi Come appare un rifiuto). Di solito puoi comunque ottenere una risposta inviando la stessa richiesta a un altro modello Claude. Questa pagina mostra come riconoscere un "refusal" (rifiuto) e come configurare quel nuovo tentativo, detto "fallback" (ripiego).

Leggi questa pagina se sviluppi su uno di questi modelli e vuoi che le richieste rifiutate passino automaticamente a un altro modello. È utile anche se hai visto "refusal" in una risposta e vuoi sapere come procedere.

Pagine correlate:

La configurazione più semplice, in beta sulla Claude API: imposta fallbacks su "default" e l'API ritenta una richiesta rifiutata sul modello di fallback che Anthropic raccomanda per la sua categoria di rifiuto. Per le categorie senza un fallback raccomandato, il rifiuto resta valido. Claude Haiku 5.5 non ha un fallback lato server, quindi per questo modello usa il fallback lato client con il middleware SDK oppure scrivi tu stesso il nuovo tentativo.

client = Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    fallbacks="default",
    betas=["server-side-fallback-2026-07-01"],
)
print(response.model)

Le sezioni seguenti descrivono il contenuto di una risposta di rifiuto, quando usare il fallback lato server o lato client e come viene fatturato ciascuno.

Come appare un rifiuto

Un rifiuto è una risposta HTTP 200 riuscita con stop_reason: "refusal":

{
  "id": "msg_01XFUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "model": "claude-fable-5",
  "content": [],
  "stop_reason": "refusal",
  "stop_details": {
    "type": "refusal",
    "category": "cyber",
    "explanation": "This request was declined because it could enable cyber harm."
  },
  "usage": {
    "input_tokens": 412,
    "output_tokens": 0
  }
}

L'oggetto stop_details spiega il rifiuto:

  • category: indica l'area di policy che ha attivato il classificatore.
  • explanation: una descrizione leggibile. Il testo non è stabile, quindi visualizzalo anziché analizzarlo.
  • recommended_model: presente solo nelle richieste che impostano fallbacks (fallback lato server, beta). Indica un modello su cui ritentare direttamente quando l'API ha saltato il tentativo di fallback (ad esempio, il modello di fallback era soggetto a limite di velocità), ed è null altrimenti. È un suggerimento, non una garanzia.
  • category ed explanation sono entrambi null quando il rifiuto non corrisponde a una categoria denominata. Quel null è un valore normale e permanente, non un segnaposto.
  • stop_details stesso è null per ogni motivo di arresto diverso da refusal.
categoryCosa significaFatturato prima di qualsiasi output
"cyber"La richiesta potrebbe favorire danni informatici, come lo sviluppo di malware o exploit. Anche il lavoro di cybersecurity benigno può attivare questa categoria.No
"bio"La richiesta potrebbe favorire danni biologici, come metodi di laboratorio pericolosi. Anche il lavoro benefico nelle scienze della vita può attivare questa categoria.Sì
"frontier_llm"La richiesta potrebbe assistere lo sviluppo di modelli di IA concorrenti, il che è limitato dai termini commerciali di Anthropic. Anche il lavoro benigno di machine learning può attivare questa categoria.Sì
"reasoning_extraction"La richiesta chiede al modello di riprodurre il suo ragionamento interno nel testo della risposta. Per ottenere invece il ragionamento in forma strutturata, usa il ragionamento adattivo. Vedi Mantieni il ragionamento nei blocchi di ragionamento.Sì
"general_harms"La richiesta rientra in un'area della policy di utilizzo al di fuori delle quattro categorie denominate. Anche il lavoro benigno può attivare questa categoria.No

Un rifiuto può arrivare prima di qualsiasi output, oppure a metà streaming dopo un output parziale. In entrambi i casi, tratta qualsiasi output parziale come incompleto e scartalo.

Mantieni il ragionamento nei blocchi di ragionamento

Un rifiuto reasoning_extraction deriva di solito da un prompt che chiede al modello di inserire il suo ragionamento nell'output, alla lettera o in un formato fisso. Esempi comuni:

  • Una sezione <thinking>, <reasoning> o di appunti che il modello compila prima di rispondere
  • Un campo reasoning, thinking o trace nell'output JSON o nell'input di uno strumento
  • Le note private del modello, o un registro continuo del suo ragionamento
  • Ragionamento richiesto alla lettera o per intero

La formulazione può trovarsi in un prompt di sistema, in una skill o nella descrizione di uno strumento, quindi controlla anche quelli.

Puoi comunque chiedere a Claude di spiegare la sua risposta. Chiedi una breve spiegazione, le prove alla base di un risultato o un riepilogo delle azioni intraprese. Per vedere come ha ragionato il modello, imposta display: "summarized" e leggi i blocchi thinking. Questa categoria non ha un modello di fallback raccomandato, quindi modifica il prompt anziché ritentare la richiesta. Se una richiesta riformulata viene ancora declinata, contatta il supporto e includi l'ID della richiesta.

Come vengono fatturati i rifiuti

Queste regole di fatturazione si applicano su ogni piattaforma: la Claude API, Amazon Bedrock, Claude Platform on AWS, Google Cloud e Microsoft Foundry.

Rifiuti prima di qualsiasi output: per contrastare i tentativi di aggirare su larga scala le salvaguardie di Anthropic, un rifiuto che arriva prima di qualsiasi output viene fatturato quando il suo stop_details.category è "bio", "frontier_llm" o "reasoning_extraction". Queste sono le categorie in cui Anthropic misura bassi volumi di falsi positivi, a settembre 2026. Questi rifiuti vengono fatturati come qualsiasi altra richiesta, alle tariffe del modello che l'ha eseguita. Un rifiuto prima di qualsiasi output in qualsiasi altra categoria, o con categoria null, non viene fatturato. In ogni caso, content è vuoto e i conteggi dei token compaiono in usage. La richiesta conta comunque ai fini dei tuoi limiti di velocità.

Rifiuti a metà streaming: un rifiuto a metà streaming addebita i token di input e l'output già trasmesso alle tariffe normali.

Fallback: quando usi il fallback, il rifiuto che lo ha attivato viene fatturato, in aggiunta alla richiesta di fallback, quando è arrivato a metà streaming o rientra in una delle categorie fatturate. Il credito di fallback compensa il mancato riscontro nella cache dei prompt da parte della richiesta di fallback, così non paghi due volte per memorizzare in cache la conversazione. Un rifiuto di Claude Haiku 5.5 non comporta alcun credito di fallback, quindi un fallback successivo paga l'intero costo di scrittura della cache dei prompt del modello di fallback. Per sapere come il fallback lato server riporta ogni tentativo, vedi Fatturazione e limiti di velocità.

Le categorie fatturate possono cambiare man mano che Anthropic continua a misurare e perfezionare i tassi di falsi positivi delle proprie salvaguardie. La colonna Fatturato prima di qualsiasi output nella tabella delle categorie di rifiuto elenca le categorie fatturate.

Scegliere un approccio di fallback

Esistono tre modi per ritentare una richiesta rifiutata su un altro modello. Quello giusto dipende da dove stai eseguendo e da quanto controllo ti serve.

La tua situazioneUsaPerché
Claude API, configurazione più sempliceFallback lato serverUna richiesta, una risposta. L'API gestisce il nuovo tentativo.
Qualsiasi piattaforma, usando un SDK AnthropicIl middleware SDKConfigura una volta sul client. I nuovi tentativi avvengono automaticamente.
HTTP grezzo o logica di retry personalizzataUn nuovo tentativo manuale con credito di fallbackControllo completo. Il credito di fallback contiene i costi.

Il fallback lato server e il middleware SDK applicano il credito di fallback per te. Ti serve la pagina Credito di fallback solo quando costruisci tu stesso il nuovo tentativo. Claude Haiku 5.5 non ha né il fallback lato server né il credito di fallback, quindi usa il middleware SDK o un nuovo tentativo manuale.

Fallback lato server

Il fallback lato server ritenta una richiesta rifiutata all'interno di una singola chiamata API. Nella modalità predefinita, quando il modello primario declina e la categoria di rifiuto ha un fallback raccomandato, l'API esegue la stessa richiesta sul modello che Anthropic raccomanda per quella categoria. Puoi invece indicare fino a tre modelli di fallback a tua scelta. In entrambi i casi, ricevi una sola risposta che indica il modello che ha risposto, così il tuo utente ottiene una risposta in un solo round trip.

Effettuare la richiesta

Imposta il parametro fallbacks sulla stringa "default" e invia l'header beta server-side-fallback-2026-07-01. L'API applica quindi il routing predefinito definito dal server per il modello richiesto, che seleziona un modello di fallback raccomandato in base alla categoria di rifiuto riportata dal classificatore, così le richieste rifiutate vengono servite senza che tu debba mantenere un elenco di modelli man mano che le raccomandazioni cambiano.

Il routing predefinito non provoca mai il rifiuto anticipato per immagine sovradimensionata per modelli che non hai scelto: un modello instradato che ridimensionerebbe un'immagine contrassegnata con "oversized_image": "error" viene invece escluso dal routing, così un'immagine contrassegnata non viene mai servita ridimensionata.

client = Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    fallbacks="default",
    betas=["server-side-fallback-2026-07-01"],
)

# Una voce fallback_message in usage.iterations indica che è stato eseguito un modello di fallback;
# abbinala a stop_reason per confermare che il fallback abbia fornito la risposta.
fallback_ran = any(
    iteration.type == "fallback_message"
    for iteration in response.usage.iterations or []
)
served_by_fallback = fallback_ran and response.stop_reason != "refusal"

print(
    json.dumps(
        {
            "stop_reason": response.stop_reason,
            "model": response.model,
            "served_by_fallback": served_by_fallback,
        }
    )
)

Anthropic definisce le salvaguardie per ciascun modello individualmente e per ciascuna categoria di policy, in linea con le capacità del modello: a seconda della categoria, una richiesta segnalata può ricadere su un modello meno capace oppure essere declinata. La modalità "default" codifica per te queste raccomandazioni per modello e per categoria, così una richiesta rifiutata viene ritentata sul modello che Anthropic raccomanda per quella categoria. I fallback sono visibili in entrambi i casi: la risposta indica il modello che l'ha servita, e il blocco di contenuto fallback segna il passaggio di consegne.

Il routing viene applicato lato server e non è pubblicato per modello sulla Models API. Per vedere quale modello ha servito una richiesta rifiutata, controlla il campo model di primo livello della risposta e cerca una voce fallback_message in usage.iterations, come fanno gli esempi di questa pagina.

Solo un rifiuto del classificatore di sicurezza attiva il fallback. Un limite di velocità, un sovraccarico o un errore del server sul modello richiesto ti viene restituito così com'è.

Indicare i propri modelli di fallback

Invece del routing predefinito, puoi impostare fallbacks su un elenco di fino a tre modelli. Quando il modello richiesto declina, l'API esegue il modello successivo nella catena sulla stessa richiesta. Usa questa forma quando vuoi controllare esattamente quali modelli servono le richieste rifiutate, ad esempio fissando un modello che la tua applicazione ha qualificato.

I modelli di fallback indicati contano ai fini del controllo delle immagini sovradimensionate: una richiesta il cui blocco immagine imposta "oversized_image": "error" viene controllata in anticipo rispetto al modello richiesto e a ogni fallback indicato, viene rifiutata se uno qualsiasi di essi ridimensionerebbe quell'immagine, e la dimensione di ridimensionamento riportata nel rifiuto è adatta a tutti.

Le righe evidenziate sono l'unica differenza rispetto alla richiesta con routing predefinito.

client = Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    fallbacks=[{"model": "claude-opus-4-8"}],
    betas=["server-side-fallback-2026-07-01"],
)
print(response.model)

All'elenco fallbacks si applicano alcune regole:

  • Le voci vengono provate in ordine. Ciascuna deve essere diversa dalle altre voci e dal modello richiesto.
  • Ogni voce deve essere una delle destinazioni consentite per il modello richiesto. Con l'header beta impostato, quell'elenco è pubblicato come allowed_fallback_models nella voce del modello nella Models API.
  • Ogni voce indica un model e può sovrascrivere max_tokens, thinking, output_config e speed solo per quel tentativo.
  • La richiesta deve essere valida come richiesta diretta a ogni modello indicato. Se un modello di fallback non supporta una funzionalità usata dalla richiesta, l'API rifiuta la richiesta in anticipo. Con l'header 2026-07-01, thinking: {"type": "between_tools"} è l'eccezione: quando una richiesta a Claude Sonnet 5.5 ripiega su Claude Sonnet 5, il tentativo di fallback viene eseguito con thinking: {"type": "disabled"} e display: "omitted". Con 2026-06-01, imposta thinking nella voce di Claude Sonnet 5, altrimenti la richiesta viene rifiutata in anticipo.
  • Come nella modalità predefinita, solo un rifiuto da parte di un classificatore di sicurezza attiva il fallback. Un limite di velocità, un sovraccarico o un errore del server sul modello richiesto ti vengono restituiti così come sono.
  • Se un modello di fallback ha raggiunto il limite di velocità o è sovraccarico, il tentativo di fallback non viene effettuato e viene invece restituito il rifiuto precedente. Il campo stop_details.recommended_model del rifiuto indica allora un modello da ritentare direttamente. Dimensiona i limiti di velocità del modello di fallback in base al volume di rifiuti che prevedi, altrimenti sotto carico i fallback si riducono a rifiuti.

La risposta ha la stessa forma in entrambe le modalità: il modello che ha servito il turno compare nel campo model di primo livello, un blocco di contenuto fallback segna il passaggio di consegne, e usage.iterations registra ogni tentativo.

Cosa contiene la risposta

La risposta appare come qualsiasi altro messaggio, con due aggiunte:

  • Il campo model di primo livello riporta il modello che ha prodotto il messaggio restituito, sia esso il modello richiesto o un fallback.
  • Un blocco di contenuto fallback segna ogni punto in content in cui l'output di un modello cede il passo al successivo: {"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}.
    • from.model riprende la stringa del modello che hai inviato quando l'hop che declina è il modello richiesto.
    • to.model è sempre l'ID risolto del modello che prosegue.

In caso di rifiuto prima di qualsiasi output, il blocco fallback è il primo blocco di contenuto. Ad esempio, quando il routing predefinito seleziona Claude Opus 4.8 per la categoria del rifiuto:

{
  "id": "msg_01XFUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-4-8",
  "content": [
    {
      "type": "fallback",
      "from": { "model": "claude-fable-5" },
      "to": { "model": "claude-opus-4-8" }
    },
    { "type": "text", "text": "Hi! How can I help you today?" }
  ],
  "stop_reason": "end_turn",
  "stop_details": null,
  "usage": {
    "input_tokens": 412,
    "output_tokens": 264,
    "cache_read_input_tokens": 0,
    "cache_creation_input_tokens": 0,
    "iterations": [
      {
        "type": "message",
        "model": "claude-fable-5",
        "input_tokens": 535,
        "output_tokens": 0,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0
      },
      {
        "type": "fallback_message",
        "model": "claude-opus-4-8",
        "input_tokens": 412,
        "output_tokens": 264,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0
      }
    ]
  }
}

L'array usage.iterations registra ogni tentativo. Un modello che ha declinato compare come una normale voce message, e il modello che ha servito il turno compare come voce fallback_message. Se ogni modello nella catena declina, la risposta è il rifiuto dell'ultimo modello, con una voce message per ogni hop precedente e una voce fallback_message per l'ultimo.

Il routing persistente può inviare un turno successivo direttamente al modello di fallback. Un tale turno non contiene alcun blocco di contenuto fallback, perché nessun modello ha declinato quel turno. Identificalo dalla voce fallback_message in usage.iterations, dall'assenza di una voce message per il modello richiesto e dal campo model della risposta.

Continuare la conversazione

Al turno successivo, rimanda il contenuto dell'assistente così come l'hai ricevuto. Dopo un fallback a metà output, content può includere tipi di blocco che il modello che ha declinato ha prodotto prima del passaggio di consegne. La tabella seguente indica quali mantenere e quali eliminare quando riproponi il turno.

Tipo di bloccoAl turno successivo
fallbackMantienilo esattamente dove è comparso. L'API usa la sua posizione per validare i blocchi di ragionamento attorno a esso, quindi una richiesta che ripropone blocchi di ragionamento da entrambi i lati del confine viene rifiutata se il blocco è omesso o spostato.
textMantieni.
Qualsiasi blocco dopo l'ultimo blocco fallbackMantieni.
thinking, redacted_thinking o connector_text prima dell'ultimo blocco fallbackElimina.
tool_use lato client prima dell'ultimo blocco fallbackElimina.
server_tool_use prima dell'ultimo blocco fallbackMantieni quando è abbinato al suo risultato. Elimina quando non ha un risultato corrispondente.

Streaming

In una richiesta in streaming, il nuovo tentativo avviene sullo stesso stream, e nulla di ciò che hai già ricevuto viene invalidato. Ciò che vedi dipende da quando avviene il rifiuto.

Quando il rifiuto avviene prima di qualsiasi output:

  • message_start indica il modello di fallback, e il blocco fallback è il primo blocco di contenuto.
  • Poiché message_start attende l'avvio del tentativo di fallback, il tempo al primo byte include il tentativo declinato.

Quando il rifiuto avviene a metà output:

  • Il blocco di contenuto aperto si chiude, e il blocco fallback (una normale coppia content_block_start e content_block_stop senza delta) segna il confine.
  • Il modello di fallback prosegue dall'output parziale. Solo i blocchi text dell'output parziale vengono passati al modello di fallback come contesto. Gli altri tipi di blocco rimangono in content.
  • message_start ha già indicato il modello richiesto, quindi leggi il modello che ha servito dal to.model del blocco fallback e dalla voce fallback_message in usage.iterations dell'ultimo message_delta.

Risposte non in streaming

In una richiesta non in streaming, un rifiuto a metà output si comporta diversamente: la risposta omette l'output parziale del modello declinato, e il modello di fallback risponde da zero. Il risultato appare come un rifiuto prima di qualsiasi output, con il blocco fallback per primo. Il tentativo declinato e i suoi token di output compaiono comunque in usage.iterations.

Fatturazione e limiti di velocità

Ogni tentativo segue le regole descritte in Come vengono fatturati i rifiuti, alle tariffe del modello che lo ha eseguito. Un tentativo che ha declinato prima di produrre qualsiasi output viene fatturato solo quando la sua categoria di rifiuto è fatturata, e i suoi token sono riportati nella sua voce usage.iterations in ogni caso. Ogni tentativo che ha prodotto output, incluso uno che ha declinato a metà della sua risposta, viene fatturato separatamente. L'array usage.iterations è il registro per tentativo di ciò che ti viene fatturato. I conteggi usage di primo livello descrivono solo il tentativo che ha prodotto il messaggio restituito. I token di modelli diversi non vengono mai sommati in un unico campo.

Ogni tentativo eseguito, incluso uno che ha declinato, conta ai fini dei limiti di velocità del proprio modello.

Routing persistente

Dopo che una conversazione è passata al fallback, l'API registra quale modello l'ha servita. Le richieste successive per quella conversazione che includono fallbacks vanno direttamente a quel modello di fallback, senza eseguire il modello richiesto. Questo evita di pagare a ogni turno un tentativo che verrebbe prevedibilmente declinato di nuovo.

Alcune proprietà della decisione di routing:

  • Viene conservata per circa 1 ora ed è limitata alla tua organizzazione.
  • Viene memorizzata come hash del contenuto del prefisso della conversazione più il modello che l'ha servita. Il contenuto dei messaggi in sé non viene memorizzato.
  • È best-effort, quindi il tuo codice deve gestire il caso in cui il modello richiesto venga provato di nuovo in qualsiasi momento.

Il routing persistente si applica sia alle richieste in streaming sia a quelle non in streaming. In una richiesta in streaming, la decisione di routing viene presa prima dell'apertura dello stream, quindi il campo model dell'evento message_start contiene già l'ID del modello di fallback.

Fallback lato client con il middleware SDK

L'SDK include un middleware di fallback per i rifiuti. Lo configuri una volta sul client con il tuo elenco di modelli di fallback. Le chiamate tramite client.beta.messages ritentano quindi automaticamente le richieste rifiutate, su qualsiasi piattaforma. Il middleware invia anche l'header beta fallback-credit-2026-07-01 su ogni richiesta che gestisce, così i nuovi tentativi vengono riprezzati senza configurazione per singola richiesta. Un rifiuto di Claude Haiku 5.5 non comporta alcun credito di fallback, quindi un nuovo tentativo successivo paga l'intero costo di scrittura della cache dei prompt del modello di fallback.

Configurazione

Passa BetaRefusalFallbackMiddleware al costruttore del client e condividi una singola istanza di BetaFallbackState tra le richieste di una conversazione.

from anthropic import Anthropic, BetaFallbackState, BetaRefusalFallbackMiddleware

# In caso di rifiuto, il middleware riprova con il modello di fallback indicato e
# invia automaticamente l'header beta fallback-credit a ogni richiesta che gestisce.
client = Anthropic(
    middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
)

state = BetaFallbackState()  # pins follow-ups to the model that accepted

# Streaming: in caso di rifiuto il middleware riprova con il modello di fallback e
# innesta i suoi eventi nello stream aperto.
with (
    state,
    client.beta.messages.stream(
        max_tokens=1024,
        model="claude-fable-5",
        messages=[{"role": "user", "content": "Hello, Claude"}],
    ) as stream,
):
    for text in stream.text_stream:
        print(text, end="", flush=True)
    final_message = stream.get_final_message()
print(f"\nserved by: {final_message.model}")

# Non-streaming: riutilizzare lo stato mantiene la conversazione fissata.
with state:
    message = client.beta.messages.create(
        max_tokens=1024,
        model="claude-fable-5",
        messages=[{"role": "user", "content": "Hello, Claude"}],
    )
print(f"served by: {message.model}")

Come si comporta

  • I nuovi tentativi scorrono il tuo elenco di fallback in ordine. Un modello di fallback che a sua volta rifiuta passa la richiesta alla voce successiva.
  • Quando tutti i modelli dell'elenco hanno rifiutato, il middleware restituisce il rifiuto finale (la risposta di rifiuto dell'ultimo modello) anziché sollevare un errore.
  • I blocchi di ragionamento di Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5, Claude Haiku 5.5 o Claude Fable 5 passano invariati. Ogni nuovo tentativo reinvia il corpo della richiesta originale, e gli unici blocchi che il middleware rimuove dalla cronologia della conversazione nelle richieste successive sono i blocchi di confine fallback che ha aggiunto esso stesso. Il modello di fallback non può leggere i blocchi di Claude Fable 5.1, che solo Claude Fable 5.1 e Claude Mythos 5.1 leggono, quindi l'API li elimina. L'API elimina anche i blocchi di Claude Opus 5.5 per ogni modello di fallback tranne Claude Fable 5.1 e Claude Mythos 5.1 (vedi Cambiare modello a metà conversazione). Elimina anche i blocchi di Claude Sonnet 5.5, per ogni modello di fallback tranne Claude Opus 5.5 sulla Claude API e su Google Cloud. Claude Opus 5.5 e Claude Sonnet 5.5 leggono i blocchi di Claude Haiku 5.5 sulla Claude API e su Google Cloud, e l'API li elimina per un modello di fallback che non può leggerli.
  • Le risposte servite tramite il middleware includono un blocco di contenuto fallback a ogni confine tra modelli, come le risposte del fallback lato server. Il middleware gestisce questi blocchi al posto tuo nelle richieste successive.
  • Il modello che ha accettato viene registrato in BetaFallbackState, quindi le richieste successive che condividono lo stato restano fissate su di esso anziché interrogare di nuovo un modello che ha rifiutato.

Scrivere il nuovo tentativo da soli

Su HTTP grezzo o con logica di retry personalizzata, implementa il pattern che il middleware racchiude:

  1. Rileva il rifiuto

    Controlla se la risposta contiene stop_reason: "refusal".

  2. Rinvia su un modello di fallback

    Invia la stessa richiesta con model impostato su un modello di fallback, come Claude Opus 4.8. Se la richiesta rifiutata ha inviato thinking: {"type": "between_tools"}, modifica prima thinking: solo Claude Sonnet 5.5 accetta quel valore, quindi ometti thinking o imposta un valore che il modello di fallback accetta. Il fallback lato server con l'header 2026-07-01 effettua questa modifica per te quando ripiega su Claude Sonnet 5. Un altro modello può normalmente servire una richiesta che Claude Fable 5.1 o Claude Fable 5 declina. Il modo in cui gestisci la cronologia della conversazione dipende dal fatto che tu riscatti o meno un credito di fallback:

    • Senza riscattare un credito: puoi lasciare al loro posto i blocchi thinking e redacted_thinking precedenti oppure rimuoverli per risparmiare token di input. In ogni caso, il modello di fallback normalmente non può usarli: solo Claude Fable 5.1 e Claude Mythos 5.1 leggono i blocchi di Claude Fable 5.1, e solo questi due modelli, insieme a Claude Fable 5 e Claude Mythos 5, leggono i blocchi di Claude Fable 5, quindi per qualsiasi altro modello di fallback l'API li elimina. L'API elimina anche i blocchi di Claude Opus 5.5 per ogni modello di fallback tranne Claude Fable 5.1 e Claude Mythos 5.1 (vedi Cambiare modello a metà conversazione). Elimina anche i blocchi di Claude Sonnet 5.5, per ogni modello di fallback tranne Claude Opus 5.5 sulla Claude API e su Google Cloud. Un nuovo tentativo dopo un rifiuto di Claude Haiku 5.5 rientra sempre in questo caso. Claude Opus 5.5 e Claude Sonnet 5.5 leggono i blocchi di Claude Haiku 5.5 sulla Claude API e su Google Cloud, quindi lascia quei blocchi al loro posto quando passi a uno di questi modelli su tali piattaforme. Per un modello di fallback che non può leggerli, l'API li elimina senza fatturarli.
    • Riscattando un credito: invia il corpo invariato, perché il riscatto richiede una corrispondenza esatta. Il server gestisce i blocchi di ragionamento del modello precedente durante un riscatto, quindi non rimuoverli (vedi Campi che devono corrispondere alla richiesta rifiutata).
  3. Resta sul modello di fallback

    Per le conversazioni a più turni, continua a usare il modello di fallback per i turni successivi anziché tornare al modello precedente.

Un nuovo tentativo manuale scrive da zero la cache dei prompt del modello di fallback, il che costa più che leggere una cache esistente. Il credito di fallback rimborsa quel costo; riscattalo a ogni nuovo tentativo che costruisci tu stesso. Un rifiuto di Claude Haiku 5.5 non comporta alcun credito di fallback, quindi un nuovo tentativo successivo paga l'intero costo di scrittura della cache dei prompt del modello di fallback.

Rifiuti nei Message Batches

Una richiesta rifiutata in un Message Batch torna come result.type: "succeeded" con stop_reason: "refusal". I risultati batch contengono lo stesso oggetto stop_details delle risposte sincrone, quindi puoi rilevare i rifiuti tramite stop_reason o stop_details.type. Una differenza: i rifiuti batch non generano crediti di fallback, quindi stop_details su un risultato batch non include mai un fallback_credit_token.

Il fallback lato server non è disponibile per i batch (una richiesta batch che include fallbacks produce un risultato in errore per elemento). Per ritentare gli elementi batch rifiutati:

  1. Raccogli gli elementi rifiutati dai risultati.
  2. Lascia al loro posto i blocchi di ragionamento nelle cronologie multi-turno, oppure rimuovili per risparmiare token di input. Per un modello di fallback che non può leggerli, l'API li elimina senza fatturarli, come in un nuovo tentativo manuale.
  3. Se un elemento rifiutato ha inviato thinking: {"type": "between_tools"}, ometti thinking o imposta un valore accettato dal modello di fallback. Solo Claude Sonnet 5.5 accetta between_tools.
  4. Reinviali su un modello di fallback come nuovo batch o come richieste dirette.

Errori comuni

  • Ritenta su un modello diverso. Reinviare una richiesta rifiutata allo stesso modello di solito produce un altro rifiuto. Indirizza il nuovo tentativo al modello di fallback.
  • Prevedi un budget di nuovi tentativi per richiesta, non per turno o per sessione. Un singolo turno può produrre diversi rifiuti, ad esempio un agente più i suoi sotto-agenti.
  • Configura il fallback su ogni percorso di richiesta. Gestori di retry, rami di recupero errori e worker in background ne hanno tutti bisogno. Un gestore che riemette una richiesta senza fallback perde la protezione proprio sulle richieste che più probabilmente ne hanno bisogno.
  • Dai alle chiamate dei sotto-agenti il proprio fallback. Il parametro fallbacks non si propaga alle chiamate al modello effettuate dall'interno dell'esecuzione degli strumenti.
  • Rendi il fallback una proprietà della richiesta, non dello stato ambientale. Un flag condiviso, un valore di configurazione in cache o un interruttore globale possono perdere la sincronizzazione e lasciare silenziosamente una richiesta non protetta. Quando non puoi confermare che il fallback sia attivo, configuralo anziché presumere che sia attivo.
  • Strumenta i rifiuti come segnale a sé. Un rifiuto è un HTTP 200, quindi il monitoraggio basato sui tassi di errore o sulle risposte 5xx non lo vede mai. Emetti un evento per ogni rifiuto e uno per ogni risposta servita tramite fallback (la voce fallback_message in usage.iterations contrassegna quest'ultima), quindi imposta un avviso sul divario tra i due conteggi.
  • Dirama su stop_reason o stop_details.type, non su content o sui campi interni di stop_details. L'oggetto stop_details è sempre presente in un rifiuto, ma i suoi campi category ed explanation possono essere null. Controlla direttamente che stop_reason sia uguale a "refusal".

Prossimi passi

Evita di pagare due volte il costo della cache dei prompt quando costruisci tu stesso il nuovo tentativo.

Ogni valore di stop_reason e come gestirlo.

Come funziona il middleware SDK, incluso l'helper di fallback per i rifiuti.

Sposta un'applicazione esistente su Claude Fable 5.1.

Was this page helpful?