Recusas e fallback
Como os modelos Claude Fable, os modelos Claude Opus, o Claude Sonnet 5.5 e o Claude Haiku 5.5 retornam recusas de classificadores e como tentar novamente solicitações recusadas em um modelo de fallback.
Claude Fable 5.1, Claude Fable 5, Claude Opus 5.5, Claude Opus 5, Claude Sonnet 5.5 e Claude Haiku 5.5 incluem "safety classifiers" (classificadores de segurança) que podem recusar uma solicitação. Quando isso acontece, você recebe uma resposta normal, não um erro, com stop_reason: "refusal". O stop_details.category dessa resposta indica a área de política (consulte Como é uma recusa). Normalmente, você ainda pode obter uma resposta enviando a mesma solicitação para outro modelo Claude. Esta página mostra como reconhecer uma "refusal" (recusa) e como configurar essa nova tentativa.
Leia esta página quando você desenvolver sobre qualquer um desses modelos e quiser que requisições recusadas passem automaticamente para outro modelo. Ela também se aplica quando você viu "refusal" em uma resposta e quer saber o que fazer em seguida.
Páginas relacionadas:
- Motivos de parada e fallback: a lista completa de valores de
stop_reason. - Crédito de fallback: como evitar pagar o custo do cache de prompt duas vezes quando você mesmo constrói a nova tentativa.
- Middleware do SDK: o helper do SDK que encapsula tudo isso.
- Cookbook de fallback e cobrança: um exemplo completo de ponta a ponta.
A configuração mais simples, em beta na Claude API: defina fallbacks como "default", e a API repete uma requisição recusada no modelo de "fallback" (modelo alternativo) que a Anthropic recomenda para a categoria da recusa. Para categorias sem fallback recomendado, a recusa permanece. O Claude Haiku 5.5 não tem fallback do lado do servidor, então, para ele, use fallback do lado do cliente com o middleware do SDK ou escreva você mesmo a nova tentativa.
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)As seções a seguir abordam 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.
Como é uma recusa
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:
category: nomeia a área de política que acionou o classificador.explanation: uma descrição legível por humanos. O texto não é estável, portanto exiba-o em vez de analisá-lo.recommended_model: presente apenas em requisições que definemfallbacks(fallback do lado do servidor, beta). Ele nomeia um modelo para repetir diretamente quando a API pulou a tentativa de fallback (por exemplo, o modelo de fallback estava com limite de taxa atingido), e énullcaso contrário. É uma sugestão, não uma garantia.categoryeexplanationsão ambosnullquando a recusa não corresponde a uma categoria nomeada. Essenullé um valor normal e permanente, não um placeholder.- O próprio
stop_detailsénullpara todos os motivos de parada que não sejamrefusal.
category | O que significa | Cobrado antes de qualquer saída |
|---|---|---|
"cyber" | A requisição poderia viabilizar danos cibernéticos, como desenvolvimento de malware ou exploits. Trabalho benigno de cibersegurança também pode acionar esta categoria. | Não |
"bio" | A requisição poderia viabilizar danos biológicos, como métodos laboratoriais perigosos. Trabalho benéfico em ciências da vida também pode acionar esta categoria. | Sim |
"frontier_llm" | A requisição poderia auxiliar o desenvolvimento de modelos de IA concorrentes, o que é restrito pelos termos comerciais da Anthropic. Trabalho benigno de aprendizado de máquina também pode acionar esta categoria. | Sim |
"reasoning_extraction" | A requisição pede que o modelo reproduza seu raciocínio interno no texto da resposta. Para obter o raciocínio em formato estruturado, use o pensamento adaptativo. Consulte Mantenha o raciocínio nos blocos de pensamento. | Sim |
"general_harms" | A requisição se enquadra em uma área da política de uso fora das quatro categorias nomeadas. Trabalho benigno também pode acionar esta categoria. | Não |
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.
Mantenha o raciocínio nos blocos de pensamento
Uma recusa reasoning_extraction geralmente vem de um prompt que pede ao modelo para colocar seu pensamento ou raciocínio na saída, seja literalmente ou em um formato fixo. Exemplos comuns:
- Uma seção
<thinking>,<reasoning>ou de rascunho que o modelo preenche antes de responder - Um campo
reasoning,thinkingoutracena saída JSON ou em uma entrada de ferramenta - As anotações privadas do modelo ou um registro contínuo do seu raciocínio
- Raciocínio solicitado literalmente ou na íntegra
Essa redação pode estar em um prompt do sistema, em uma skill ou na descrição de uma ferramenta, então verifique esses pontos também.
Você ainda pode pedir ao Claude que explique sua resposta. Peça uma explicação curta, as evidências por trás de um resultado ou um resumo das ações que ele executou. Para ver como o modelo raciocinou, defina display: "summarized" e leia os blocos thinking. Esta categoria não tem modelo de fallback recomendado, então altere o prompt em vez de tentar a requisição novamente. Se uma requisição reformulada ainda for recusada, entre em contato com o suporte e inclua o ID da solicitação.
Como as recusas são cobradas
Estas regras de cobrança se aplicam a todas as plataformas: Claude API, Amazon Bedrock, Claude Platform on AWS, Google Cloud e Microsoft Foundry.
Recusas antes de qualquer saída: para dificultar tentativas de contornar as salvaguardas da Anthropic em escala, uma recusa que chega antes de qualquer saída é cobrada quando seu stop_details.category é "bio", "frontier_llm" ou "reasoning_extraction". Essas são as categorias em que a Anthropic mede baixos volumes de falsos positivos, em setembro de 2026. Essas recusas são cobradas como qualquer outra requisição, às taxas do modelo que a executou. Uma recusa antes de qualquer saída em qualquer outra categoria, ou com categoria null, não é cobrada. Em ambos os casos, content está vazio e as contagens de tokens aparecem em usage. A requisição ainda conta para seus limites de taxa.
Recusas no meio do stream: uma recusa no meio do stream cobra os tokens de entrada e a saída já transmitida via streaming às taxas normais.
Fallback: quando você usa fallback, a recusa que o acionou é cobrada, além da requisição de fallback, quando chegou no meio do stream ou está em uma das categorias cobradas. O crédito de fallback compensa a falha de cache de prompt da requisição de fallback, para que você não pague para armazenar a conversa em cache duas vezes. Uma recusa do Claude Haiku 5.5 não gera crédito de fallback, então um fallback após ela paga o custo total de gravar o cache de prompt do modelo de fallback. Para saber como o fallback do lado do servidor relata cada tentativa, consulte Cobrança e limites de taxa.
As categorias cobradas podem mudar à medida que a Anthropic continua medindo e refinando as taxas de falsos positivos de suas salvaguardas. A coluna Cobrado antes de qualquer saída na tabela de categorias de recusa lista as categorias cobradas.
Escolhendo uma abordagem de fallback
Há três maneiras de repetir uma requisição recusada em outro modelo. A correta depende de onde você está executando e de quanto controle você precisa.
| Sua situação | Use | Por quê |
|---|---|---|
| Claude API, configuração mais simples | Fallback do lado do servidor | Uma requisição, uma resposta. A API cuida da nova tentativa. |
| Qualquer plataforma, usando um SDK da Anthropic | O middleware do SDK | Configure uma vez no cliente. As novas tentativas acontecem automaticamente. |
| HTTP puro ou lógica de nova tentativa personalizada | Uma nova tentativa 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ê. Você só precisa da página Crédito de fallback quando você mesmo cria a nova tentativa. O Claude Haiku 5.5 não tem fallback do lado do servidor nem crédito de fallback, então use o middleware do SDK ou uma nova tentativa manual.
Fallback do lado do servidor
O fallback do lado do servidor repete uma requisição recusada dentro de uma única chamada de API. No modo padrão, quando o modelo primário recusa e a categoria de recusa tem um fallback recomendado, a API executa a mesma requisição no modelo que a Anthropic recomenda para essa categoria. Em vez disso, você pode nomear até três modelos de fallback próprios. De qualquer forma, você recebe de volta uma resposta que nomeia o modelo que respondeu, de modo que seu usuário obtém uma resposta em uma única ida e volta.
Fazendo a requisição
Defina o parâmetro fallbacks como a string "default" e envie o cabeçalho beta server-side-fallback-2026-07-01. A API então aplica o roteamento padrão definido pelo servidor para o modelo solicitado, que seleciona um modelo de fallback recomendado com base na categoria de recusa que o classificador reporta, de modo que requisições recusadas sejam atendidas sem que você precise manter uma lista de modelos à medida que as recomendações mudam.
O roteamento padrão nunca provoca a rejeição antecipada de imagem superdimensionada para modelos que você não escolheu: um modelo roteado que redimensionaria uma imagem marcada com "oversized_image": "error" é removido do roteamento, de modo que uma imagem marcada nunca é servida redimensionada.
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"],
)
# 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 forneceu a 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,
}
)
)A Anthropic define salvaguardas para cada modelo individualmente e para cada categoria de política, de acordo com a capacidade do modelo: dependendo da categoria, uma requisição sinalizada pode recorrer a um modelo menos capaz ou ser recusada. O modo "default" codifica essas recomendações por modelo e por categoria para você, de modo que uma requisição recusada é repetida no modelo que a Anthropic recomenda para essa categoria. Os fallbacks são visíveis de qualquer forma: a resposta nomeia o modelo que a atendeu, e o bloco de conteúdo fallback marca a transferência.
O roteamento é aplicado do lado do servidor e não é publicado por modelo na Models API. Para ver qual modelo atendeu uma requisição recusada, verifique o campo model de nível superior da resposta e procure uma entrada fallback_message em usage.iterations, como fazem os exemplos desta página.
Apenas uma recusa do classificador de segurança aciona o fallback. Um limite de taxa, sobrecarga ou erro de servidor no modelo solicitado é retornado a você como está.
Nomeando seus próprios modelos de fallback
Em vez do roteamento padrão, você pode definir fallbacks como uma lista de até três modelos. Quando o modelo solicitado recusa, a API executa o próximo modelo da cadeia na mesma requisição. Use esta forma quando quiser controlar exatamente quais modelos atendem requisições recusadas, como fixar um modelo que sua aplicação qualificou.
Modelos de fallback nomeados contam para a verificação de imagem superdimensionada: uma requisição cujo bloco de imagem define "oversized_image": "error" é verificada antecipadamente em relação ao modelo solicitado e a cada fallback nomeado, é rejeitada se qualquer um deles redimensionaria essa imagem, e o alvo de redimensionamento reportado na rejeição serve para todos eles.
As linhas destacadas são a única diferença em relação à requisição de roteamento padrão.
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)Algumas regras se aplicam à lista fallbacks:
- As entradas são tentadas em ordem. Cada uma deve ser diferente das outras entradas e do modelo solicitado.
- Cada entrada deve ser um dos destinos permitidos do modelo solicitado. Com o cabeçalho beta definido, essa lista é publicada como
allowed_fallback_modelsna entrada do modelo na Models API. - Cada entrada indica um
modele pode substituirmax_tokens,thinking,output_configespeedapenas para aquela tentativa. - A solicitação deve ser válida como solicitação direta para cada modelo nomeado. Se um modelo de fallback não suportar um recurso que a solicitação usa, a API rejeita a solicitação antecipadamente. Com o cabeçalho
2026-07-01,thinking: {"type": "between_tools"}é a exceção: quando uma solicitação ao Claude Sonnet 5.5 recorre ao Claude Sonnet 5, a tentativa de fallback é executada comthinking: {"type": "disabled"}edisplay: "omitted". Com2026-06-01, definathinkingna entrada do Claude Sonnet 5, ou a solicitação será rejeitada antecipadamente. - Assim como no modo padrão, somente uma recusa de um classificador de segurança aciona o fallback. Um limite de taxa, sobrecarga ou erro de servidor no modelo solicitado é retornado a você como está.
- Se um modelo de fallback atingir o limite de taxa ou estiver sobrecarregado, a tentativa de fallback não é feita e a recusa anterior é retornada. O
stop_details.recommended_modelda recusa então indica um modelo para repetir diretamente. Dimensione os limites de taxa do modelo de fallback para o volume de recusas que você espera, ou os fallbacks se degradarão em recusas sob carga.
A resposta tem o mesmo formato em ambos os modos: o modelo que atendeu o turno aparece no campo model de nível superior, um bloco de conteúdo fallback marca a transferência, e usage.iterations registra cada tentativa.
O que a resposta contém
A resposta se parece com qualquer outra mensagem, com duas adições:
- O campo
modelde nível superior reporta o modelo que produziu a mensagem retornada, seja o modelo solicitado ou um fallback. - Um bloco de conteúdo
fallbackmarca cada ponto emcontentonde a saída de um modelo dá lugar à do próximo:{"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}.from.modelecoa a string de modelo que você enviou quando o salto que recusa é 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. Por exemplo, quando o roteamento padrão seleciona Claude Opus 4.8 para a categoria da recusa:
{
"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.
O roteamento persistente pode enviar um turno posterior diretamente para o modelo de fallback. Tal turno não carrega nenhum bloco de conteúdo fallback, porque nenhum modelo recusou aquele turno. Identifique-o pela entrada fallback_message em usage.iterations, pela ausência de uma entrada message para o modelo solicitado e pelo campo model da resposta.
Continuando a conversa
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 a seguir indica quais manter e quais descartar quando você ecoa 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 pensamento ao redor dele, portanto uma requisição que ecoa blocos de pensamento 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 pareado com seu resultado. Descarte quando não tiver resultado correspondente. |
Streaming
Em uma requisição com streaming, a nova tentativa acontece no mesmo stream, e nada do que você já recebeu é invalidado. O que você vê depende de quando a recusa acontece.
Quando a recusa acontece antes de qualquer saída:
message_startnomeia o modelo de fallback, e o blocofallbacké o primeiro bloco de conteúdo.- Como
message_startaguarda o início da tentativa de fallback, 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, e o bloco
fallback(um par comum decontent_block_startecontent_block_stopsem deltas) marca a fronteira. - O modelo de fallback continua a partir da saída parcial. Apenas os blocos
textda saída parcial são passados ao modelo de fallback como contexto. Outros tipos de bloco permanecem emcontent. message_startjá nomeou o modelo solicitado, portanto leia o modelo que atendeu a partir doto.modeldo blocofallbacke da entradafallback_messageemusage.iterationsdomessage_deltafinal.
Respostas sem streaming
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.
Cobrança e limites de taxa
Cada tentativa segue as regras de Como as recusas são cobradas, às taxas do modelo que a executou. Uma tentativa que recusou antes de produzir qualquer saída só é cobrada quando sua categoria de recusa é cobrada, e seus tokens são reportados em sua entrada de usage.iterations em qualquer caso. Cada tentativa que produziu saída, incluindo uma que recusou no meio de sua resposta, é cobrada separadamente. O array usage.iterations é o registro por tentativa do que é cobrado de você. As contagens de usage de nível superior descrevem apenas a tentativa que produziu a mensagem retornada. Tokens de modelos diferentes nunca são somados em um único campo.
Cada tentativa executada, incluindo uma que recusou, conta para os limites de taxa de seu próprio modelo.
Roteamento persistente
Depois que uma conversa recorre ao fallback, a API registra qual modelo a atendeu. Requisições posteriores para essa conversa que incluem fallbacks vão diretamente para esse modelo de fallback, sem executar o modelo solicitado. Isso evita pagar por uma tentativa que previsivelmente seria recusada novamente a cada turno.
Algumas propriedades da decisão de "sticky routing" (roteamento persistente):
- Ela é retida por aproximadamente 1 hora e tem escopo na sua organização.
- Ela é armazenada como um hash de conteúdo do prefixo da conversa mais o modelo que a atendeu. O conteúdo da mensagem em si não é armazenado.
- Ela é de melhor esforço, portanto seu código deve lidar com o modelo solicitado sendo tentado novamente a qualquer momento.
O roteamento persistente se aplica tanto a requisições com streaming quanto sem streaming. Em uma requisição com streaming, a decisão de roteamento é tomada antes de o stream abrir, portanto o campo model do evento message_start já carrega o ID do modelo de fallback.
Fallback do lado do cliente com o middleware do SDK
O SDK inclui um middleware de fallback de recusa. Você o configura uma vez no cliente com sua lista de modelos de fallback. As chamadas por meio de client.beta.messages então repetem automaticamente as requisições recusadas, em qualquer plataforma. O middleware também envia o cabeçalho beta fallback-credit-2026-07-01 em cada requisição que processa, para que as novas tentativas sejam reprecificadas sem configuração por requisição. Uma recusa do Claude Haiku 5.5 não gera crédito de fallback, então uma nova tentativa após ela paga o custo total de gravar o cache de prompt do modelo de fallback.
Configurando
Passe BetaRefusalFallbackMiddleware ao construtor do cliente e compartilhe uma instância de BetaFallbackState entre as requisições de uma conversa.
from anthropic import Anthropic, BetaFallbackState, BetaRefusalFallbackMiddleware
# Em caso de recusa, o middleware tenta novamente no modelo de fallback listado e
# envia automaticamente o cabeçalho beta fallback-credit 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 text in stream.text_stream:
print(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}")Como ele se comporta
- As novas tentativas percorrem sua lista de fallback em ordem. Um modelo de fallback que também recusa passa a solicitação para a próxima entrada.
- Quando todos os modelos da lista recusaram, o middleware retorna a recusa final (a resposta de recusa do último modelo) em vez de gerar um erro.
- Os blocos de pensamento do Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5, Claude Haiku 5.5 ou Claude Fable 5 passam inalterados. Cada nova tentativa reenvia o corpo da sua solicitação original, e os únicos blocos que o middleware remove do histórico da conversa em solicitações posteriores são os blocos de fronteira
fallbackque ele mesmo adicionou. O modelo de fallback não consegue ler blocos do Claude Fable 5.1, que apenas o Claude Fable 5.1 e o Claude Mythos 5.1 leem, então a API os descarta. A API também descarta blocos do Claude Opus 5.5 para todo modelo de fallback, exceto Claude Fable 5.1 e Claude Mythos 5.1 (consulte Trocar de modelo no meio da conversa). Ela também descarta blocos do Claude Sonnet 5.5, para todo modelo de fallback, exceto o Claude Opus 5.5 na Claude API e no Google Cloud. O Claude Opus 5.5 e o Claude Sonnet 5.5 leem blocos do Claude Haiku 5.5 na Claude API e no Google Cloud, e a API os descarta para um modelo de fallback que não consegue lê-los. - As respostas atendidas por meio do middleware incluem um bloco de conteúdo
fallbackem cada fronteira entre modelos, assim como as respostas de fallback no lado do servidor. O middleware gerencia esses blocos para você em solicitações posteriores. - O modelo que aceitou é registrado em
BetaFallbackState, de modo que as solicitações seguintes que compartilham o estado permanecem fixadas nele, em vez de consultar novamente um modelo que recusou.
Escrevendo a nova tentativa por conta própria
Sobre HTTP puro ou com lógica de nova tentativa personalizada, implemente o padrão que o middleware encapsula:
Detecte a recusa
Verifique se a resposta contém
stop_reason: "refusal".Reenvie para um modelo de fallback
Envie a mesma solicitação com
modeldefinido como um modelo de fallback, como o Claude Opus 4.8. Se a solicitação recusada enviouthinking: {"type": "between_tools"}, alterethinkingprimeiro: apenas o Claude Sonnet 5.5 aceita esse valor, então omitathinkingou defina um valor que o modelo de fallback aceite. O fallback no lado do servidor com o cabeçalho2026-07-01faz essa alteração para você quando recorre ao Claude Sonnet 5. Outro modelo normalmente consegue atender uma solicitação que o Claude Fable 5.1 ou o Claude Fable 5 recusa. A forma como você lida com o histórico da conversa depende de você resgatar ou não um crédito de fallback:- Sem resgatar um crédito: você pode deixar os blocos
thinkingeredacted_thinkinganteriores no lugar ou removê-los para economizar tokens de entrada. O modelo de fallback normalmente não consegue usá-los de qualquer forma: apenas o Claude Fable 5.1 e o Claude Mythos 5.1 leem blocos do Claude Fable 5.1, e apenas esses dois modelos, além do Claude Fable 5 e do Claude Mythos 5, leem blocos do Claude Fable 5, então, para qualquer outro modelo de fallback, a API os descarta. A API também descarta blocos do Claude Opus 5.5 para todo modelo de fallback, exceto Claude Fable 5.1 e Claude Mythos 5.1 (consulte Trocar de modelo no meio da conversa). Ela também descarta blocos do Claude Sonnet 5.5, para todo modelo de fallback, exceto o Claude Opus 5.5 na Claude API e no Google Cloud. Uma nova tentativa após uma recusa do Claude Haiku 5.5 sempre se enquadra neste caso. O Claude Opus 5.5 e o Claude Sonnet 5.5 leem blocos do Claude Haiku 5.5 na Claude API e no Google Cloud, então deixe esses blocos no lugar quando recorrer a qualquer um desses modelos ali. Para um modelo de fallback que não consegue lê-los, a API os descarta sem cobrá-los. - Resgatando um crédito: envie o corpo inalterado, porque o resgate exige correspondência exata. O servidor lida com os blocos de thinking do modelo anterior em um resgate, então não os remova (consulte Campos que devem corresponder à solicitação recusada).
- Sem resgatar um crédito: você pode deixar os blocos
Permaneça no modelo de fallback
Em conversas com vários turnos, continue usando o modelo de fallback nos turnos seguintes em vez de voltar ao modelo original.
Uma nova tentativa manual grava o cache de prompt do modelo de fallback do zero, o que custa mais do que ler um cache existente. O crédito de fallback reembolsa esse custo; resgate-o em cada nova tentativa que você mesmo criar. Uma recusa do Claude Haiku 5.5 não gera crédito de fallback, então uma nova tentativa após ela paga o custo total de gravar o cache de prompt do modelo de fallback.
Recusas em Message Batches
Uma requisição recusada em um Message Batch retorna como result.type: "succeeded" com stop_reason: "refusal". Os resultados de lote carregam o mesmo objeto stop_details que as respostas síncronas, portanto você pode detectar recusas através de stop_reason ou de stop_details.type. Uma diferença: recusas em lote não geram créditos de fallback, portanto stop_details em um resultado de lote nunca inclui um fallback_credit_token.
O fallback do lado do servidor não está disponível para lotes (uma requisição de lote que inclui fallbacks produz um resultado com erro por item). Para repetir itens de lote recusados:
- Colete os itens recusados dos resultados.
- Deixe os blocos de pensamento nos históricos de vários turnos no lugar ou remova-os para economizar tokens de entrada. Para um modelo de fallback que não consegue lê-los, a API os descarta sem cobrá-los, como em uma nova tentativa manual.
- Se um item recusado enviou
thinking: {"type": "between_tools"}, omitathinkingou defina um valor que o modelo de fallback aceite. Apenas o Claude Sonnet 5.5 aceitabetween_tools. - Reenvie-os em um modelo de fallback como um novo lote ou como requisições diretas.
Armadilhas comuns
- Repita em um modelo diferente. Reenviar uma requisição recusada para o mesmo modelo geralmente resulta em outra recusa. Direcione a nova tentativa para o modelo de fallback.
- Orce novas tentativas por requisição, não por turno ou por sessão. Um único turno pode produzir várias recusas, por exemplo um agente mais seus subagentes.
- Configure o fallback em todos os caminhos de requisição. Handlers de nova tentativa, ramificações de recuperação de erro e workers em segundo plano todos precisam dele. Um handler que reemite uma requisição sem fallback perde a proteção exatamente nas requisições com maior probabilidade de precisar dela.
- Dê às chamadas de subagentes seu próprio fallback. O parâmetro
fallbacksnão se propaga para chamadas de modelo feitas de dentro da execução de ferramentas. - Torne o fallback uma propriedade da requisição, não do estado ambiente. Uma flag compartilhada, um valor de configuração em cache ou um toggle global podem ficar fora de sincronia e silenciosamente deixar uma requisição desprotegida. Quando você não puder confirmar que o fallback está ativo, configure-o em vez de presumir que está ligado.
- Instrumente recusas como um sinal próprio. Uma recusa é um HTTP 200, portanto monitoramento baseado em taxas de erro ou respostas 5xx nunca a vê. Emita um evento por recusa e um por resposta atendida por fallback (a entrada
fallback_messageemusage.iterationsmarca esta última), e então alerte sobre a diferença entre as duas contagens. - Ramifique com base em
stop_reasonoustop_details.type, não emcontentou nos campos internos destop_details. O objetostop_detailsestá sempre presente em uma recusa, mas seus camposcategoryeexplanationpodem sernull. Verifique diretamente sestop_reasoné igual a"refusal".
Próximos passos
Evite pagar o custo do cache de prompt duas vezes quando você mesmo constrói a nova tentativa.
Cada valor de stop_reason e como lidar com ele.
Como o middleware do SDK funciona, incluindo o helper de fallback de recusa.
Mova uma aplicação existente para o Claude Fable 5.1.
Was this page helpful?