Claude Fable 5 include classificatori di sicurezza che possono rifiutare una richiesta. Quando ciò accade, ricevi una risposta normale, non un errore, con stop_reason: "refusal". Di solito puoi comunque ottenere una risposta inviando la stessa richiesta a un altro modello Claude. Questa pagina mostra come riconoscere un rifiuto e come configurare quel nuovo tentativo.
Leggi questa pagina quando sviluppi con Claude Fable 5 e vuoi che le richieste rifiutate vengano automaticamente passate a un altro modello. Si applica anche quando hai appena visto "refusal" in una risposta e vuoi sapere cosa fare dopo.
Pagine correlate:
stop_reason.La configurazione più semplice: specifica un modello di fallback nella richiesta e l'API gestisce il nuovo tentativo.
client = Anthropic()
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-06-01"],
)Le sezioni seguenti trattano cosa contiene una risposta di rifiuto, quando usare il fallback lato server o lato client e come viene fatturato ciascuno.
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 dall'utente. Il testo non è stabile, quindi visualizzalo anziché analizzarlo.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.category | Cosa significa |
|---|---|
"cyber" | La richiesta potrebbe consentire danni informatici, come lo sviluppo di malware o exploit. Anche il lavoro legittimo di cybersecurity può attivare questa categoria. |
"bio" | La richiesta potrebbe consentire danni biologici, come metodi di laboratorio pericolosi. Anche il lavoro benefico nelle scienze della vita può attivare questa categoria. |
"frontier_llm" | La richiesta potrebbe assistere lo sviluppo di modelli di IA concorrenti, cosa limitata dai termini commerciali di Anthropic. Anche il lavoro legittimo di machine learning può attivare questa categoria. |
"reasoning_extraction" | La richiesta chiede al modello di riprodurre il proprio ragionamento interno nel testo della risposta. Per ottenere invece il ragionamento in forma strutturata, usa il pensiero adattivo. |
Un rifiuto può arrivare prima di qualsiasi output, oppure a metà stream dopo un output parziale. In entrambi i casi, considera qualsiasi output parziale come incompleto e scartalo.
Come vengono fatturati i rifiuti: Non ti viene addebitato un rifiuto che arriva prima di qualsiasi output. content è vuoto, i conteggi dei token appaiono in usage ma non vengono addebitati e la richiesta non viene conteggiata nei limiti di velocità. Un rifiuto a metà stream addebita i token di input e l'output già trasmesso in streaming alle tariffe normali.
Ci sono 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 situazione | Usa | Perché |
|---|---|---|
| Claude API o Claude Platform su AWS, configurazione più semplice | Fallback lato server | Una richiesta, una risposta. L'API gestisce il nuovo tentativo. |
| Qualsiasi piattaforma, con l'SDK TypeScript, Python, Go, Java o C# | Il middleware SDK | Configura una volta sul client. I nuovi tentativi avvengono automaticamente. |
| Ruby, PHP, HTTP grezzo o logica di retry personalizzata | Retry manuale con credito di fallback | Controllo completo. Il credito di fallback mantiene basso il costo. |
Il fallback lato server e il middleware SDK applicano il credito di fallback per te. Hai bisogno della pagina Credito di fallback solo quando costruisci tu stesso il retry.
Il fallback lato server ritenta una richiesta rifiutata all'interno di una singola chiamata API. Specifichi fino a tre modelli di fallback e, quando Claude Fable 5 rifiuta, l'API esegue il modello successivo nella catena sulla stessa richiesta. Ricevi una sola risposta che indica il modello che ha risposto, così il tuo utente ottiene una risposta in un solo round trip.
Il fallback lato server è in beta sulla Claude API e su Claude Platform su AWS. Il parametro fallbacks viene rifiutato sulla Message Batches API e non è disponibile su Amazon Bedrock, Google Cloud o Microsoft Foundry. Su quelle piattaforme, usa invece il middleware SDK.
Specifica i modelli di fallback nel parametro fallbacks e invia l'header beta server-side-fallback-2026-06-01.
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-06-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 ha 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,
}
)
)Alcune regole si applicano all'elenco fallbacks:
allowed_fallback_models nella voce del modello nella Models API.model e può sovrascrivere max_tokens e thinking solo per quel tentativo.L'header beta deve contenere esattamente la data 2026-06-01. Con qualsiasi altro valore server-side-fallback-*, il parametro fallbacks viene rifiutato con un errore 400. Se hai sviluppato su una preview precedente di questa funzionalità, aggiorna insieme l'header beta e le forme di richiesta e risposta a quelle presenti in questa pagina.
La risposta è simile a qualsiasi altro messaggio, con due aggiunte:
model di primo livello riporta il modello che ha prodotto il messaggio restituito, che sia il modello richiesto o un fallback.fallback segna ogni punto in content in cui l'output di un modello lascia il posto al successivo: {"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}.
from.model riporta la stringa del modello che hai inviato quando il passaggio che rifiuta è il modello richiesto.to.model è sempre l'ID risolto del modello che continua.In caso di rifiuto prima di qualsiasi output, il blocco fallback è il primo blocco di contenuto:
{
"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 rifiutato appare come una voce message ordinaria, e il modello che ha servito il turno appare come una voce fallback_message. Se ogni modello nella catena rifiuta, la risposta è il rifiuto dell'ultimo modello, con una voce message per ogni passaggio precedente e una voce fallback_message per l'ultimo.
Al turno successivo, rinvia 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 rifiutato ha prodotto prima del passaggio; la tabella seguente indica quali mantenere e quali eliminare quando riporti il turno.
| Tipo di blocco | Al turno successivo |
|---|---|
fallback | Mantienilo esattamente dove è apparso. L'API usa la sua posizione per validare i blocchi di pensiero intorno ad esso, quindi una richiesta che riporta blocchi di pensiero da entrambi i lati del confine viene rifiutata se il blocco viene omesso o spostato. |
text | Mantieni. |
Qualsiasi blocco dopo il blocco fallback finale | Mantieni. |
thinking, redacted_thinking o connector_text prima del blocco fallback finale | Elimina. |
tool_use lato client prima del blocco fallback finale | Elimina. |
server_tool_use prima del blocco fallback finale | Mantieni quando è abbinato al suo risultato. Elimina quando non ha un risultato corrispondente. |
Un blocco connector_text contiene testo narrativo che alcune risposte con uso degli strumenti includono tra le chiamate agli strumenti.
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.message_start attende l'avvio del tentativo di fallback, il tempo al primo byte include il tentativo rifiutato.Quando il rifiuto avviene a metà output:
fallback (una coppia ordinaria content_block_start e content_block_stop senza delta) segna il confine.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 serve dal to.model del blocco fallback e dalla voce fallback_message in usage.iterations del message_delta finale.In una richiesta non in streaming, un rifiuto a metà output si comporta diversamente: la risposta omette l'output parziale del modello rifiutato 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 rifiutato e i suoi token di output appaiono comunque in usage.iterations.
Rifiuti dopo l'esecuzione di strumenti server: quando un rifiuto si attiva dopo che gli strumenti server (ad esempio, ricerca web o esecuzione di codice) sono già stati eseguiti all'interno di una richiesta, l'API restituisce il rifiuto invece di passare a un modello di fallback. Se è impostato anche l'header fallback-credit-2026-06-01, quel rifiuto contiene un token di credito riscattabile continuando la risposta parziale, così il lavoro degli strumenti completato non va perso. Questo si applica solo agli strumenti server che iterano all'interno di una singola richiesta. Le conversazioni che usano strumenti lato client eseguono il fallback normalmente.
Gli SDK TypeScript, Python, Go, Java e C# includono 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-06-01 su ogni richiesta che gestisce, così i nuovi tentativi vengono riprezzati senza configurazione per richiesta.
L'helper middleware di fallback per i rifiuti non è ancora disponibile negli SDK Ruby e PHP. Su quegli SDK, implementa direttamente il pattern rileva-e-ritenta.
Passa il middleware al costruttore del client e condividi una singola istanza BetaFallbackState tra le richieste di una conversazione.
# In caso di rifiuto, il middleware riprova sul modello di fallback indicato e
# invia automaticamente l'header beta fallback-credit su 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 sul modello di fallback e
# inserisce 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 event in stream:
if event.type == "text":
print(event.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 ancorata.
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}")fallback a ogni confine tra modelli, come le risposte di fallback lato server. Il middleware gestisce quei blocchi per te nelle richieste successive.BetaFallbackState, così le richieste successive che condividono lo stato rimangono fissate su di esso anziché richiedere di nuovo a un modello che ha rifiutato.Il middleware e il parametro fallbacks lato server svolgono lo stesso compito. Configura l'uno o l'altro, mai entrambi sulla stessa richiesta. Per inviare una richiesta fallbacks lato server da un'applicazione che installa il middleware, usa un'istanza client separata senza di esso.
Una richiesta rifiutata in un Message Batch ritorna come result.type: "succeeded" con stop_reason: "refusal". Il campo stop_details può essere null nei risultati batch, quindi rileva i rifiuti controllando direttamente stop_reason.
Il fallback lato server non è disponibile per i batch (una richiesta batch che include fallbacks produce un risultato di errore per elemento). Per ritentare gli elementi batch rifiutati:
fallbacks non si propaga nelle chiamate al modello effettuate dall'interno dell'esecuzione degli strumenti.fallback_message in usage.iterations segna quest'ultima), poi imposta un alert sulla differenza tra i due conteggi.stop_reason, non su stop_details o content. stop_details è informativo e può essere null su un rifiuto. Controlla direttamente che stop_reason sia uguale a "refusal".Evita di pagare due volte il costo della cache dei prompt quando costruisci tu stesso il retry.
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.
Was this page helpful?