Como rotear requisições entre Sonnet 5.5 e Opus 5.5 automaticamente na API

Um roteador de modelos Claude é uma função no seu backend que decide qual modelo atende cada requisição. Antes de chamar a API, ela classifica a tarefa (por regra fixa ou com um modelo barato como o Haiku 5.5), escolhe entre claude-sonnet-5-5 e claude-opus-5-5 e define o nível de esforço em output_config.effort. Depois, registra o model e o usage da resposta para você comparar qualidade e custo.
Este tutorial é para quem já sabe quando usar Sonnet ou Opus na mão e agora quer que a própria aplicação tome essa decisão. Um roteador não economiza nada por definição: a economia só existe se você medir com o tráfego real do seu app.
O que você precisa antes de montar o roteador
O mínimo é ter acesso à Claude API e usar um SDK oficial. Os exemplos abaixo estão em Python, com client.messages.create, que é a forma que a documentação usa para o parâmetro de esforço.
Separe também estes itens:
- IDs de modelo corretos:
claude-opus-5-5(Opus 5.5),claude-sonnet-5-5(Sonnet 5.5) eclaude-haiku-5-5(Haiku 5.5), este último para servir de classificador. - Parâmetro de esforço: ele vai no corpo da requisição, em
output_config.effort. Segundo a documentação de effort, está disponível em todos os modelos suportados sem header beta. - Uma amostra de requisições reais do seu app: sem isso você inventa regra no escuro. Pegue pedidos de verdade e anote o que cada um exige.
Se o seu código ainda chama um modelo antigo e você vai migrar junto, vale revisar o que muda ao trocar para o Sonnet 5.5 na API antes de colocar um roteador por cima.
Que tipo de requisição vai para o Sonnet 5.5 e qual vai para o Opus 5.5
A regra de roteamento sai do posicionamento oficial dos dois modelos. O Sonnet 5.5 é descrito como complemento mais rápido e mais barato ao Opus 5.5. Ele é forte em tarefas do dia a dia bem delimitadas (código, agentes, trabalho de conhecimento) e em tarefas de agente bem definidas, como investigação, revisão e rascunho.
O Opus 5.5 é feito para trabalho agêntico de longa duração. A documentação cita agentes de código autônomos rodando por horas, refatoração em larga escala, engenharia de sistemas complexos e fluxos com muita visão e computer use.
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 120 aulas
- 4 projetos
- 9h 48min
Traduzindo isso para categorias de um app:
| Tipo de requisição | Modelo |
|---|---|
| Correção pontual, revisão de PR, investigação, rascunho de texto | claude-sonnet-5-5 |
| Agente que roda por muito tempo sozinho | claude-opus-5-5 |
| Refatoração que atravessa muitos arquivos | claude-opus-5-5 |
| Fluxo pesado em imagem ou computer use | claude-opus-5-5 |
O tamanho do pedido não serve de critério. Os dois modelos têm 1M tokens de contexto e 128K tokens de saída máxima, então o que decide é a natureza da tarefa.
Essa ideia é documentada pela própria Anthropic. No guia Optimizing for cost and intelligence, a recomendação é decompor a tarefa e mandar cada parte ao modelo mais barato capaz de resolvê-la. Planejamento e julgamento tendem a pedir modelo maior, e execução mecânica pode ir para o Haiku ou nem precisar de modelo.
O mesmo guia cita dois padrões multimodelo: um executor que escala decisões difíceis para um advisor, e um orquestrador que delega trabalho em volume para workers mais baratos. O roteador deste tutorial é a versão mais simples disso, uma decisão por requisição.
E o preço? Pela tabela oficial, o Opus 5.5 custa US$ 4 por milhão de tokens de entrada e US$ 20 por milhão de saída. O Sonnet 5.5 sai por US$ 2 e US$ 10. A diferença por token existe, mas o custo final depende de quantos tokens cada modelo gasta nas suas tarefas, e isso só o seu log responde.
Como montar o roteador passo a passo
O fluxo tem cinco partes: classificar, escolher modelo e esforço, chamar, tratar falha e registrar. O código abaixo é um exemplo didático para você adaptar, não uma implementação pronta para produção.
- Classifique pela heurística do próprio app. O jeito mais barato de classificar é não chamar modelo nenhum. Seu app geralmente já sabe muita coisa sobre o pedido: de qual endpoint veio, se tem imagem, se vai rodar como agente com ferramentas.
def classificar_por_heuristica(req): # req é um dict montado pelo seu app (exemplo didático) if req.get("tem_imagem") or req.get("usa_computer_use"): return "visao_ou_computer_use" if req.get("agentico") and req.get("execucao_longa"): return "agente_longo" if req.get("endpoint") == "/refatorar-projeto": return "refatoracao_ampla" if req.get("endpoint") in {"/revisar", "/investigar", "/rascunho", "/corrigir-bug"}: return "tarefa_delimitada" return None # sem sinal claro: segue para o classificadorO resultado esperado é um rótulo para a maioria dos pedidos e
Nonesó nos casos ambíguos. Um endpoint de correção de bug, por exemplo, cai no Sonnet porque é tarefa delimitada, e o prompt pode reforçar isso com instruções para corrigir bug sem reescrever tudo.O erro comum deste passo: regra vaga do tipo "se o texto for grande, vai pro Opus" ou "se mencionar código, vai pro Opus". Essas regras parecem prudentes e acabam mandando quase tudo para o modelo mais caro.
- Use o Haiku 5.5 quando a heurística não decidir. Para os pedidos que sobraram com
None, um modelo barato lê o texto e devolve só um rótulo. A Anthropic tem um guia oficial de ticket routing que serve de referência para usar o Claude como classificador.O Haiku 5.5 custa US$ 0,10 por milhão de tokens de entrada e US$ 0,50 por milhão de saída em prompts de até 100K tokens, e um prompt de classificação curto fica bem abaixo disso.
import anthropic client = anthropic.Anthropic() ROTULOS_VALIDOS = { "tarefa_delimitada", "agente_longo", "refatoracao_ampla", "visao_ou_computer_use", } PROMPT_CLASSIFICADOR = """Classifique o pedido abaixo em UM destes rótulos: tarefa_delimitada, agente_longo, refatoracao_ampla, visao_ou_computer_use. Responda somente com o rótulo, sem explicação. Pedido: {pedido}""" def classificar_com_haiku(texto, **parametros_extras): resposta = client.messages.create( model="claude-haiku-5-5", messages=[{"role": "user", "content": PROMPT_CLASSIFICADOR.format(pedido=texto)}], **parametros_extras, # inclua os demais parâmetros obrigatórios da Messages API ) rotulo = resposta.content[0].text.strip().lower() if rotulo not in ROTULOS_VALIDOS: return "tarefa_delimitada" # valor padrão definido por você return rotuloPara checar, rode o classificador nas requisições da sua amostra e compare com a classificação que você faria na mão.
O erro comum deste passo: aceitar a saída do classificador sem validar. Se o modelo responder com uma frase, um rótulo com acento ou algo fora da lista, o roteador quebra ou manda o pedido para lugar nenhum. Por isso o código checa contra
ROTULOS_VALIDOSe tem um valor padrão. - Mapeie cada rótulo para modelo e esforço. Aqui entra o segundo botão do roteador. Os níveis de esforço são
low,medium,high,xhighemax, suportados no Opus 5.5 e no Sonnet 5.5.A documentação indica
highpara raciocínio complexo, código e tarefas agênticas em que qualidade importa mais que velocidade ou custo.xhighfica para as tarefas de código e agênticas mais difíceis,maxé capacidade máxima sem limite de gasto de tokens, elowé o mais eficiente, com economia significativa de tokens.ROTAS = { "tarefa_delimitada": ("claude-sonnet-5-5", "medium"), "agente_longo": ("claude-opus-5-5", "high"), "refatoracao_ampla": ("claude-opus-5-5", "xhigh"), "visao_ou_computer_use": ("claude-opus-5-5", "medium"), } def chamar_modelo(rotulo, messages, **parametros_extras): modelo, esforco = ROTAS.get(rotulo, ROTAS["tarefa_delimitada"]) resposta = client.messages.create( model=modelo, messages=messages, output_config={"effort": esforco}, **parametros_extras, ) return modelo, esforco, respostaOs pares da tabela são um ponto de partida para você ajustar com dados, não uma recomendação medida. Se você não mandar
effort, cada modelo usa o padrão dele:highno Sonnet 5.5 emediumno Opus 5.5. Ou seja, o Sonnet sem configuração já roda num esforço maior que o Opus sem configuração.O esforço afeta TODOS os tokens da resposta: texto, explicações, chamadas de ferramenta e seus argumentos, e o thinking quando está ativo. No Opus 5.5 o adaptive thinking fica sempre ligado, e no Sonnet 5.5 vem ligado por padrão. Mexer no esforço muda o custo da resposta inteira, não só o texto final.
O erro comum deste passo: subir para
max"por garantia". Comomaxnão tem limite de gasto de tokens, ele é para casos raros, não para uma rota inteira. - Trate falhas com fallback consciente. Dois erros da API importam para o roteador, conforme a página de erros. O
529 overloaded_errorindica API temporariamente sobrecarregada, o que pode acontecer com tráfego alto entre todos os usuários.O
429 rate_limit_errorindica limite de taxa ou teto de gasto do tier. Quando vem com o headerretry-after, basta esperar aquele número de segundos. Já o 429 de teto de gasto do tier não trazretry-aftere continua falhando até o acesso voltar.Os SDKs oficiais já repetem falhas transitórias (erro de conexão, rate limit, 5xx) com backoff exponencial, 2 vezes por padrão, respeitando o
retry-after. Cada cliente tem uma opção de máximo de retentativas para ajustar ou desligar esse comportamento. O seu código entra só depois que o SDK desistiu.def chamar_com_fallback(rotulo, messages, **parametros_extras): try: modelo, esforco, resposta = chamar_modelo(rotulo, messages, **parametros_extras) return modelo, esforco, resposta, False except Exception as erro: # troque pela exceção com status HTTP do seu SDK status = getattr(erro, "status_code", None) modelo_original, _ = ROTAS.get(rotulo, ROTAS["tarefa_delimitada"]) if status == 529 and modelo_original == "claude-opus-5-5": # decisão de produto: degradar para o Sonnet em vez de falhar modelo, esforco, resposta = chamar_modelo("tarefa_delimitada", messages, **parametros_extras) return modelo, esforco, resposta, True raise # 429 de teto de gasto não se resolve trocando de modeloCair do Opus para o Sonnet é uma decisão de produto. Para um agente de horas, talvez seja melhor falhar e reagendar do que entregar um resultado pior. O flag
Trueno retorno serve para você saber depois quantas respostas vieram de fallback.O erro comum deste passo: empilhar um loop de retentativa próprio em cima do SDK sem ajustar a opção de máximo de retentativas do cliente. Aí cada falha vira uma cascata de chamadas, e num 429 de teto de gasto você só bate na mesma parede várias vezes.
- Registre tudo o que precisa para comparar. Sem log, o roteador vira achismo automatizado. A Messages API devolve o campo
modele o objetousagecominput_tokens,output_tokens,cache_creation_input_tokensecache_read_input_tokens. O total de entrada é a soma desses três campos de entrada.

VPS Hostinger para seu sistema
10% OFF extraVPS com SSD NVMe e backups semanais. O cupom MATHEUSHORADECODAR é aplicado automaticamente pelo link.
Ver planos com 10% OFF →import json
import time
def registrar(rotulo, modelo_pedido, esforco, resposta, fallback):
u = resposta.usage
criacao_cache = u.cache_creation_input_tokens or 0
leitura_cache = u.cache_read_input_tokens or 0
registro = {
"ts": time.time(),
"rotulo": rotulo,
"modelo_pedido": modelo_pedido,
"modelo_resposta": resposta.model,
"esforco": esforco,
"fallback": fallback,
"input_tokens": u.input_tokens,
"cache_creation_input_tokens": criacao_cache,
"cache_read_input_tokens": leitura_cache,
"entrada_total": u.input_tokens + criacao_cache + leitura_cache,
"output_tokens": u.output_tokens,
"nota_qualidade": None, # preenchida depois, na revisão manual
}
print(json.dumps(registro)) # troque pelo seu sistema de logs
Para conferir, faça uma chamada de cada rota e veja se modelo_resposta bate com modelo_pedido e se os campos de usage estão preenchidos.
O erro comum deste passo: estimar custo contando o texto que aparece na tela. Os tokens em usage não batem 1 para 1 com o conteúdo visível da requisição e da resposta, porque a saída passa por uma etapa de parsing. Calcule custo sempre a partir do usage.
Como saber se o roteamento está funcionando
A checagem final é olhar os logs agrupados por rótulo. Para cada categoria, compare a nota de qualidade, o volume de tokens e o custo calculado a partir do usage. Só depois disso dá para dizer se o roteador ajudou ou se só complicou o código.
Alguns sintomas aparecem rápido:
- Quase tudo indo para o Opus. A causa costuma ser uma regra larga demais, na heurística ou no prompt do classificador. Abra os pedidos classificados como
agente_longoourefatoracao_amplae veja quantos eram tarefas delimitadas. - Queixas de qualidade numa categoria roteada ao Sonnet. Antes de trocar o modelo, suba o esforço daquela rota. Se você colocou
medium, lembre que o padrão do Sonnet 5.5 éhigh, então talvez você mesmo tenha baixado a qualidade. - Muitos 429 sem
retry-after. Isso aponta para o teto de gasto do tier, não para sobrecarga momentânea. Trocar de modelo no fallback não resolve. - Muitas respostas com
fallbackverdadeiro. O Opus está sendo trocado com frequência, então a qualidade daquela rota no log não representa o Opus. Separe essas linhas na análise.
Para prevenir, mantenha uma amostra de revisão manual: algumas respostas por rótulo, avaliadas por alguém que entende da tarefa, preenchendo nota_qualidade. Ajuste as regras a partir do que os dados mostram, nunca pela intuição de que "o Opus é melhor em tudo".
E se parte do trabalho não precisa de resposta na hora? Relatórios noturnos, reprocessamento e classificação em lote podem ir para a Batch API, que dá 50% de desconto em entrada e saída para trabalho que pode esperar até 24 horas. É outra camada de roteamento, por urgência em vez de dificuldade.
Próximo passo: comece pela heurística e meça
Escolha UMA rota do seu app, de preferência uma com volume e com tarefas variadas. Implemente só o passo 1 (heurística), o mapeamento de modelo e esforço e o logging, deixando o classificador com Haiku de fora por enquanto.
Rode assim por um período, preencha a nota de qualidade de uma amostra e compare as categorias. Se sobrarem muitos pedidos sem rótulo, aí vale colocar o Haiku na frente. Se uma categoria estiver mal, mexa primeiro no esforço, depois no modelo.
Com os números da sua própria aplicação, você vai saber se o roteador compensa, e quanto.
Perguntas frequentes
O roteador de modelos funciona também fora da Claude API, tipo no Bedrock?
O tutorial usa o SDK oficial chamando a Claude API direto, mas o Opus 5.5 também está disponível no Amazon Bedrock, no Claude Models on Google Cloud, no Microsoft Foundry e no Claude Platform on AWS. A lógica de classificar, escolher modelo e esforço é a mesma, mas os parâmetros de chamada mudam de plataforma para plataforma, então vale checar a documentação específica de cada uma antes de portar o código.
Dá para rotear só o nível de esforço, sem trocar de modelo?
Sim. Nada impede manter o mesmo modelo, por exemplo o Sonnet 5.5, e variar apenas o output_config.effort entre low e high conforme a complexidade do pedido. Isso é uma versão mais simples do roteador deste tutorial, útil quando os dois tipos de tarefa cabem no mesmo modelo e só a profundidade do raciocínio muda.
Fontes consultadas
Consulta em .
Encontre outros guias no YouTube da Hora de Codar. Se quiser aprofundar o contexto, veja Dizem que o Sonnet 5.5 bateu o Opus 5.5, será? Teste completo.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 30min
Blog | Mais populares

Como usar o Laya como roteador de modelos: decidindo small vs frontier a cada request
Laya roteador de modelos: como usar o preset router_questions() pra decidir entre small e frontier a cada request. Guia prático.

Fugu Max: quais modelos ele orquestra e onde entra a NVIDIA Nemotron?
Fugu Max é o orquestrador da Sakana AI que roteia tarefas entre modelos, com NVIDIA Nemotron cuidando de código. Veja preço e como funciona.
Como montar fallback entre Fable 5.1 e GPT-6 Astra quando um dos dois falha
Fallback Fable 5.1 GPT-6 Astra: veja como criar um adaptador único, tratar erros e trocar de modelo sem quebrar seu app.
