O Claude Fable 5 inclui classificadores de segurança que podem recusar uma requisição. Quando isso acontece, você recebe uma resposta normal, não um erro, com stop_reason: "refusal". Normalmente, você ainda pode obter uma resposta enviando a mesma requisição para outro modelo Claude. Esta página mostra como reconhecer uma recusa e como configurar essa nova tentativa.
Leia esta página quando estiver desenvolvendo com o Claude Fable 5 e quiser que requisições recusadas sejam automaticamente encaminhadas para outro modelo. Ela também se aplica quando você acabou de ver "refusal" em uma resposta e quer saber o que fazer em seguida.
A lista completa de valores de stop_reason está em Motivos de parada e fallback. Detalhes sobre como requisições recusadas são cobradas, e como evitar pagar duas vezes pelo cache de prompt em uma nova tentativa, estão em Crédito de fallback. O helper do SDK que encapsula tudo isso está em Middleware do SDK. Para um exemplo completo de ponta a ponta, consulte o cookbook de fallback e cobrança.
A configuração mais simples: nomeie um modelo de fallback na requisição, e a API cuida da nova tentativa.
await client.beta.messages.create({
model: "claude-fable-5",
max_tokens: 1024,
messages,
betas: ["server-side-fallback-2026-06-01"],
fallbacks: [{ model: "claude-opus-4-8" }]
});As seções abaixo cobrem o que uma resposta de recusa contém, quando usar fallback do lado do servidor ou do lado do cliente, e como cada um é cobrado.
Uma recusa é uma resposta HTTP 200 bem-sucedida com 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
}
}O objeto stop_details explica a recusa. Seu campo category nomeia a área de política que acionou o classificador. Seu campo explanation é uma descrição legível por humanos; o texto não é estável, então exiba-o em vez de analisá-lo. Ambos os campos são null quando a recusa não corresponde a uma categoria nomeada, e null é um valor normal e permanente, não um placeholder. O próprio stop_details é null para todos os motivos de parada que não sejam refusal.
category | O que significa |
|---|---|
"cyber" | A requisição poderia possibilitar danos cibernéticos, como desenvolvimento de malware ou exploits. Trabalho benigno de cibersegurança também pode acionar esta categoria. |
"bio" | A requisição poderia possibilitar danos biológicos, como métodos laboratoriais perigosos. Trabalho benéfico em ciências da vida também pode acionar esta categoria. |
"reasoning_extraction" | A requisição pede ao modelo que reproduza seu raciocínio interno no texto da resposta. Para obter o raciocínio em forma estruturada, use adaptive thinking. |
Uma recusa pode chegar antes de qualquer saída, ou no meio do stream após saída parcial. Em ambos os casos, trate qualquer saída parcial como incompleta e descarte-a.
Como as recusas são cobradas: Uma recusa antes de qualquer saída deixa content vazio, e você não é cobrado (as contagens de tokens aparecem em usage, mas não são cobradas, e a requisição não conta contra os limites de taxa). Uma recusa no meio do stream cobra os tokens de entrada e a saída já transmitida às taxas normais.
Há três maneiras de repetir uma requisição recusada em outro modelo. A escolha certa depende de onde você está executando e de quanto controle você precisa.
| Sua situação | Use | Por quê |
|---|---|---|
| Claude API ou Claude Platform na AWS, configuração mais simples | Fallback do lado do servidor | Uma requisição, uma resposta. A API cuida da nova tentativa. |
| Qualquer plataforma, com o SDK de TypeScript, Python, Go, Java ou C# | O middleware do SDK | Configure uma vez no cliente. As novas tentativas acontecem automaticamente. |
| Ruby, PHP, HTTP puro ou lógica de retry personalizada | Retry manual com crédito de fallback | Controle total. O crédito de fallback mantém o custo baixo. |
O fallback do lado do servidor e o middleware do SDK aplicam o crédito de fallback para você, então você só precisa daquela página quando estiver construindo a nova tentativa por conta própria.
O fallback do lado do servidor repete uma requisição recusada dentro de uma única chamada de API. Você nomeia até três modelos de fallback e, quando o Claude Fable 5 recusa, a API executa o próximo modelo da cadeia na mesma requisição. Você recebe de volta uma única resposta que nomeia o modelo que respondeu, de modo que seu usuário obtém uma resposta em uma única ida e volta.
O fallback do lado do servidor está em beta na Claude API e na Claude Platform na AWS. O parâmetro fallbacks é rejeitado na Message Batches API e não está disponível no Amazon Bedrock, Vertex AI ou Microsoft Foundry. Nessas plataformas, use o middleware do SDK.
Nomeie os modelos de fallback no parâmetro fallbacks e envie o cabeçalho 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"],
)
# Uma entrada fallback_message em usage.iterations indica que um modelo de fallback foi executado;
# combine-a com stop_reason para confirmar que o fallback atendeu à resposta.
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,
}
)
)Algumas regras se aplicam à lista fallbacks:
allowed_fallback_models na entrada do modelo na Models API.model e pode sobrescrever max_tokens e thinking apenas para aquela tentativa.O cabeçalho beta deve conter exatamente a data 2026-06-01. Sob qualquer outro valor server-side-fallback-*, o parâmetro fallbacks é rejeitado com um erro 400. Se você desenvolveu com base em uma prévia anterior deste recurso, atualize o cabeçalho beta e os formatos de requisição e resposta juntos para os desta página.
A resposta se parece com qualquer outra mensagem, com duas adições:
model de nível superior informa o modelo que produziu a mensagem retornada, seja ele o modelo solicitado ou um fallback.fallback marca cada ponto em content onde a saída de um modelo dá lugar à do próximo: {"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}. from.model ecoa a string de modelo que você enviou quando o salto que recusou é o modelo solicitado. to.model é sempre o ID resolvido do modelo que continua.Em uma recusa antes de qualquer saída, o bloco fallback é o primeiro bloco de conteúdo:
{
"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
}
]
}
}O array usage.iterations registra cada tentativa. Um modelo que recusou aparece como uma entrada message comum, e o modelo que atendeu o turno aparece como uma entrada fallback_message. Se todos os modelos da cadeia recusarem, a resposta é a recusa do último modelo, com uma entrada message para cada salto anterior e uma entrada fallback_message para o último.
No próximo turno, envie o conteúdo do assistente de volta como você o recebeu. Após um fallback no meio da saída, content pode incluir tipos de bloco que o modelo que recusou produziu antes da transferência; a tabela abaixo cobre quais manter e quais descartar quando você ecoar o turno.
| Tipo de bloco | No próximo turno |
|---|---|
fallback | Mantenha-o exatamente onde apareceu. A API usa sua posição para validar os blocos de thinking ao redor dele, então uma requisição que ecoa blocos de thinking de ambos os lados da fronteira é rejeitada se o bloco for omitido ou movido. |
text | Mantenha. |
Qualquer bloco após o bloco fallback final | Mantenha. |
thinking, redacted_thinking ou connector_text antes do bloco fallback final | Descarte. |
tool_use do lado do cliente antes do bloco fallback final | Descarte. |
server_tool_use antes do bloco fallback final | Mantenha quando emparelhado com seu resultado. Descarte quando não tiver resultado correspondente. |
Um bloco connector_text carrega texto de narração que algumas respostas com uso de ferramentas incluem entre chamadas de ferramenta.
Em uma requisição de streaming, a nova tentativa acontece no mesmo stream, e nada do que você já recebeu é invalidado. Quando a recusa acontece antes de qualquer saída, message_start nomeia o modelo de fallback e o bloco fallback é o primeiro bloco de conteúdo; como message_start espera a tentativa de fallback começar, o tempo até o primeiro byte inclui a tentativa recusada. Quando a recusa acontece no meio da saída, o bloco de conteúdo aberto é fechado, o bloco fallback (um par comum de content_block_start e content_block_stop sem deltas) marca a fronteira, e o modelo de fallback continua a partir da saída parcial. Apenas os blocos text da saída parcial são passados ao modelo de fallback como contexto; outros tipos de bloco permanecem em content. No caso de recusa no meio da saída, message_start já nomeou o modelo solicitado, então leia o modelo que está atendendo a partir do to.model do bloco fallback e da entrada fallback_message em usage.iterations do message_delta final.
Em uma requisição sem streaming, uma recusa no meio da saída se comporta de forma diferente: a resposta omite a saída parcial do modelo que recusou, e o modelo de fallback responde do zero. O resultado se parece com uma recusa antes de qualquer saída, com o bloco fallback primeiro. A tentativa recusada e seus tokens de saída ainda aparecem em usage.iterations.
Quando uma recusa é acionada depois que ferramentas de servidor (por exemplo, busca na web ou execução de código) já foram executadas dentro de uma requisição, a API retorna a recusa em vez de avançar para um modelo de fallback. Se o cabeçalho fallback-credit-2026-06-01 também estiver definido, essa recusa carrega um token de crédito resgatável ao continuar a resposta parcial, de modo que o trabalho de ferramenta concluído não seja perdido. Isso se aplica apenas a ferramentas de servidor iterando dentro de uma única requisição; conversas que usam ferramentas do lado do cliente fazem fallback normalmente.
Os SDKs de TypeScript, Python, Go, Java e C# incluem um middleware de fallback de recusa. Você o configura uma vez no cliente com sua lista de modelos de fallback. As chamadas através de client.beta.messages então repetem requisições recusadas automaticamente, em qualquer plataforma. O middleware também envia o cabeçalho beta fallback-credit-2026-06-01 em cada requisição que ele trata, de modo que as novas tentativas são reprecificadas sem configuração por requisição.
O helper de middleware de fallback de recusa ainda não está disponível nos SDKs de Ruby e PHP. Nesses SDKs, implemente o padrão de detectar-e-repetir diretamente.
Passe o middleware para o construtor do cliente e compartilhe uma instância de BetaFallbackState entre as requisições de uma conversa.
# Em caso de recusa, o middleware tenta novamente no modelo de fallback listado e
# envia automaticamente o cabeçalho beta de crédito de fallback em cada requisição que processa.
client = Anthropic(
middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
)
state = BetaFallbackState() # pins follow-ups to the model that accepted
# Streaming: em caso de recusa, o middleware tenta novamente no modelo de fallback e
# insere seus eventos no stream aberto.
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}")
# Sem streaming: reutilizar o estado mantém a conversa fixada.
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 em cada fronteira de modelo, da mesma forma que as respostas de fallback do lado do servidor. O middleware gerencia esses blocos para você em requisições posteriores.BetaFallbackState, de modo que requisições subsequentes que compartilham o estado permanecem fixadas nele em vez de perguntar novamente a um modelo que recusou.O middleware e o parâmetro fallbacks do lado do servidor fazem o mesmo trabalho. Configure um ou outro, nunca ambos na mesma requisição. Para enviar uma requisição com fallbacks do lado do servidor a partir de uma aplicação que instala o middleware, use uma instância de cliente separada sem ele.
Uma requisição recusada em um Message Batch retorna como result.type: "succeeded" com stop_reason: "refusal". O campo stop_details pode ser null em resultados de batch, então detecte recusas verificando stop_reason diretamente.
O fallback do lado do servidor não está disponível para batches (uma requisição de batch que inclui fallbacks produz um resultado com erro por item). Para repetir itens de batch recusados:
fallbacks não se propaga para chamadas de modelo feitas de dentro da execução de ferramentas.fallback_message em usage.iterations marca a última), então alerte sobre a diferença entre as duas contagens.stop_reason, não em stop_details ou content. stop_details é informativo e pode ser null em uma recusa. Verifique se stop_reason é igual a "refusal" diretamente.Evite pagar o custo de cache de prompt duas vezes quando você mesmo constrói a nova tentativa.
Todos os valores de stop_reason e como tratá-los.
Como o middleware do SDK funciona, incluindo o helper de fallback de recusa.
Migre uma aplicação existente para o Claude Fable 5.
Was this page helpful?