Um Modelo de Decisão "System 1" para Atendimento em PT-BR — Parte 4: O Bake-off de Juízes e o v6 Híbrido
- decisum
- making-of
- benchmarks
Decisum é o nome público do modelo que chamamos internamente de "decisor". Esta série de making-of preserva a nomenclatura interna usada durante o desenvolvimento.
Raphael Pizzo — Especialista em Machine Learning Outubro de 2026 · Série técnica, parte 4
Nota de anonimização: como nas partes anteriores, nenhum nome de empresa, produto ou plataforma aparece neste texto. O juiz da Parte 3 (modelo de chat de propósito geral) segue sendo "o juiz". O novo modelo avaliado aqui — um modelo de decisão de propósito específico, acessado por API tipada — será chamado de juiz-D. O único nome real é o do autor.
1. O problema que sobrou: o teto do juiz único
A Parte 3 prometeu que o próximo capítulo seria produto, não treino. Esta parte é a exceção que confirma a regra — uma última volta de treino, justificada por um fato novo: apareceu um professor melhor a preço de café.
A vitória do v5 tinha uma verdade incômoda embutida: todo o train tinha sido re-rotulado por um único juiz — o mesmo modelo de chat, com o mesmo guia de anotação e os mesmos few-shots. O ouro humano (999 chamados do núcleo) provou que esse juiz era muito melhor que a prata de regex que o antecedeu. Mas "melhor que a prata" não é "bom o bastante": o próprio ouro mede a concordância do juiz com o humano, e ela está longe de 100% — numa amostra estratificada de 76 casos do núcleo, o juiz concorda com o humano em 71% das respostas, somadas as três perguntas (seção 4).
A pergunta científica natural: existe um juiz melhor? E a pergunta de engenharia, igualmente importante: a quanto?
2. O candidato improvável: um modelo que não conversa
O juiz-D não é um modelo de chat. Ele não recebe prompt de sistema, não
recebe few-shots, não gera texto livre. A API dele recebe um estado
(o texto do chamado) e um conjunto de perguntas tipadas — choice
(escolha entre opções, cada uma com uma descrição-critério) e score
(escala ordenada) — e devolve, por pergunta: a opção vencedora, as
probabilidades de cada opção e uma confiança.
Três propriedades mudam o jogo:
- Probabilidades por opção, nativamente. Um juiz de chat devolve um rótulo duro; pedir distribuição calibrada de um chat é teatro. O juiz-D devolve a distribuição de verdade — o que o torna um professor de destilação KL pronto, não só um rotulador.
- Preço de entrada irrisório e saída grátis. A chamada média saiu por ~US$ 0,00008. Rotular os 6.217 casos de CS do train custou US$ 0,49 no total — menos que o café da esquina.
- Sem few-shots. Todo o conhecimento de domínio tem que caber nas descrições-critério de cada opção — uma página de guia destilada em uma linha por categoria. Isso é uma limitação e um teste de pureza: mede o que o modelo sabe fazer por arquitetura, não por prompt.
O lado ruim, declarado antes dos números: o modelo não é determinístico (não há temperatura a fixar), e a própria documentação admite que abaixo de confiança 0,7 cerca de 40% das respostas mudam em repetição. Rótulo de treino não precisa ser perfeito — precisa ser melhor que a alternativa. É isso que o bake-off mede.
3. O desenho do bake-off
A régua é o ouro humano — o único conjunto em que confio cegamente, porque cada um dos 999 chamados do núcleo passou por olhos humanos (os meus), com adjudicação nos casos de baixa confiança.
- Amostra: 76 casos do núcleo do ouro, estratificados por categoria (seed 42). Amostra pequena de propósito: este é um teste de fumaça barato antes de comprometer um treino de 4 horas, não um estudo clínico.
- Juiz (chat): exatamente o pipeline da Parte 3 — guia de anotação completo + few-shots, temperatura 0. O melhor que o chat sabe fazer.
- Juiz-D: o mesmo estado do chamado (truncado em 12.000 caracteres,
confortavelmente abaixo do limite prático da API), as mesmas 3
perguntas, com os critérios de uma linha destilados do guia (incluindo
os quatro desempates difíceis descobertos na adjudicação do ouro).
Zero few-shots. Uma assimetria de protocolo declarada: urgência chega
ao juiz-D como
scoreordenado (0–3) e vira rótulo pelo argmax das probabilidades; para o chat, échoicecomo sempre foi. - Métrica: acurácia contra o ouro, por pergunta (categoria, decisão, urgência) e geral.
4. Resultado do bake-off
| pergunta | juiz (chat, guia+few-shots) | juiz-D (só critérios) |
|---|---|---|
| categoria | 0,763 | 0,711 |
| decisão | 0,697 | 0,816 |
| urgência | 0,671 | 0,737 |
| geral | 0,711 | 0,754 |
E nos 14 desacordos de categoria entre os dois juízes, o ouro concordou com o chat 9 vezes e com o juiz-D 5.
Leitura honesta, sem torcida:
- Não existe vencedor único — existe divisão de trabalho. O juiz-D entende melhor o que fazer (decisão) e quão grave é (urgência); o chat entende melhor que tipo de caso é (categoria). Faz sentido: categoria é a pergunta com 17 opções e fronteiras sutis de domínio — onde o guia completo e os few-shots do chat mais pesam.
- A margem geral (4,4pp) não é conclusiva com n=76; as margens por pergunta são mais informativas. Decisão (+11,9pp) é o sinal mais forte do bake-off.
- O custo assimétrico muda a decisão mesmo sem vencedor claro. Se o juiz-D empatasse em tudo, ainda assim seria interessante: centavos por mil casos e probabilidades por opção de graça.
5. A destilação híbrida
A regra de montagem do train v6 cai direto da tabela acima — cada pergunta fica com o juiz que o ouro aprovou:
| pergunta | rótulo do v6 | por quê |
|---|---|---|
| categoria | juiz (chat) — como já estava | 0,763 vs 0,711; ouro 9×5 nos desacordos |
| decisão | juiz-D (argmax) | 0,816 vs 0,697 |
| urgência | juiz-D (argmax) | 0,737 vs 0,671 |
Destilar os 6.217 casos de CS (3.982 do train re-rotulado da Parte 3 + 2.235 casos novos de abr–out, recuperados de exports antigos e dedupados contra corpus e ouro) levou ~7 minutos, zero falhas, US$ 0,49. As probabilidades por opção de cada caso ficaram arquivadas — são os soft targets de uma futura destilação KL, se o argmax desta rodada mostrar que a direção é boa.
5.1 O que a troca de juiz mudou nos rótulos
| pergunta | rótulos trocados | o que mudou |
|---|---|---|
| decisão | 35,7% | escalar 984 → 2.220; executar_acao 4.498 → 2.949; pedir_mais_info 464 → 933; rejeitar 208 → 22 |
| urgência | 28,4% | 3 - crítica 703 → 271; 1 - moderada 2.177 → 2.502 |
O juiz-D é sistematicamente mais conservador: escala mais, executa menos no nível 1, e distribui muito menos "crítica". Como o ouro concorda mais com ele exatamente nessas duas perguntas, a leitura é que o juiz de chat estava super-resolvendo e super-dramatizando — comportamento coerente com um modelo treinado para agradar ("posso resolver isso pra você!").
5.2 O que NÃO mudou
- Os dados externos de robustez (e-commerce público e tickets em inglês) seguem com os rótulos originais: o bake-off não mediu esse domínio, e não se troca o que não se mediu.
- O ouro segue intocável como teste permanente. Nenhum rótulo do ouro participa de treino; nenhum juiz novo "vota" nele.
- Config de treino: idêntica à do v5 (2 épocas, smoothing 0,05, sem class weighting). Duas variáveis mudam de uma vez — dados novos e rótulos novos — e a seção 6 vai precisar ser honesta sobre esse confundimento deliberado: esta é uma série de engenharia com GPU contada, não um delineamento fatorial.
6. Resultados do v6 contra o ouro
Protocolo: split por caso (seed 42) sobre o ouro (999 núcleo adversarial
- 500 aleatórios não-enviesados; 1.499 casos × 3 perguntas), temperature scaling ajustado no split de calibração, métricas no teste. As ECEs abaixo são pós-temp.
Tabela principal (teste, n = 753 casos por pergunta):
| métrica | v6 | v5 | v3 |
|---|---|---|---|
| acc categoria | 0,5578 | 0,5299 | 0,3028 |
| acc decisao | 0,5963 | 0,6202 | 0,6215 |
| acc urgencia | 0,6746 | 0,6388 | 0,3240 |
| acc geral | 0,6096 | 0,5963 | 0,4161 |
| macro-F1 categoria | 0,4135 | 0,3859 | 0,1882 |
| ECE pós-temp (cat / dec / urg) | 0,066 / 0,044 / 0,028 | 0,046 / 0,052 / 0,044 | 0,059 / 0,096 / 0,125 |
Breakdown por subset (acurácia, "todas" = média das 3 perguntas):
| subset | v6 | v5 | v3 |
|---|---|---|---|
| núcleo (n = 999 casos) | 0,5882 | 0,5835 | 0,4011 |
| aleatorio (n = 500 casos) | 0,6510 | 0,6211 | 0,4453 |
Veredito pela regra fixada a priori: o v6 vence — 0,5882 contra 0,5835 do v5 no subset núcleo (+0,5 pp no critério acordado).
Leitura honesta. O híbrido ganhou onde o bake-off dizia que ganharia: a categoria (única pergunta em que o juiz-chat foi escolhido) subiu +2,8 pp no geral e +7,8 pp no subset aleatório, e a urgencia (juiz-D) subiu +3,6 pp, com macro-F1 de categoria também acima do v5. A perda ficou na decisao (−2,4 pp contra o v5), pergunta em que o juiz-D já empatava com o juiz-chat no bake-off — trocar o rotulador não comprou nada ali, e o v3 segue ligeiramente acima dos dois nessa pergunta, um sinal de que decisao pode ter um teto ligado à ambiguidade intrínseca dos casos, não ao rotulador. O confundimento de variáveis é declarado como foi planejado: mudamos dados novos e rótulos novos ao mesmo tempo, então não é possível atribuir o ganho isoladamente a um dos dois — o que a tabela permite dizer é que o pacote inteiro não degradou nenhuma pergunta além da margem acima e ainda entregou a maior cobertura de roteamento automático entre os candidatos (17,4% das linhas com acurácia 0,83 no auto). Sobre o subset aleatório, a ressalva de circularidade permanece: o juiz-chat rotulou o treino do v6, então os 0,651 devem ser lidos como teto otimista — foi exatamente por isso que o critério fixado a priori olha só o núcleo. A calibração pós-avaliação convergiu (T* = 1,15 / 1,35 / 1,30 para 4 / 5 / 17 opções; ECE no split de calibração 0,018 / 0,030 / 0,059) e está gravada no checkpoint.
Estado da API: o v5 segue em produção. O v6 está calibrado e apto ao swap — que fica pendente de autorização explícita do dono, dado que o v5 acabou de entrar.
7. Se o v6 vencer: o caminho da destilação de verdade
Esta rodada usou o juiz-D como rotulador de argmax. Mas ele devolve a distribuição inteira por opção — e isso habilita o passo que a literatura chama de destilação propriamente dita: treinar o aluno com KL divergence contra os soft targets do professor, em vez de entropia cruzada contra rótulos duros. Soft targets carregam a geometria do professor ("este caso é 52% bug e 45% dúvida" informa muito mais que "bug"), e é a técnica por trás de meia década de modelos pequenos que performam acima do que seu tamanho sugere. Os 6.217 conjuntos de probabilidades já estão arquivados esperando a decisão.
8. Lições da Parte 4
- Juiz também se audita. O bake-off de juízes contra o ouro custou centavos e 10 minutos — e evitou assumir que "o juiz que já temos" é o teto.
- Modelo especializado vence prompt engenhoso em 2 de 3 perguntas; na terceira (categoria, 17 opções de fronteira sutil), o guia completo e os few-shots do chat ainda pagam a diferença.
- Híbrido não é gambiarra, é alocação: cada pergunta com o juiz que o ouro aprovou — e o v6 confirmou no teste, ganhando exatamente nas perguntas onde trocou de juiz.
- Probabilidade por opção é o ativo subestimado. Rótulo duro todo mundo dá; distribuição calibrada, não.
- Vitória por critério a priori vale mais que vitória retórica. O ganho no núcleo foi de meio ponto percentual — real, mas dentro da margem de ruído; a região de decisao ainda regrediu. A destilação KL com os soft targets arquivados é o próximo alavancamento natural, não um luxo.
- Critério fixado antes de ver o número protege contra autoengano. O subset aleatório mostrou +3 pp a favor do v6, mas é circular (juiz-chat rotulou o treino); o critério legítimo foi o núcleo.
9. v8: a aposta multilíngue
O v6 tinha um teto óbvio: 6.217 casos, todos em português. A aposta do v8 foi destravar escala com o ativo mais barato do pipeline — o juiz-D — em outro idioma: 48.765 linhas de tickets em inglês (fontes públicas de suporte), rotuladas pelo juiz-D com os mesmos critérios de uma linha, somadas à receita inteira do v6. Treino e config idênticos; a única variável nova é o corpus EN.
Asterisco metodológico, declarado antes da tabela: o juiz-D foi validado por bake-off apenas em PT-BR. A transferência para o inglês foi assumida, não medida — a auditoria humana de 50 casos EN estava pendente no momento da escrita desta seção.
Tabela principal (teste, n = 753 casos por pergunta):
| métrica | v8 | v6 | v5 | v3 |
|---|---|---|---|---|
| acc categoria | 0,5339 | 0,5578 | 0,5299 | 0,3028 |
| acc decisao | 0,5989 | 0,5963 | 0,6202 | 0,6215 |
| acc urgencia | 0,6786 | 0,6746 | 0,6388 | 0,3240 |
| acc geral | 0,6038 | 0,6096 | 0,5963 | 0,4161 |
| macro-F1 categoria | 0,4113 | 0,4135 | 0,3859 | 0,1882 |
| ECE pós-temp (cat / dec / urg) | 0,066 / 0,048 / 0,033 | 0,066 / 0,044 / 0,028 | 0,046 / 0,052 / 0,044 | 0,059 / 0,096 / 0,125 |
Breakdown por subset (acurácia "todas"):
| subset | v8 | v6 | v5 | v3 |
|---|---|---|---|---|
| núcleo (n = 999 casos) | 0,5869 | 0,5882 | 0,5835 | 0,4011 |
| aleatorio (n = 500 casos) | 0,6367 | 0,6510 | 0,6211 | 0,4453 |
Veredito pela regra fixada a priori (acc geral no núcleo): o v8 NÃO vence — 0,5869 contra 0,5882 do v6, uma derrota por 0,13 pp, dentro da margem de ruído do teste mas uma derrota pela régua acordada, e derrotas pela régua acordada se registram com o mesmo cuidado das vitórias (tradição do v4). Sem calibração, sem fila de produção.
Leitura honesta. O inglês não quebrou o modelo — 0,6038 no geral, acima do v5, e a urgencia até melhorou (0,6786, melhor marca da linhagem) —, mas também não moveu a régua que importa. No núcleo, o v8 ganhou a categoria (+0,6 pp sobre o v6) e a urgencia (+0,4 pp), e perdeu na decisao (−1,4 pp), pergunta que segue amaldiçoada: o v6 já havia regredido ali contra o v5 (0,5963 × 0,6202) e o v8 apenas recuperou parte do estrago (0,5989), permanecendo abaixo de um modelo três gerações mais velho. O padrão de confusão do v8 no núcleo (conta_config ↔ duvida_produto, bug_produto → incidente) é o mesmo de sempre, agora em versão bilíngue. Duas hipóteses ficam abertas, e nenhuma é inocente: ou o juiz-D em EN rotula com viés diferente do validado em PT (e a auditoria pendente de 50 casos humanos é exatamente o teste entre as duas), ou o ganho de escala em dados fora de domínio simplesmente dilui os 6.217 casos de CS que carregam a régua. Enquanto isso não se desfaz, o corpus EN é um ativo em observação, não um fato consumado.
Estado da API: o v5 segue em produção; o v6 segue calibrado e na fila do swap; o v8 fica sem calibração, checkpoint arquivado como candidato reprovado pelo critério. Por decisão do dono, o v9 (receita do v8 + 136.845 linhas de fontes públicas rotuladas pelo juiz-D) entrou na GPU logo após esta avaliação — os números do v8 foram analisados enquanto o v9 treinava, e a próxima seção tratará dele.
10. v9: a escala máxima — e o teto que ela não moveu
O v8 perdeu por 0,13 pp, um empate técnico. A leitura da seção 9 deixou duas hipóteses abertas — viés de rótulo do juiz-D em EN, ou diluição de domínio — e o v9 foi desenhado para testá-las à força: receita inteira do v8 mais 136.845 linhas novas de fontes públicas HF, todas rotuladas pelo juiz-D — twitter (74,6k, com oversampling de mensagens de raiva), bitext (55,5k, EN), openjev_cs (3,4k) e br_pt (2,8k). Treino e config idênticos; a variável nova é volume puro, o maior lote externo da linhagem.
Tabela principal (teste, n = 753 casos por pergunta):
| métrica | v9 | v8 | v6 | v5 | v3 |
|---|---|---|---|---|---|
| acc categoria | 0,5378 | 0,5339 | 0,5578 | 0,5299 | 0,3028 |
| acc decisao | 0,5883 | 0,5989 | 0,5963 | 0,6202 | 0,6215 |
| acc urgencia | 0,6454 | 0,6786 | 0,6746 | 0,6388 | 0,3240 |
| acc geral | 0,5905 | 0,6038 | 0,6096 | 0,5963 | 0,4161 |
| macro-F1 categoria | 0,4193 | 0,4113 | 0,4135 | 0,3859 | 0,1882 |
| ECE pós-temp (cat / dec / urg) | 0,081 / 0,053 / 0,045 | 0,066 / 0,048 / 0,033 | 0,066 / 0,044 / 0,028 | 0,046 / 0,052 / 0,044 | 0,059 / 0,096 / 0,125 |
Breakdown por subset (acurácia "todas"):
| subset | v9 | v8 | v6 | v5 | v3 |
|---|---|---|---|---|---|
| núcleo (n = 999 casos) | 0,5775 | 0,5869 | 0,5882 | 0,5835 | 0,4011 |
| aleatorio (n = 500 casos) | 0,6159 | 0,6367 | 0,6510 | 0,6211 | 0,4453 |
Veredito pela regra fixada a priori (acc geral no núcleo): o v9 PERDEU — 0,5775 contra 0,5882 do v6, uma derrota por 1,07 pp. Não é mais empate técnico: é a primeira regressão de mais de 1 ponto no núcleo desde o v4, e ela veio justamente do experimento de maior escala da linhagem. Sem calibração, sem fila.
Leitura honesta, ressalva por ressalva. (1) A auditoria EN do juiz-D segue pendente com o dono — e o v9 agravou exatamente a aposta não auditada, acrescentando 55,5k linhas bitext em inglês às 48,7k do v8. O sinal indireto aponta para ruído de rótulo: as duas perguntas que regrediram (decisao −1,1 pp sobre o v8, urgencia −3,3 pp) são as mais sensíveis ao tom do rótulo, enquanto categoria, a mais lexical, melhorou. Mas sem os 50 casos auditados isso é atribuição plausível, não medição — e agora há 184k linhas EN em dois checkpoints arquivados pousando nessa incógnita. (2) O oversampling de raiva do twitter foi checado na distribuição de erros e inocentado no mérito relevante: no núcleo, os erros que mais cresceram foram baixa → moderada (67 no v8, 80 no v9), não moderada → alta (18 → 16), e alta → moderada ficou estável (47 → 50). A regressão de urgência vem da fronteira baixa ↔ moderada — o modelo novo hesita mais entre "pode esperar" e "precisa de atenção" —, não de urgência inflada. Se o oversampling teve efeito, foi borrar essa fronteira, não empurrar o medidor para cima. (3) O "outro" não virou lixeira: F1 de 0,676 contra 0,689 do v8, estável, e nenhuma das 12 confusões mais frequentes do v9 termina em "outro" — os 16k de "outro" do bloco novo não contaminaram o comportamento no ouro. O que os dados novos de fato mudaram: a categoria subiu no núcleo (+0,6 pp sobre o v8) e o macro-F1 de categoria é o melhor da linhagem inteira — os volumes ajudam a separar o que o chamado é, mas cobram o preço em o que fazer com ele e com que pressa. Por fim, um dado que fecha qualquer atalho: o ECE de categoria do v9 (0,081) é o pior dos recentes — ele não seria promovido nem como calibrado. O teto do núcleo segue em 0,5882, marcado pelo v6, um modelo treinado só com os 6.217 casos de CS e zero volume externo.
Estado da API: o v5 segue em produção; o v6 segue
calibrado e na fila do swap; o v8 e o v9 ficam sem calibração,
checkpoints arquivados como reprovados pelo critério. O próximo
candidato já tem dados prontos — o v7-KL, destilação com soft targets
em data/processed_v7/ —, e o teto que o v9 não moveu define o que
ele precisa quebrar.
11. v7-KL: soft targets contra rótulos duros — o experimento controlado
O v7 é o experimento mais limpo da linhagem: mesmos 18.651 exemplos do
v6, mesmo backbone, mesma agenda — a única diferença é que decisão e
urgência carregam a distribuição completa do juiz-D (probs_alvo,
KL-divergência com alpha 1.0 e temperatura 2.0) em vez do rótulo duro.
Categoria, que não recebeu soft target nenhum, funciona como controle
negativo embutido no desenho. A pergunta é direta: a incerteza que o
professor confessa (entropia normalizada média de 0,43 em decisão, 0,42
em urgência) chega ao aluno ou evapora no caminho?
Avaliação contra o ouro, mesma régua de sempre (split por caso seed 42, temperatura calibrada no calib, métricas no teste, n=753 linhas por modelo). O campeão vigente é o v6 (núcleo 0,5882); o v9 entrou na mesma rodada para referência.
11.1 Núcleo duro (subset adversarial, n=497 por pergunta)
| pergunta | v7-KL | v6 (campeão) | v9 (referência) |
|---|---|---|---|
| categoria | 0,5272 | 0,5191 | 0,5372 |
| decisao | 0,5996 | 0,5795 | 0,5533 |
| urgencia | 0,6640 | 0,6660 | 0,6419 |
| todas | 0,5969 | 0,5882 | 0,5775 |
11.2 Headline de produção (subset aleatório, n=256 por pergunta)
| pergunta | v7-KL | v6 (campeão) |
|---|---|---|
| categoria | 0,6016 | 0,6328 |
| decisao | 0,6562 | 0,6289 |
| urgencia | 0,7031 | 0,6914 |
| todas | 0,6536 | 0,6510 |
11.3 Teste completo (n=2259 linhas)
| métrica | v7-KL | v6 (campeão) |
|---|---|---|
| acc geral | 0,6162 | 0,6096 |
| ECE categoria | 0,0736 | 0,0656 |
| ECE decisao | 0,0677 | 0,0440 |
| ECE urgencia | 0,0246 | 0,0282 |
| macro-F1 categoria | 0,3833 | 0,4135 |
11.4 Veredito do experimento
O KL venceu, com ressalvas que importam. No núcleo — o subset que decide promoção — o v7 marcou 0,5969 contra 0,5882 do v6 (+0,87 p.p.), novo teto da linhagem, e confirmou a direção no aleatório não-enviesado (0,6536 contra 0,6510). O ganho vem inteiro de decisão: +2,0 p.p. no núcleo e +2,7 p.p. no aleatório, exatamente a pergunta onde o professor mais confessa incerteza — a hipótese do apêndice A.3 se confirmou onde ela era testável. Urgência empatou dentro do ruído (0,6640 contra 0,6660 no núcleo), e categoria — o controle que não recebeu tratamento nenhum — ficou a meio ponto percentual do v6 no núcleo, o que é exatamente o esperado se a única coisa que mudou foi o alvo das duas perguntas tratadas. Em outras palavras: o experimento controlado se comportou como um experimento controlado. As ressalvas são honestas: o macro-F1 de categoria caiu de 0,4135 para 0,3833 (o soft target não explica categoria, mas o modelo compartilha tronco e o desgaste aparece ali), o ECE de decisão piorou de 0,0440 para 0,0677 — o aluno ficou mais acertivo e menos calibrado onde o professor era ambíguo — e no aleatório de categoria o v6 segue 3 pontos à frente. Soft targets não são mágica: são um ganho real e modesto, concentrado na pergunta certa, com custo de calibração que a temperatura por pergunta (T=1,25 nas 17 classes de categoria, 0,75 nas 4 de urgência, 1,10 nas 5 de decisão) absorve parcialmente. Para a próxima geração, a combinação óbvia é manter o KL em decisão/urgência e investigar de separadamente por que a categoria desgente quando os vizinhos mudam de alvo. Conclusão prática: neste regime de dados, soft target supera rótulo duro; o rótulo duro deixa de ser o padrão para decisão e urgência.
Estado da API: o v5 segue em produção, intocado. O v6
permanece calibrado e passa a ser o rollback imediato; o v7-KL está
calibrado (temperaturas salvas em models/decisor-v7/temperaturas.pt)
e é o novo campeão do núcleo — a promoção a produção fica condicionada
ao swap via scripts/trocar_api_v5.sh, com rollback simétrico. O v8 e o
v9 seguem arquivados como reprovados pelo critério.
Apêndice A — A destilação KL em carne e osso (engenharia)
A seção 7 conta o porquê; este apêndice conta o como, porque o diabo da destilação mora em três linhas de código.
A.1 A loss
O treinador do decisor usa uma cabeça de option-markers: cada pergunta gera logits sobre até 32 opções, com os slots de padding travados em −1e4 (softmax ali ≈ softmax só nas opções válidas). A loss por exemplo, antes, era CE dura com label smoothing manual mascarado (o smoothing padrão do PyTorch espalha massa nos slots de padding — o episódio da "loss 666" da Parte 3 nasceu disso).
A destilação entra por linha, não por dataset:
se a linha tem probs_alvo (veio do juiz-D):
p_T = normalize(p_alvo ** (1/T)) # professor suavizado
KL = Σ p_T · (log p_T − log_softmax(logits/T)) · T²
per = α · KL + (1−α) · NLL(argmax) # âncora dura opcional
senão:
per = CE dura com smoothing (como sempre foi)
T = 2,0 e α = 1,0 no config v7. Três decisões de desenho, e o
motivo de cada:
- α = 1,0 (KL puro, sem âncora dura). O rótulo duro da linha já é o argmax do próprio professor — a âncora estaria redundante com o pico da distribuição destilada. Se um dia desconfiarmos que o professor erra sistematicamente num nicho, α = 0,7 devolve 30% de peso ao argmax sem custo novo.
- Linhas destiladas não levam label smoothing. Smoothing espalha massa uniformemente; a distribuição do professor já codifica qual incerteza existe e onde (52% bug × 45% dúvida não é "40% em qualquer lugar"). Smoothing por cima seria dupla borragem.
- Professor renormalizado sobre as opções válidas da linha. A API
devolve probs sobre as opções que recebeu; a renormalização defensiva
cobre qualquer divergência de conjunto (e as 7 linhas em 12.434 —
0,06% — em que o campo
choicediverge do argmax das probabilidades; ruído de desempate interno do professor, mantido como está: ochoiceé o rótulo oficial, as probs carregam a geometria).
A.2 O bug que era do teste, não do código
A verificação numérica da loss KL quase reprovou o treinador por um
motivo instrutivo: o teste comparava contra
torch.distributions.kl_divergence sobre logits sem mascarar os
slots de padding. Sem o −1e4, o softmax do aluno espalha massa pelos 32
slots; com ele, concentra nas 5 opções reais. A "divergência" era o
teste medindo uma distribuição que o modelo nunca vê. Replicada a
máscara no teste, a loss confere com a referência do PyTorch até a 6ª
casa decimal — e as linhas sem soft target saem bit a bit com a loss
antiga, o que importa por um motivo operacional: o treino do v6
rodava na GPU enquanto o treinador era editado no disco. O container
já tinha o código em memória, e mesmo numa re-execução hipotética o
comportamento seria idêntico (sem probs_alvo nos dados, os ramos novos
são inertes). Edição cirúrgica com padrões desligados é como se mexe num
treinador em produção.
A.3 O que os dados já dizem antes do treino
A entropia normalizada média das distribuições do juiz-D é 0,43 em decisão e 0,42 em urgência (0 = professor decidido, 1 = dúvida total). Ou seja: em quase metade da massa de probabilidade o professor está confessando incerteza — exatamente o conhecimento que o rótulo duro joga fora e que o KL preserva. Se o v6-híbrido confirmar a direção no ouro, o v7 não precisa de um caso novo de dados: mesma base, alvo mais rico.
12. v10: a receita inteira — e o novo teto
O v10 não tem variável nova. Ele é o primeiro modelo da linhagem a combinar, num único treino, as três alavancas que as seções anteriores validaram isoladamente — e é exatamente por isso que ele fecha esta parte do artigo:
- O híbrido de juízes do v6 (seção 5): categoria pelo juiz de chat, decisão e urgência pelo juiz-D.
- A destilação KL do v7 (seção 11): decisão e urgência com soft targets completos do juiz-D (α = 1,0, T = 2,0), não rótulos duros.
- Casos novos de domínio: 234 casos minerados dos exports de ago→out (702 linhas), com o parsing corrigido do formato SELECT, dedupados contra corpus e ouro, rotulados pelo juiz-D por US$ 0,019 — o lote mais barato da linhagem.
Treino e agenda idênticos aos anteriores (37.645 steps, ~4 h na GPU de treino). A régua é a de sempre: acurácia geral no núcleo adversarial do ouro, split por caso seed 42, temperatura calibrada no split de calibração, métricas no teste. O campeão vigente é o v7-KL (0,5969); o v6 (0,5882) entra como referência da base comum.
12.1 Núcleo duro (subset adversarial, n=497 por pergunta)
| pergunta | v10 | v7-KL | v6 |
|---|---|---|---|
| categoria | 0,5231 | 0,5272 | 0,5191 |
| decisao | 0,6076 | 0,5996 | 0,5795 |
| urgencia | 0,6660 | 0,6640 | 0,6660 |
| todas | 0,5989 | 0,5969 | 0,5882 |
12.2 Headline de produção (subset aleatório, n=256 por pergunta)
| pergunta | v10 | v7-KL | v6 |
|---|---|---|---|
| categoria | 0,5938 | 0,6016 | 0,6328 |
| decisao | 0,7148 | 0,6562 | 0,6289 |
| urgencia | 0,7031 | 0,7031 | 0,6914 |
| todas | 0,6706 | 0,6536 | 0,6510 |
12.3 Teste completo (n=753 casos por pergunta)
| métrica | v10 | v7-KL | v6 |
|---|---|---|---|
| acc geral | 0,6233 | 0,6162 | 0,6096 |
| acc categoria | 0,5471 | 0,5525 | 0,5578 |
| acc decisao | 0,6441 | 0,6189 | 0,5963 |
| acc urgencia | 0,6786 | 0,6773 | 0,6746 |
| macro-F1 categoria | 0,4215 | 0,3833 | 0,4135 |
| ECE pós-temp (cat / dec / urg) | 0,049 / 0,043 / 0,037 | 0,074 / 0,068 / 0,025 | 0,066 / 0,044 / 0,028 |
| roteamento linha (% auto @ acc) | 21,9% @ 0,854 | 20,2% @ 0,816 | 17,4% @ 0,832 |
12.4 Veredito do experimento
O v10 venceu pela regra fixada a priori — 0,5989 contra 0,5969 do v7-KL no núcleo (+0,2 p.p.) e é o novo teto da linhagem. A margem do critério é pequena, mas o v10 não é um empate envernizado: ele abre vantagem onde a régua não olha diretamente — 0,6233 no teste completo (melhor marca da linhagem), 0,6706 no aleatório não-enviesado (melhor marca), e o maior salto aparece na decisão: 0,6441 no teste completo, a pergunta que estava amaldiçoada desde o v3. Toda a linhagem v6 em diante havia regredido nessa pergunta (o v3 marcara 0,6215 e o v5, 0,6202); o v10 é o primeiro a superar os dois com folga — e com correção de prior por Bayes-EM chega a 0,6587, com macro-F1 de decisão saltando de 0,31 para 0,43 (nos predecessores, o mesmo ajuste mal movia o macro-F1: o v10 aprendeu classes de decisão que os outros nem tentam prever). No roteamento, a cobertura automática sobe para 21,9% das linhas com acurácia 0,854 no auto — mais cobertura e mais acurácia que qualquer antecessor, a combinação que normalmente troca uma pela outra.
As ressalvas, sem verniz nenhum. (1) Categoria puro regrediu — 0,5471 contra 0,5578 do v6, terceira geração seguida em que categoria fica aquém do v6-híbrido. Com vector scaling pós-hoc o v10 vai a 0,579, a melhor marca da mesa, mas isso é remendo de calibração, não aprendizado: a fronteira bug_produto ↔ incidente ↔ duvida_produto ↔ conta_config segue sendo o eixo cego do projeto, e nenhuma alavanca testada até aqui a atacou de frente. (2) As classes de cauda seguem sem dados — duvida_comercial (12 casos no ouro) tem F1 zero em todos os modelos da tabela; reembolso (3 casos) oscila ao sabor do split. Nenhum treino corrige o que o ouro mal mede. (3) A margem no critério (+0,2 p.p.) está dentro do ruído do teste — o que a sustenta é o conjunto da obra: vitória consistente nos três subsets, na pergunta mais difícil, e no roteamento. E uma nota de reprodutibilidade que vale mais que qualquer margem: o v6 e o v7 reavaliados nesta rodada reproduziram exatamente os números das seções 6 e 11 (0,5882 e 0,5969 no núcleo) — a régua é estável, o split não vaza, e as diferenças reportadas ao longo desta série são de modelo, não de medição.
A calibração pós-avaliação convergiu e está gravada no checkpoint (T* = 1,05 / 0,85 / 1,25 para decisão, urgência e categoria; ECE de calibração 0,018 / 0,024 / 0,041 — o ECE de categoria caiu de 0,114 para 0,041, o maior ganho de temperatura da linhagem).
Estado da API: o v10 está em produção desde 17/out —
swap autorizado pelo dono e executado com rollback simétrico pronto
(scripts/rollback_api_v5.sh recoloca o v5 no ar em ~1 min). O v7-KL
é o rollback imediato; o v6, terceira linha.
12.5 A tabela consolidada — doze gerações contra o ouro
Para fechar a parte 4, a linhagem inteira na mesma régua (acurácia geral no teste completo; negrito no campeão de cada onda):
| geração | o que mudou | geral | destino |
|---|---|---|---|
| v3 | primeira receita KL-capaz, prata de regex | 0,4161 | arquivado |
| v5 | ouro de juiz de chat + hard labels | 0,5963 | produção até 17/out |
| v6 | híbrido de juízes (bake-off) | 0,6096 | rollback 2ª linha |
| v8 | +48,8k linhas EN (juiz-D) | 0,6038 | reprovado |
| v9 | +136,8k linhas HF (juiz-D) | 0,5905 | reprovado |
| v7-KL | soft targets KL do juiz-D | 0,6162 | rollback imediato |
| v10 | receita completa: híbrido + KL + casos novos | 0,6233 | membro da campeã |
| v11_cons | +reclamações reais (curadoria conservadora) | 0,6127 | melhor macro-F1 |
| v11e | ensemble v10+v11_cons | 0,6282 | campeã por 24h |
| v12stack | +focal/R-Drop/FGM/SWA (pilha completa) | 0,5644 | ❌ super-regulariza |
| swa | só SWA isolado da pilha | 0,6242 | melhor single |
| v10+swa | ensemble do campeão | 0,6339 | 🏆 EM PRODUÇÃO |
As lições que atravessam as doze gerações:
- Escala de rótulo de juiz, sozinha, dilui (v8, v9, v12active) — volume sem curadoria é ruído, não sinal.
- O conhecimento do professor vale mais que o volume (KL com os mesmos dados vence volume novo 5× maior) — mas escolher O QUE destilar importa mais ainda (SWA do que o professor sabe; focal/R-Drop do que ele não sabe).
- A técnica campeã estava escondida dentro do fracasso — a pilha completa perdeu 4,8 p.p., mas a ablação revelou que SWA sozinho era ouro puro. Sem ablação componente-a-componente, o campeão teria sido descartado junto com o fracasso.
- Pré-treino adicional em encoder pequeno é bomba-relógio — DAPT over-trained destruiu o modelo (−20 p.p.); a janela entre "adaptado" e "esqueceu como classificar" é estreita e sem sinal de parada.
13. O v11: o programa de dados dirigido (síntese verificada + reclamações reais)
Depois do v10, a questão deixou de ser "mais dados" e passou a ser dados apontados para os erros medidos. O v11 nasce de quatro fontes novas, todas passando pelo mesmo funil (dedup contra o ouro e o treino, rotulagem híbrida — categoria por juiz de chat, decisão/urgência por juiz-D com probabilidades — e verificação):
- Corpus sintético verificado (~9,1 mil conversas): geração dirigida às caudas medidas (fraude, frete, prazos) e às fronteiras do eixo cego (bug × dúvida × conta × incidente), com pares contrastivos e pares de calibração de urgência (calmo-crítico × bravo-banal); tudo filtrado por juiz — 26% de rejeição, concentrada exatamente nas fronteiras visadas.
- Churn real (318 conversas reais de clientes, dedup por protocolo).
- Amostra do Consumidor.gov.br (portal público de reclamações): 30,2 mil reclamações reais com resposta da empresa e desfecho, das quais 22,2 mil do comércio eletrônico — 75% mapeando nas categorias-cauda (frete 5,2 mil, reembolso 5,1 mil, prazos 2,2 mil).
- Pacote externo híbrido (2 mil conversas com probabilidades do juiz-D já embutidas).
Duas dosagens foram montadas sobre a receita do v10 (mesma arquitetura, mesmos hiperparâmetros, KL ligado): conservadora (~1,3:1 novo:base) e agressiva (tudo). A conservadora treinou primeiro.
13.1 Resultado na régua oficial (conservadora)
| métrica | v10 | v11 | Δ |
|---|---|---|---|
| núcleo (métrica oficial) | 0,5989 | 0,6009 | +0,20 p.p. |
| geral | 0,6233 | 0,6127 | −1,06 p.p. |
| categoria | 0,5471 | 0,5564 | +0,93 p.p. |
| macro-F1 categoria (17 classes) | 0,4215 | 0,5037 | +8,22 p.p. |
| decisão | 0,6441 | 0,6109 | −3,32 p.p. |
| urgência | 0,6786 | 0,6707 | −0,79 p.p. |
13.2 Leitura
O programa venceu exatamente onde mirou: o subset núcleo — casos difíceis adjudicados por humanos, onde vivem as caudas — subiu, e o macro-F1 de categoria deu o maior salto da linhagem desde o v5 (+8,2 p.p., movido pelas classes que até aqui tinham F1 próximo de zero). O custo apareceu no subset aleatório e na decisão: a hipótese de trabalho é que o rótulo do juiz-D sobre reclamações (estilo "consumidor versus empresa") desloca o prior de decisão — o registro público de reclamações ensina "escalar/rejeitar" mais do que o chat de plataforma ensina. É a próxima fronteira de calibragem: correção de prior por origem do dado.
13.3 Dosagem agressiva (v11b) — o teste da escala com funil
O perfil agressivo (toda a amostra nova, ~575 mil linhas) respondeu a pergunta deixada em aberto — e a resposta confirmou a lição do v9, agora com funil de qualidade no caminho:
| métrica | v10 | v11 (conservador) | v11b (agressivo) |
|---|---|---|---|
| núcleo (oficial) | 0,5989 | 0,6009 | 0,5983 |
| geral | 0,6233 | 0,6127 | 0,6144 |
| categoria | 0,5471 | 0,5564 | 0,5671 |
| decisão | 0,6441 | 0,6109 | 0,6003 |
| macro-F1 categoria | 0,4215 | 0,5037 | 0,4771 |
O agressivo emplacou o melhor acerto bruto de categoria, mas o volume cheio do registro público de reclamações re-diluiu o equilíbrio das caudas (macro-F1 cai 2,7 p.p. frente ao conservador) e o núcleo ficou abaixo até do v10. Direção segue batendo escala — mesmo com dedup, dois juízes e KL. A conclusão operacional: o ganho sustentável mora na seleção (active learning), não no volume; e o conservador é a dosagem de referência para as próximas rodadas.
14. A regressão de decisão explicada (prior-por-origem)
A análise dos fluxos de erro na decisão revelou um padrão concentrado:
das 69 respostas onde o v10 acertava e o v11 errou, 52 (75%) seguem um
único fluxo: casos onde a resposta correta era executar_acao e o v11
passou a predizer escalar. A assinatura é inconfundível do professor:
o registro público de reclamações (Consumidor.gov.br) ensina o estilo
"consumidor versus empresa", onde a resposta certa é escalar para um
humano — não executar uma ação automática. O dado é bom para categoria
(caudas, macro-F1 +8,2 p.p.) mas desloca o prior de decisão.
A correção é treinável: distribution matching (casar a marginal do professor com a marginal do ouro por pergunta) ou simplesmente reduzir o peso da fatia consumidor na perda de decisão mantendo o peso cheio em categoria. Ambas entram como flags no v12.
14.1 Born-again: o núcleo afia, a cauda cai (v12ba)
O experimento de rede renascida (téc. 18) — o v11_cons rotulando com probs macias o próprio corpus de treino, aluno treinado do zero contra esses alvos — fechou com um resultado negativo instrutivo:
| métrica | v12ba | v10 | v11_cons |
|---|---|---|---|
| núcleo adversarial | 0,6016 | 0,5989 | 0,6009 |
| headline de produção | 0,6224 | 0,6706 | 0,6354 |
| macro-F1 categoria | 0,4141 | 0,4215 | 0,5037 |
O born-again deu o melhor núcleo da história (+0,27 p.p. sobre o v10) e perdeu 4,8 p.p. no subset limpo de produção, com macro-F1 despencando. A autodestilação afia o que o professor já sabia (casos difíceis do próprio viés) e apaga a diversidade que o coletivo de professores originais (juiz de chat + juiz-D) carregava — sobretudo nas caudas de categoria. Ensembles não resgatam: média das três redes (v10 + v11_cons
- v12ba) no núcleo cai para 0,6043 contra 0,6110 da dupla original. Veredito: técnica reprovada nesta família; o conhecimento que faltava ao v11 não estava dentro dele.
15. A campanha dos nove desafiantes — e o que ela delimita
Entre 18 e 19 de outubro executamos, na mesma régua e no mesmo protocolo (split por caso seed 42, temperature scaling no calib, métricas no teste), uma campanha completa contra o campeão vigente — o ensemble v11e (média das probs calibradas de v10 + v11_cons: núcleo 0,6110, geral 0,6282). A campanha abriu com seis desafiantes — e os seis foram reprovados:
| desafiante | ideia | geral | leitura |
|---|---|---|---|
| v12ba (born-again) | aluno do zero com as probs do próprio campeão | 0,6087 | §14.1: núcleo recorde, cauda destruída |
| v12imp (troca de professor) | rótulos macios do Imperium 26B no lugar do juiz-D | 0,6184 | melhor single da linhagem v11, mas macro-F1 0,4002 |
| v12stack (pilha de treino) | focal + R-Drop + FGM + SWA + downweight consumidor | 0,5644 | super-regularização (−4,8 p.p.); melhor calibração da família (ECE 0,025–0,061) |
| v12active (active learning) | +6k casos selecionados por incerteza×discordância | 0,5985 | a fatia rotulada pelo professor injeta viés, não informação |
| Veredicto 9B | escalar o classificador para um backbone de 9B | 0,3838 | reprovado como classificador; recorde de urgência 0,745 |
| ensembles com os desafiantes | média com o campeão | ≤0,6110 (núcleo) | nenhum supera a dupla original |
Três leções se consolidam. Primeira: o gargalo não é a técnica de treino — pilha de regularização, autodestilação e seleção ativa de dados com rótulo de LLM todas falharam em mover a régua, e a que chegou mais perto (troca de professor) ganhou no geral perdendo exatamente na cauda que já doía. Segunda: escala de backbone também não é — o 9B floreia em categoria e decisão no formato joint-schema, revelando que o formato de pergunta multiopção não transfere grátis para modelos maiores. Terceira, e a mais acionável: o conhecimento está nas perguntas certas dos modelos certos — o Veredicto responde urgência (0,745) melhor que qualquer Decisum (teto 0,6919, da campeã v10+swa), e o Imperium rotula melhor o conjunto do que o juiz-D (0,6184 contra 0,6127 no aluno). A agenda que sobra é cirúrgica: destilar urgência do Veredicto no 322M, levar representação (não só decisão) do 26B via hidden states, e engrossar a fronteira de categoria com dados — os três caminhos que a campanha deixou abertos e o stack de técnicas, fechado.
15.1 O oitavo desafiante: SWA sozinho, o campeão escondido
A campanha parecia fechada com o veredito de que "nenhuma técnica de treino move a régua" — até a ablação componente-a-componente da pilha revelar que o problema não era a SWA, mas a companhia dela. O v12stack (focal + R-Drop + FGM + SWA juntos) perdera 4,8 p.p.; removidos os três primeiros, o que sobrou foi o melhor modelo da história:
| sistema | geral | cat | dec | urg | macro-F1 |
|---|---|---|---|---|---|
| v11e (campeã até aqui) | 0,6282 | 0,5604 | 0,6375 | 0,6866 | 0,4223 |
| swa sozinho (single) | 0,6242 | 0,5551 | 0,6295 | 0,6879 | 0,4693 |
| v10+swa (ensemble) | 0,6339 | 0,5618 | 0,6481 | 0,6919 | 0,4301 |
O ensemble v10+swa desbanca a v11e por 0,57 p.p., com categoria e urgência recordes absolutos (0,5618 e 0,6919). A lição cirúrgica: SWA (média de pesos no último quarto do treino) estabiliza o checkpoint final numa região mais plana da paisagem de perda — sozinho, é ganho puro; combinado com focal/R-Drop/FGM (que também empurram pra zonas planas), o efeito composto super-regulariza e destrói a adaptação fina.
A campanha parecia fechar aí: oito desafiantes, sete reprovados, um campeão vindo de dentro da própria pilha que parecia reprovada. Faltava ainda o nono — a aposta "segura" do pré-treino de domínio (§15.3).
15.2 O professor medido na régua — e o aluno que o superou
Para fechar a comparação com referência única, rodamos o juiz-D (a API de decisões de fronteira, professor da linhagem) na régua oficial completa — mesmo split seed 42, mesmos 753 casos de teste:
| sistema | categoria | decisão | urgência | geral |
|---|---|---|---|---|
| juiz-D (API) | 0,7251 | 0,6892 | 0,7238 | 0,7127 |
| v10+swa (campeã) | 0,5618 | 0,6481 | 0,6919 | 0,6339 |
| Veredicto 9B (v4) | 0,2430 | 0,1633 | 0,7450 | 0,3838 |
| Veredicto 9B (v5) | 0,0969 | 0,1700 | 0,7278 | 0,3316 |
Dois números valem o experimento. O teto honesto do professor é 0,7127 — a amostra antiga de 76 casos superestimava (0,754) por ser enviesada a caudas; o gap real para a campeã local é de 7,9 p.p., concentrado em categoria. E o achado da campanha se confirma com força total: na urgência, o aluno de 9B destilado do professor supera o próprio professor (0,745 contra 0,724) — especialização de domínio e média de professores compram mais que os parâmetros extras na pergunta certa. É o resultado que abre a próxima onda: destilar urgência do Veredicto no 322M.
O v5 (re-treino com dados limpos e deduplicados, 2 épocas) confirma que a limitação em categoria/decisão é arquitetural, não de dados: dado limpo deixou categoria ainda pior (0,097 contra 0,243), enquanto a urgência se manteve robusta (0,728 contra 0,745). O clef-flash não transfere classificação multiopção fina em PT-BR no formato joint-schema.
15.3 O nono desafiante: DAPT, o blefe do pré-treino
O experimento de adaptação de domínio (DAPT — 1,08M documentos de e-commerce PT-BR alimentando MLM no encoder por 11 horas) parecia a aposta mais segura de toda a campanha: técnica consolidada, literatura favorável, oceano de dados. O resultado: 0,4188 geral — perda de 20,5 p.p. para o mesmo modelo sem o encoder adaptado.
A explicação está no bug da retomada: o script de DAPT rodou 230k steps
em vez dos 129k planejados (um erro de arredondamento em
math.ceil(0.48) que executou a época inteira em vez de 48%). O encoder
over-trained sofreu catastrophic forgetting — especializou-se tanto em
prever palavras de ticket que perdeu a representação geral que o
fine-tune supervisionado precisava recuperar.
A lição vai além do bug: DAPT em encoder de 322M com um corpus de 1M documentos é uma bomba-relógio de hiperparâmetros — a janela entre "adaptado ao domínio" e "esqueceu como classificar" é estreita e não tem sinal de parada óbvia. Com 476k linhas rotuladas de qualidade auditada, o encoder genérico já está saturado.
15.4 O placar final da campanha
| # | desafiante | geral | veredito |
|---|---|---|---|
| 1 | born-again (v12ba) | 0,6087 | ❌ cauda destruída |
| 2 | troca de professor (v12imp) | 0,6184 | ❌ macro-F1 cai |
| 3 | pilha completa (v12stack) | 0,5644 | ❌ super-regulariza |
| 4 | active learning (v12active) | 0,5985 | ❌ injeta viés |
| 5 | Veredicto 9B | 0,3838 | ❌ como classificador; ✅ urgência |
| 6 | Veredicto 9B v5 (limpo) | 0,3316 | ❌ confirma limitação |
| 7 | DAPT encoder (v12dapt) | 0,4188 | ❌ catastrophic forgetting |
| 8 | DAPT + pilha | cancelado | — (encoder comprometido) |
| 9 | SWA isolado | 0,6242 | ✅ melhor single |
| — | v10+swa ensemble | 0,6339 | 🏆 CAMPEÃ |
Nove desafiantes, oito reprovados, um campeão. E o campeão estava escondido dentro do experimento que parecia o maior fracasso (a pilha completa com −4,8 p.p.). A técnica que moveu a régua não veio de literatura nova, nem de mais dados, nem de escala — veio de ablação cirúrgica: separar o que funcionava do que atrapalhava dentro de uma combinação que fracassou em conjunto.
15.5 O campeão está público
O ensemble v10+swa está público no Hugging Face — syvorai/decisum, sob Apache 2.0: pesos dos dois membros, calibração (temperature scaling), scripts de inferência e serving, e o benchmark de latência reproduzível usado na tabela de hardware do model card (ROCm, XPU e Apple Silicon, todos medidos com a mesma carga).
Raphael Pizzo é Especialista em Machine Learning. Este projeto foi desenvolvido em infraestrutura própria (AMD ROCm), com dados anonimizados e aprovados para uso em pesquisa.