DEV Community

Cover image for Roteamento multi-LLM na prática: 16 modelos, escada de complexidade e FinOps que dispara
Alexandre Caramaschi
Alexandre Caramaschi

Posted on AI-assisted

Roteamento multi-LLM na prática: 16 modelos, escada de complexidade e FinOps que dispara

TL;DR (English). geo-orchestrator routes each task of a natural-language request across 16 LLMs from 5 providers by task type, complexity, cost and provider health. Every task type keeps a fallback chain whose top two slots come from different vendors; the two frontier models (US$ 10/50 per million tokens) sit behind a declarative policy with a 35% per-session share cap; and FinOps enforces per-run, per-day and per-provider ceilings with alerts that actually fire. State as of Oct 7, 2026: 23 task types, 962 passing tests.

Este artigo mostra, com pseudocódigo, as decisões de roteamento e de custo de um orquestrador multi-LLM em produção. O sistema é o geo-orchestrator, que construí para a pesquisa e a produção de conteúdo da Brasil GEO. O repositório é privado; os fluxos interativos estão em https://alexandrecaramaschi.com/geo-orchestrator.

Estado descrito: 07/10/2026, Sprint 33, parque v5.3. São 16 modelos da Anthropic, OpenAI, Google, Perplexity e xAI, 23 tipos de tarefa e 962 testes aprovados.

1. O formato do problema

Uma demanda em linguagem natural vira um plano de tarefas tipadas com dependências. Cada tarefa precisa de um modelo. As restrições que o roteador respeita, em ordem de força:

  1. orçamento (limite por execução e tetos diários);
  2. provedor apto (disjuntor fechado, com crédito, abaixo do limite de taxa);
  3. teto de concentração por provedor no run;
  4. qualidade histórica, custo e latência.

Pense numa central de despacho de táxi: o despachante sabe o destino (tipo de tarefa), a urgência (complexidade), quais carros estão na rua (saúde do provedor) e quanto já gastou no dia. Ele não manda o carro executivo buscar uma pizza.

Grafo do parque: provedores, modelos e tipos de tarefa ligados pelas rotas primárias e pelas filas de reserva

2. Cadeia de reserva com top 2 de famílias distintas

Cada tipo de tarefa tem uma cadeia ordenada. Três contratos são presos por teste:

  • o primário e a primeira reserva vêm de provedores diferentes (exceção: o par Fable 5.1 e Opus 5.5 nas rotas frontier);
  • toda cadeia tem pelo menos três degraus;
  • as cadeias de redação (writing, copywriting, seo) não aceitam modelos econômicos.

Alguns exemplos do parque vigente:

Tipo Primário Reserva 1 Reserva 2
research Grok 4.7 Perplexity (preset high) Gemini 3.1 Pro
writing GPT-5.5 Claude Opus 5.5 Grok 4.7
code GPT-6.1 Sol (Astra em alta complexidade) Gemini 3.1 Pro GPT-6 Astra
architecture Claude Fable 5.1 Claude Opus 5.5 GPT-6 Astra
classification Gemini 3.8 Flash GPT-6 Luna Grok 4.20 Non-Reasoning
long_context_synthesis Gemini 3.1 Pro GPT-5.5 GPT-6.1 Sol

Percorrer a cadeia é simples; o cuidado está no que conta como falha:

executar(tarefa):
    para alias em cadeia(tarefa.tipo):
        alias = aplicar_escada(alias, tarefa)            # seção 3
        se não utilizável(alias): continua
        resposta = chamar(alias, tarefa)
        se resposta.ok: devolve resposta
        se resposta.status em {429, 500, 502, 503, 504} ou timeout:
            disjuntor(alias.provedor).falha()             # falha transitória
        se resposta é erro de crédito ou autenticação:
            marcar_fora_da_rota(alias.provedor, 30 min)    # falha de conta
        # outros 4xx: provável bug nosso, não conta contra o provedor
    falha_com_relatório(tarefa)
Enter fullscreen mode Exit fullscreen mode

Separar os dois tipos de falha evitou um custo repetido: sem o registro de provedor fora da rota, cada tarefa de monitoramento pagava uma ida e volta falha antes da reserva quando a conta de um provedor ficou sem crédito (incidente de 24/08/2026). A marca some na primeira resposta boa, e por isso uma recarga tem efeito imediato.

Simulador de roteamento: tipo architecture, complexidade alta e demanda complexa escolhem o Claude Fable 5.1, com a fila de reservas

3. Escada de complexidade e o degrau frontier

Dentro das famílias Anthropic e OpenAI há quatro degraus:

Complexidade Claude OpenAI Entrada / saída (US$ por milhão)
baixa Haiku 5.5 GPT-6 Luna 0,10 / 0,50 nos dois (Haiku até 100K de prompt)
média Sonnet 5.5 GPT-5.5 2 / 10 e 5 / 30
alta Opus 5.5 GPT-6.1 Sol 4 / 20 e 2 / 10
frontier Fable 5.1 GPT-6 Astra 10 / 50 nos dois

Preços da tabela oficial de cada provedor, lidos em 07/10/2026. Preço promocional nunca entra no catálogo: o Gemini 3.8 Flash tem promoção até 31/12/2026, e o roteador decide pelo preço de tabela.

A complexidade sai de quatro sinais:

estimar(tarefa, plano):
    n = tarefa.dica_do_decompositor ou padrão(tarefa.tipo)
    se tem_palavra_de_julgamento(tarefa.descrição): n = sobe(n)
    n = ajusta_por_tamanho_e_dependências(n, tarefa)
    se dependentes(tarefa, plano) >= 3 e não é_volume(tarefa): n = sobe(n)    # fundação
    senão se é_final(tarefa, plano) e nº_dependências(tarefa) >= 2: n = sobe(n) # peça entregue
    devolve n
Enter fullscreen mode Exit fullscreen mode

O degrau frontier ficou atrás de uma tabela de política (FRONTIER_ESCALATION, Sprint 33, 07/10/2026). A porta "sempre" vale para architecture, critical_review e code em alta complexidade. A porta "demanda complexa" vale para analysis, long_context_synthesis, review, multi_perspective_decomposition e redação (só família Anthropic), e exige demanda classificada como complexa e fatia frontier da sessão abaixo de 35%:

pode_subir(tarefa, família, sessão):
    regra = política.get(tarefa.tipo)
    se regra é nula ou tarefa.complexidade != ALTA: devolve falso
    se família não está em regra.famílias: devolve falso
    se regra.porta == SEMPRE: devolve verdadeiro
    devolve (sessão.faixa == COMPLEX
             e (sessão.atribuições < 3 ou sessão.fatia_frontier < 0.35))
Enter fullscreen mode Exit fullscreen mode

Os 35% são um parâmetro da política, calculado sobre o total de atribuições de modelo da sessão, e só passam a valer a partir da terceira atribuição. A estimativa da sprint: numa demanda complexa de 8 a 12 tarefas, 3 ou 4 vão ao frontier, e uma análise de alta complexidade passa de cerca de US$ 0,04 no Opus para cerca de US$ 0,20 no Fable.

Escadas das famílias Anthropic e OpenAI, da faixa econômica ao frontier, com as regras de subida e descida

O esforço de raciocínio também acompanha a complexidade: em tarefa alta, sobe um nível (baixo para médio, médio para alto). O topo da escala dos modelos novos ficou fora até ter custo medido.

4. Teto de concentração com folga para outage

Cada provedor pode receber no máximo uma fração das tarefas de um run: Anthropic 0,45, OpenAI 0,50, Google 0,60, Perplexity 0,50 e xAI 0,50. Quando um provedor passa da fatia, o plano é rebalanceado para a primeira alternativa viável de outra família.

O invariante que importa é o de queda:

para cada provedor p:
    assert soma(tetos) - tetos[p] >= 1.40
# soma = 2,55; pior caso (Google fora) = 1,95
Enter fullscreen mode Exit fullscreen mode

Se a conta não fecha, um provedor fora do ar torna o plano impossível de atribuir sem estourar os tetos.

Uma regra de prioridade evita conflito: orçamento é restrição dura e teto de fatia é flexível. No aperto de orçamento, o redirecionamento confere o teto de fatia e registra a violação quando não há saída, mas nunca estoura o orçamento para respeitar a fatia.

5. FinOps que dispara

Diagrama de fluxo do orçamento diário de US$ 300 repartido por provedor, modelo e família de tarefa

Três camadas de teto:

Camada Valor
execução US$ 25
global por dia US$ 300 (soma individual: US$ 350)
por provedor por dia Anthropic 100, OpenAI 70, Google 60, Perplexity 40, xAI 80
registrar_custo(chamada):
    tente:
        gasto = custo_faturado(chamada) or custo_por_tabela(chamada)
        ledger.somar(provedor, gasto)
        para limiar em (0.80, 0.95):
            se ledger.dia(provedor) >= limiar * teto(provedor)
               e não alertado_hoje(provedor, limiar):
                enviar_alerta_em_segundo_plano(provedor, limiar)
    se qualquer erro:
        log("contabilidade falhou")   # nunca derruba a chamada ao modelo
Enter fullscreen mode Exit fullscreen mode

Detalhes que vieram de defeito real:

  • Alerta sem chamador. Até 30/09/2026, os avisos de 80% e 95% do teto diário iam só para o log: a função de envio existia e nada a chamava. Hoje eles saem por mensagem e e-mail, com deduplicação persistida em disco por dia, escopo e limiar.
  • Custo faturado prevalece. xAI e Perplexity devolvem o custo na resposta, e esse valor vence a estimativa por tabela.
  • Cache que expira antes do reuso. De 1 a 24/09/2026, o Claude Sonnet 5 teve 1,83 milhão de tokens escritos no cache de prompt e zero lidos, porque a validade de 5 minutos acabava entre uma chamada Anthropic e a seguinte. Desde 25/09/2026 a validade padrão é 1 hora.
  • Preço errado no catálogo. Na vistoria de 07/09/2026, o preço de entrada do GPT-5.6 Luna estava em US$ 1,00 no catálogo contra US$ 0,20 na tabela (400% acima), e o roteador desviava do modelo barato.

Teto diário e teto de concentração de cada provedor no FinOps do geo-orchestrator

6. Três coisas que eu faria desde o primeiro dia

  1. Imprimir o plano antes de executar. Tipo, complexidade, modelo e origem da escolha por tarefa, com o custo estimado. A única chamada paga até ali é a decomposição.
  2. Medir quem o roteador deixa de fora. Em sete semanas (04/08 a 23/09/2026), o Grok recebeu de 1 a 3 chamadas porque era primário em 3 dos 23 tipos. O primário da pesquisa naquela época tinha nota 0,24 do juiz, custava US$ 0,59 e levava 245 s por chamada. Depois da troca, a chamada de verificação do Grok 4.7 em pesquisa custou US$ 0,035 em 10,3 s.
  3. Verificar contra a API viva. O catálogo é comparado com os endpoints de listagem de modelos de cada provedor, sem gastar token, e cada id novo passa por uma chamada real mínima antes de entrar.

O plano ao vivo, as ondas paralelas e o simulador de roteamento estão em https://alexandrecaramaschi.com/geo-orchestrator

Alexandre Caramaschi é Chief Strategy Officer da Nuvini (Nasdaq: NVNI), Founder da Brasil GEO, cofundador da NAIA e cofundador da AI Brasil. Foi CMO da Semantix (Nasdaq).

Top comments (0)