Um único modelo no cliente: o gateway divide automaticamente
Tire a escolha de modelo da interface — o cliente expõe um único nome de modelo, o planejamento roda no modelo forte e a execução cai no modelo econômico, divididos no salto que a requisição já estava fazendo.
Do que a comunidade realmente reclama
"Cada um tem um modelo diferente nas configurações e o mesmo prompt sai diferente para duas pessoas", "a pergunta mais comum na primeira semana de alguém é qual modelo devo escolher", "aposentar um modelo significa editar variáveis de ambiente em cada máquina de desenvolvimento". A escolha de modelo foi entregue às pessoas com menos informação para fazê-la: elas não veem o próprio gasto e não têm como saber se esta requisição em particular merece o modelo forte.
Se em vez disso você rebaixar todo mundo para um modelo barato, o trabalho degrada — entregue planejamento e julgamento arquitetural a um modelo pequeno e o retrabalho custa mais do que a economia. A divisão que realmente importa é o que esta requisição está fazendo, planejamento ou execução, e o cliente nunca contou isso ao gateway.
Como o GateLLM faz isso
O cliente mantém um único nome de modelo; um mapeamento catch-all (from "*") no gateway normaliza qualquer nome que o cliente peça, então editar configurações pessoais não muda mais onde a requisição chega. Não sobra nada a explicar sobre qual modelo escolher.
O sinal de divisão já está na conversa: o modo de plano do Claude Code injeta Plan mode is active na entrada e Exited Plan Mode na saída. Um script de slot anterior varre de trás para frente a partir da última mensagem, usa o último marcador visto para determinar o estado atual e então chama context.useModel() para trocar o roteamento. A decisão é uma comparação de posição de string — sem chamada separada de classificação, sem salto de rede extra.
A divisão precisa viver no slot anterior: o slot posterior vê o corpo traduzido do upstream e não consegue ler os marcadores injetados pelo cliente, e o useModel do slot posterior só troca dentro do mesmo protocolo, enquanto planejamento para execução é uma mudança de rota entre modelos. As regras de request_payload (prompt_cache_key e afins) precisam ser configuradas nos dois modelos: o modelo de entrada mantém a sua durante o planejamento, e a do modelo de destino se aplica quando a troca acontece.
5 alavancas que realmente funcionam
- Nome único de entrada: o cliente expõe um nome de modelo e um mapeamento catch-all from "*" normaliza todo nome solicitado para um modelo de destino
- Divisão automática: um script de slot anterior usa o último marcador varrendo de trás para frente — o marcador de entrada permanece no histórico para sempre, então uma verificação de "contém" leria o estado como modo de plano permanentemente
- Proteção de protocolo: o script verifica context.sourceProtocol primeiro e retorna cedo para tráfego não Anthropic, para que um modelo de entrada que atende vários clientes nunca seja mal roteado
- Observável: uma tag SW na coluna de modelo do log marca uma troca por script e MM marca um mapeamento de identidade; estatísticas e cobrança atribuem ao nome final do modelo, então toda decisão de divisão é auditável
- Zero implantação no cliente: mudanças de configuração não exigem edições por máquina e os mapeamentos recarregam a quente (a única exceção é o teto de heap do script SCRIPT_MEMORY_LIMIT_MB, que exige reinício)