Voltar para todos os posts

Um Modelo de Decisão "System 1" para Atendimento em PT-BR — Parte 2: Resultados, Calibração e o Veredito sobre RL

25 min de leitura
  • 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 2

Nota de anonimização: como na Parte 1, todos os nomes de empresas, produtos, plataformas e clientes foram omitidos ou generalizados. "A plataforma de atendimento", "o dataset público de e-commerce brasileiro" e "o helpdesk" referem-se a sistemas reais em operação.


1. Recap: onde a Parte 1 parou

Resumo em três linhas para quem chegou agora:

  • Construímos um decisor System 1 (encoder mmBERT de 322M parâmetros, option-markers, 17 categorias) que decide categoria/decisão/urgência de chamados em PT-BR, com probabilidades calibradas, rodando em CPU.
  • O primeiro treino (v1) saiu degenerado por um bug de tokenização — [MASK] hardcoded em vez do <mask> real do ModernBERT; 100% dos exemplos sem máscara; o "modelo" respondia sempre a opção 0.
  • A correção + a vacina (checa_trunc.py, 0% de perda de máscara em todos os conjuntos) abriram caminho para o v2, treinado sobre ~444 mil exemplos com padding dinâmico e batch 24.

Esta Parte 2 responde quatro perguntas:

  1. O v2 aprendeu de verdade? (acurácia no gold set intocável)
  2. As probabilidades dele significam alguma coisa? (calibração)
  3. O RLCD melhora a honestidade das probabilidades? (e quanto)
  4. Quantas rodadas de RLCD valem a pena? (análise de ganho marginal)

Spoiler honesto: a resposta da pergunta 4 virou uma das descobertas mais interessantes do projeto — e não é a que eu esperava.

2. O protocolo de avaliação (antes dos números)

Uma decisão metodológica tomada antes de ver qualquer resultado, para não cair na armadilha do v1 (ECE bonito sobre comportamento degenerado):

  • Gold set intocável: 5.244 exemplos dos últimos 60 dias, nunca vistos em nenhuma fase de treino (split temporal, não aleatório).
  • Ordem das métricas: primeiro acurácia, depois calibração. ECE só é reportado para modelos que passam no gate de sanidade (acurácia muito acima do baseline aleatório).
  • Tudo por pergunta: categoria (17 opções), decisão (5 opções) e urgência (4 opções) são avaliadas separadamente — um modelo pode ser bom numa e ruim noutra.
  • Roteamento simulado: a métrica que paga as contas. Com threshold de confiança 0,8, medimos (a) que fração do gold o System 1 decidiria sozinho e (b) qual a acurácia dentro desse subconjunto. Objetivo do projeto: cobertura 80–90% com acurácia visivelmente maior que a acurácia global.
  • Reprodutibilidade: a avaliação é um script (avaliar_decisor.py) que salva JSON + Markdown por checkpoint; a comparação entre fases é outro script (comparar_checkpoints.py) que lê os artefatos e emite a tabela de evolução. Nenhum número deste artigo foi copiado à mão de log.
  • Gate anti-degradação: nenhuma fase nova (RL, novo treino) é aceita se piorar acurácia geral > 1 p.p., acurácia no roteamento automático > 1 p.p., ou ECE > 0,01. Autorização de experimento nunca atropela qualidade.

3. Resultados do v2 (supervised, pós-correção)

3.1 Treinamento

  • 55.500 steps, 3 épocas sobre ~444 mil exemplos (dataset público de e-commerce BR + tickets de suporte EN + chamados próprios), batch 24 com padding dinâmico, max_len 1024, em uma das GPUs AMD de 24 GB a ~3,2 steps/s — pouco menos de 5 horas de treino.
  • Loss final 0,122 · acurácia de treino 0,959 (época 3/3: loss 0,1219, acc 0,959). A curva estabilizou na época 2 (acc 0,958) — sinal de que 3 épocas foram suficientes e uma 4ª não agregaria.

A comparação que importa: o v1 bugado reportava "acurácia de treino" de 27% — a frequência exata da opção 0 no dataset. O v2 saiu de 47,3% no step 1.000 para 95,9% no final. Dessa vez, o gradiente tinha para onde ir.

3.2 Acurácia no gold set

perguntav1 (bugado)baseline aleatóriov2
categoria (17 opções)1,8%5,9%53,7%
decisão (5 opções)0,0%20%74,4%
urgência (4 opções)0,0%25%100,0% ⚠️
geral (5.244 ex.)0,6%—76,0%

Leitura honesta, número a número:

  • Decisão (74,4%) é o resultado mais valioso: é a pergunta que o negócio mais precisa (resolver, escalar, pedir info...) e o modelo acerta 3,7× o baseline em dados que nunca viu.
  • Categoria (53,7%) é 9× o aleatório, mas está longe do confortável. A seção 3.4 mostra que boa parte do "erro" mora na fronteira semântica entre categorias vizinhas, não em ignorância do modelo.
  • Urgência (100,0%) é bom demais para ser verdade — e mereceu o mesmo ceticismo que aplicamos ao v1. A auditoria (seção 10) confirmou que havia algo errado, mas com um desfecho diferente da hipótese inicial: não era vazamento de features — era pior. O rótulo de urgência é 100% degenerado: todos os 1.748 exemplos do gold (e todos os 3.967 do treino) são da classe "3 - crítica". O modelo acerta 100% respondendo sempre a mesma coisa — o v1 das probabilidades se repetindo como v1 das classes. A causa raiz estava na linha de derivação do rótulo: a urgência era calculada a partir da "confiança" do rótulo SFT, que o pipeline fixa em 0,9 para todo chamado resolvido por humano → conf >= 0.9 → urgência 3 para todo mundo, sempre. Uma métrica perfeita sobre uma pergunta vazia. A correção está na seção 10.

3.3 P/R/F1 das categorias

O gold set cobre 14 das 17 categorias (3 não aparecem nos últimos 60 dias — sem suporte, sem julgamento):

categoriaNPRF1
canal_msg6430,6790,6920,686
outro2450,4970,6160,550
incidente4090,4350,6260,514
plano_creditos750,4730,4670,470
integracao810,6250,3700,465
bug_produto1020,2980,1670,214
pagamento300,4290,1000,162
conta_config560,3330,0360,065
duvida_comercial280,0000,0000,000
duvida_produto640,0000,0000,000
prazo_envio90,0000,0000,000
produto_defeito20,0000,0000,000
reembolso10,0000,0000,000
troca_devolucao30,0000,0000,000

Padrões claros:

  1. Volume ajuda, mas não garante: as três categorias mais frequentes (canal_msg, incidente, outro) concentram os únicos F1 razoáveis — e também a maioria das confusões (elas se confundem entre si, ver 3.4).
  2. As 6 categorias de e-commerce quase zeradas (reembolso, troca, prazo_envio...) têm suporte ínfimo no gold (1–9 exemplos) porque o gold vem dos chamados próprios dos últimos 60 dias, não do dataset público. Ou seja: o gold atual não mede o domínio e-commerce — para ele, o teste real continua sendo o split temporal do próprio dataset público. Não concluir "o modelo esqueceu e-commerce" por esta tabela.
  3. duvida_produto e duvida_comercial com F1 0 e suporte real (64 e 28) são o fracasso genuíno da tabela: o modelo nunca as prediz — tudo escorre para incidente, outro e canal_msg. Candidatas claras a oversampling ou a revisão de rótulo na próxima iteração.

3.4 Anatomia das confusões

As top confusões (real → predita) contam uma história muito específica:

  • 128× canal_msg → incidente · 114× incidente → canal_msg
  • 59× outro → incidente · 58× bug_produto → incidente
  • 27× canal_msg → outro · 24× outro → canal_msg · 23× incidente → outro

Leitura preliminar (a confirmar na auditoria manual): o eixo incidente ↔ canal_msg domina — 242 exemplos, ~14% do gold de categoria. É exatamente a fronteira semântica que já apareceu na auditoria de vocabulário da Parte 1: quando a mensageria corporativa é o canal da conversa e também o assunto da falha ("as mensagens não estão saindo"), o mesmo chamado é legitimamente os dois. Se a regra de rotulagem original usava o canal como sinal, o rótulo carrega ambiguidade estrutural — e o modelo "errando" 50/50 entre as duas pode estar é reproduzindo a incerteza do próprio processo de rotulagem. O remédio aqui é uma regra de desempate no vocabulário (ex.: "se a falha reportada é no canal X, a categoria é incidente, não canal_msg"), não mais GPU.

Esta distinção muda o roadmap: se a auditoria confirmar que uma fatia grande das confusões é de rótulo/fronteira, a próxima alavanca é higiene de dados, não mais treino.

4. Calibração: as probabilidades significam alguma coisa?

4.1 Metodologia

Temperature scaling por número de opções (uma temperatura por tamanho de lista de opções), ajustado e medido sobre o gold por ECE (Expected Calibration Error), reportado separadamente por pergunta.

E o lembrete que virou regra da casa depois do v1: ECE sem acurácia não valida nada. O v1 bugado tinha ECE de categoria de 0,041 — "excelente" — porque sempre dizia a mesma coisa com confiança uniforme. Calibração só é reportada aqui porque o v2 passou pelo gate de acurácia.

4.2 Resultados

pergunta (n° opções)ECE antesECE depoistemperatura
urgência (4)0,0010,0000,25
decisão (5)0,1110,0191,65
categoria (17)0,1200,0411,35

Três leituras:

  1. O modelo saía do supervised superconfiante nas duas perguntas que importam (ECE ~0,11–0,12, acima do alvo de 0,10): as temperaturas > 1 (1,65 e 1,35) "achatam" a distribuição e derrubam o ECE para 0,019 e 0,041 — ambos confortavelmente abaixo do alvo.
  2. A temperatura de 0,25 da urgência é outro sintoma do rótulo degenerado discutido em 3.2: classe única no treino → o modelo aprendeu a ter certeza absoluta de uma resposta só. Calibração perfeita sobre pergunta vazia não é mérito — é advertência.
  3. Diferente do v1, aqui o ECE baixo acompanha acurácia real — é o primeiro modelo do projeto cujas probabilidades podem ser usadas para rotear tráfego de verdade. E é exatamente aí que o RLCD entra: se o temperature scaling corrigiu a média, o RL deveria corrigir a forma da distribuição, exemplo a exemplo. "Deveria" — a seção 5 conta o que aconteceu de fato.

5. RLCD: três rodadas, três resultados, um veredito

5.1 Por que RL depois do supervised

Cross-entropy ensina a acertar a resposta; não ensina a distribuir a probabilidade de forma honesta. Um modelo supervised tende a concentrar massa na opção argmax além do que sua taxa real de acerto justificaria — superconfiança clássica, confirmada na seção 4.2 (ECE ~0,12 antes do scaling). O RLCD (Reinforcement Learning for Calibrated Decisions) ataca exatamente isso:

  • REINFORCE com baseline estilo GRPO: para cada exemplo, amostramos G decisões da política; a vantagem é a recompensa menos a média do grupo — sem crítico aprendido, sem PPO, variância controlada pelo grupo.
  • Recompensa = strictly proper scoring rules (log score + spherical score sobre a distribuição reportada). A propriedade matemática que importa: uma scoring rule strictly proper só é maximizada em esperança quando a distribuição reportada é a crença verdadeira do modelo. Ou seja: a recompensa ótima não é "acerte sempre com 100%" — é "reporte exatamente a incerteza que você tem". O RL literalmente paga o modelo para ser honesto.

5.2 O desenho do experimento: uma curva dose-resposta em 3 pontos

Em vez de uma única rodada "no feeling", rodamos três configurações que varrem o espaço de doses — e isso fez toda a diferença na conclusão:

RLCD-1 (quente demais)RLCD-2 (fria demais)RLCD-3 (intermediária)
parâmetros treinadosencoder + cabeça (322M)só cabeçasó cabeça
LR5e-61e-65e-6
épocas211
grupo G488
recompensa medida empolítica com ruídopolítica limpapolítica limpa
vantagemsem clipclip ±2clip ±2
weight decay0,01 (padrão)00
dropout nos rolloutsligadodesligadodesligado
dados11.901 chamados própriosidemidem

O RLCD-1 foi o primeiro a rodar — e falhou de forma instrutiva. A auditoria pós-falha (antes de qualquer re-tentativa) encontrou sete problemas empilhados, não um:

  1. Recompensa medida na política com ruído (σ=0,5): o log score pune sem limite inferior; com ruído grande, a vantagem passa a medir o azar do sorteio do ruído, não a qualidade da política.
  2. Encoder inteiro treinando: RL de calibração deveria ajustar a cabeça; mover 322M parâmetros com gradiente de alta variância é pedir deriva catastrófica.
  3. Grupo G=4 pequeno demais para o baseline amortecer a variância.
  4. Vantagem sem clip: um único caso com log p ≈ -18 dita o gradiente do lote.
  5. Dropout ligado nos rollouts (modelo em modo treino): mais uma fonte de ruído invisível para a recompensa e o baseline.
  6. Weight decay padrão do AdamW (0,01): encolhe os pesos da cabeça a cada step independentemente do sinal — confiança drenada "de graça".
  7. Recompensa/baseline dentro do grafo de autograd: desperdício de VRAM e risco de vazamento de gradiente por caminho lateral.

A correção virou a config do RLCD-2/3: encoder congelado, recompensa na política limpa (ruído só para amostrar a ação), G=8, clip ±2, decay 0, dropout off, mais uma guarda anti-divergência: se a recompensa móvel cai > 0,75 abaixo da melhor vista, o treino aborta sem salvar checkpoint — modelo degradado nunca mais chega ao disco.

5.3 Trajetórias de recompensa: o sinal que conta a história

rodadainíciofimleitura
RLCD-1-0,38-2,21recompensa caindo por 3.900 steps seguidos — o treino estava ativamente piorando a política
RLCD-2-0,17-0,17oscilação ±0,1 em torno da média, sem tendência — política praticamente parada
RLCD-3-0,19-0,19idem — nenhuma direção

Detalhe forense curioso: as trajetórias das rodadas 2 e 3 são quase idênticas ponto a ponto (mesma seed → mesma ordem de batches e mesma sequência de ruído; com os pesos quase parados, a recompensa é dominada pela sequência aleatória, não pela política). É a assinatura de um treino que não está se movendo.

5.4 O que cada rodada fez no gold set

métricasupervised v2RLCD-1RLCD-2RLCD-3
acurácia geral0,7600,658 ❌0,7600,760
categoria0,5370,234 ❌0,5370,536
decisão0,7440,7390,7440,745
cobertura S1 (conf≥0,8)52,5%33,3% ❌52,5%49,7%
acurácia no auto0,9451,000*0,9450,955
ECE categoria (pós-scaling)0,0410,0730,0400,041
ECE decisão (pós-scaling)0,0190,0390,0190,019
temperatura necessária (17 op)1,354,951,351,40

* acurácia de 100% sobre apenas 33% do volume — o modelo só "confia" nos casos triviais; sintoma da calibração destruída (ECE pré-scaling de 0,764).

E o dado mais frio de todos: a diferença máxima de peso da cabeça entre supervised e RLCD-2 foi de 1,2e-4 — com encoder congelado e LR 1e-6, o RL literalmente não saiu do lugar. O RLCD-3 (LR 5× maior) moveu a cabeça o suficiente para trocar meia dúzia de predições: +0,1 p.p. em decisão, -0,1 p.p. em categoria, -2,8 p.p. de cobertura, +1,0 p.p. de acurácia no auto. Tudo dentro do ruído.

6. Quantas rodadas de RLCD valem a pena?

6.1 Critério de parada (definido antes de rodar)

Uma rodada adicional só se justificaria se a anterior trouxesse ganho marginal mensurável: ΔECE ≥ 0,01 em alguma pergunta, ou Δacurácia no auto ≥ 0,5 p.p., sem perda de acurácia geral.

6.2 O veredito: zero rodadas — e isso é um resultado, não um fracasso

Aplicando o critério às três rodadas:

  • RLCD-1: degradou (reprovada no gate anti-degradação, -10,3 p.p. de acurácia geral).
  • RLCD-2: ΔECE = 0,000–0,001; Δacc = 0,000. Nada.
  • RLCD-3: ΔECE = 0,000; Δacc ≤ 0,1 p.p. Nada além do ruído.

A dose-resposta é plana nos dois extremos úteis e catastrófica no extremo quente: não existe dose deste RLCD que melhore o que o temperature scaling já entrega. A recomendação de produção é o checkpoint supervised puro + temperaturas (1,35/1,65) — o componente mais barato do pipeline.

Isso não contradiz a literatura de RL para calibração — contextualiza: o RLCD foi proposto para corrigir superconfiança quando não há um método mais simples. Aqui havia. O temperature scaling por número de opções capturou praticamente toda a superconfiança sistemática (ECE 0,12 → 0,02– 0,04); o que sobrou de erro de calibração é condicional (depende do exemplo), e sobre ele o RL com recompensa de scoring rule média tem gradiente fraco demais para agir — como mostram as trajetórias sem tendência. A lição metodológica: rodar o baseline escalar primeiro e o RL depois teria poupado uma rodada de GPU; a ordem correta de complexidade crescente deveria ter sido norma desde o início.

6.3 O teto que nenhuma rodada furaria

Mesmo que o RL tivesse funcionado, havia um teto baixo esperando: o gold de categoria carrega ambiguidade estrutural (a fronteira incidente↔canal_msg da seção 3.4 afeta ~14% dos exemplos) e, muito provavelmente, rótulos derivados por regra com ruído próprio. Contra um chão de irredutibilidade dessa ordem, a distância entre "ECE 0,041" e "calibração perfeita" é curta demais para pagar horas de GPU. O ganho marginal real de mais rodadas seria decimal — o critério de parada existia exatamente para dizer isso com dados, e disse.

7. A simulação de roteamento: o número que paga as contas

Com threshold de confiança 0,8 e probabilidades pós-temperature-scaling:

cenáriocobertura S1acurácia no autoacurácia global
supervised v2 (recomendado)52,5%94,5%76,0%
RLCD-133,3%100%*65,8%
RLCD-252,5%94,5%76,0%
RLCD-349,7%95,5%76,0%

Leitura operacional: hoje, metade do volume cairia no automático acertando 19 de cada 20 — já é um produto útil. O objetivo de 80–90% de cobertura, porém, não será alcançada por calibração: o que separa 52,5% de 80% é acurácia de categoria (53,7%), e isso é problema de dados e vocabulário (seção 3.4), não de distribuição de probabilidade. O RLCD-3 mostra o trade-off no osso: -2,8 p.p. de cobertura comprando +1,0 p.p. de acurácia no auto — a curva cobertura×acurácia existe, e o ponto de operação é uma decisão de negócio (custo do erro vs. custo da escalada humana).

8. Evolução de qualidade por fase (visão única)

Tabela gerada pelo comparar_checkpoints.py diretamente dos artefatos de avaliação — uma linha por checkpoint, todas as fases lado a lado:

checkpointacc geralacc categ.acc decisãoroteamento S1acc no autoECE 17-opECE 5-op
decisor-v1 (supervised)0,7600,5370,74452,5%0,9450,0410,019
decisor-rlcd (RLCD-1)0,657 ❌0,234 ❌0,73933,3%1,000*0,0730,039
decisor-rlcd20,7600,5370,74452,5%0,9450,0400,019
decisor-rlcd30,7600,5360,74549,7%0,9550,0410,019

Cada fase do pipeline deixou um rastro medível, comparável e reproduzível — nenhuma "melhora" foi declarada sem delta. Incluindo a que não melhorou.

9. A auditoria de rótulos: ouro, prata e o que estava quebrado

Depois do veredito do RLCD, a pergunta que ficou na mesa era: se a calibração está resolvida, por que a acurácia de categoria estaciona em 53,7%? A resposta exigiu descer um nível abaixo do modelo — na linhagem dos rótulos.

9.1 A descoberta desconfortável: o "gold" era prata

Os rótulos dos chamados próprios (treino e gold) não vêm de humanos: são derivados por regras de palavra-chave sobre a conversa inteira — primeira regra que casa vence, numa ordem fixa. Isso vale para categoria (regex sobre o texto), decisão (regex sobre o comportamento do atendente) e urgência (que deveria medir severidade). Ou seja: o modelo foi treinado e avaliado contra a saída de uma família de regexes. O teto real do modelo não é 100% — é a qualidade dessas regras. Três evidências de que elas eram o gargalo:

  1. A confusão nº 1 era erro de rótulo, não do modelo. A fronteira incidente ↔ canal_msg concentrava 242 casos (~14% do gold de categoria). Lendo os casos contestados (142 exemplos com keywords das duas regras), o padrão é claro: o cliente relata "mensagem não enviada no canal_msg" ou "nosso contato caiu" — o assunto é o canal de mensageria, mas a regra de incidente ("caiu", "mensagem não enviada") vinha antes na ordem e engolia o caso. O modelo que previa canal_msg estava, frequentemente, mais certo que o rótulo.
  2. Urgência 100% degenerada (seção 3.2): a "urgência" era derivada da confiança do rótulo SFT, que o pipeline fixa em 0,9 para todo chamado resolvido por humano → classe única, treino e gold. Pergunta vazia.
  3. Categorias órfãs com suporte real: duvida_produto (135 exemplos de treino, 64 no gold) e duvida_comercial (41/28) têm F1 = 0 — o modelo nunca as prevê. Padrão típico de rótulo indistinguível da classe vizinha nos dados (o regex que gera duvida_produto quase nunca dispara antes de incidente/outro), não de falta de exemplos.

E um quarto achado, sobre a pergunta de decisão: acurácia de 74,4% contra 73,9% de baseline da classe majoritária (executar_acao é o rótulo default da regra quando nada dispara). O modelo agregava +0,5 p.p. sobre "sempre executar" — a pergunta mais importante do sistema era, também ela, quase vazia de sinal discriminativo.

9.2 A correção (v3 dos dados)

Duas mudanças cirúrgicas, ambas documentadas em código:

  1. Regra de desempate de categoria: canal_msg (e as demais categorias específicas de canal/produto) passam a vir antes de incidente, que fica residual para indisponibilidade sistêmica sem canal específico nomeado. Efeito na distribuição: incidente 38,8% → 23%, canal_msg 24,6% → 40% — a zona contestada migrou para onde a leitura humana apontava.
  2. Urgência heurística real: substituída a regra da confiança por padrões sobre o texto do chamado (impacto: "fora do ar", "equipe parada", "prejuízo" → 3; bloqueio de fluxo: "não consigo", "erro" → 2; dúvida de uso → 0; resto → 1). Ainda é prata — mas prata sobre urgência, não sobre confiança de rotulador. Distribuição resultante: 4 classes vivas (treino: 16% / 49% / 22% / 4%; gold: 15% / 46% / 21% / 3%).

O gold foi regerado com as mesmas regras novas — e, para a comparação ser justa, o v2 será reavaliado no gold novo lado a lado com o v3 (seção 11). Trocar o rótulo e a régua ao mesmo tempo sem reavaliar o modelo antigo na régua nova seria o erro clássico de medida.

9.3 O resultado do v3: a régua honesta reescreve o placar

O v3 foi treinado com exatamente os mesmos hiperparâmetros do v2 — o que mudou foram os rótulos (seção 9.2). E ambos foram avaliados no mesmo gold novo (5.193 exemplos, categorias com desempate corrigido, urgência com 4 classes reais):

métricav2 no gold novov3 no gold novoleitura
acurácia geral0,4350,646+21,1 p.p.
categoria0,5290,593+6,4 p.p.
decisão0,7410,745estável (regra não mudou)
urgência0,0340,600o v2 não sabia urgência — respondia sempre "crítica"; com 3% de críticos no gold novo, quebrou
cobertura S1 (conf≥0,8)52,5%30,2%cobertura caiu…
acurácia no auto0,3300,913…mas a do v2 era conforto falso: confiante e errando 2/3
ECE (cat/dec/urg, pós-scaling)—0,050 / 0,027 / 0,042v3 calibrado nas 3 perguntas reais

Três destaques:

  1. O número mais importante desta Parte não é do v3 — é o 0,330 do v2. No gold velho (prata), o v2 roteava 52,5% do volume com "94,5% de acurácia no automático". Na régua honesta, esse mesmo subconjunto confiante acerta um terço. A urgência degenerada inflava a acurácia e as categorias trocadas inflavam a confiança. A régua errada fazia um modelo mediano parecer produto pronto. Esta é a lição mais cara do projeto inteiro: quem avalia errado, entrega errado.
  2. A fronteira incidente↔canal_msg encolheu de 242 para 131 confusões (-46%), e o F1 de canal_msg subiu de 0,686 para 0,769 — a regra de desempate fez pelo dado o que nenhuma GPU faria pelo modelo.
  3. Urgência existe agora: 60% de acurácia em 4 classes (baseline 25%) com ECE real de 0,042. Não é excelente — é a primeira medida real.

E o trade-off honesto: a cobertura caiu de 52,5% para 30,2% porque o modelo agora sabe o que não sabe (a confiança parou de ser inflada por rótulo fácil). 30% de cobertura com 91,3% de acurácia é um produto menor, mas é um produto de verdade — e a fronteira seguinte (recuperar cobertura sem perder a honestidade) passa por mais dados de domínio e pelo System 2, não por métrica inflada.

Decisão de produção: decisor-v3, sem discussão — supera o v2 em todas as métricas na mesma régua, e a única métrica em que "perde" (cobertura) é exatamente aquela em que o v2 estava trapaceando sem saber.

Duas ressalvas que sobrevivem ao v3:

  • A prata continua prata: regex melhorado ainda é regex. A medida definitiva exige um gold humano (ou de juiz forte, o System 2) sobre uma amostra — o número 0,646 também é uma cota inferior da qualidade percebida, porque uma fatia das "confusões" restantes ainda pode ser erro de régua.
  • pedir_mais_info (10 exemplos de treino) e as categorias de e-commerce nos chamados próprios seguem sub-representadas — o próximo salto de qualidade de decisão virá daí e do gold humano, não de mais treino sobre estes rótulos.

10. Lições da Parte 2

  1. Acurácia primeiro, calibração depois, sempre nesta ordem. (Repetida de propósito: é a lição mais cara do projeto.)
  2. Desconfie do 100%. A urgência perfeita era o sinal de fumaça de um rótulo degenerado (classe única por uma confiança hardcoded) — o mesmo ceticismo que pegou o bug do <mask> pega prata mal-extraída. Métrica perfeita em tarefa imperfeita é diagnóstico, não troféu.
  3. Toda confusão recorrente tem dono: rótulo, vocabulário ou modelo. A fronteira incidente↔canal_msg sugere que a próxima alavanca de qualidade é uma regra de desempate no vocabulário, não GPU.
  4. RL não é varinha: é bisturi. Sete problemas de configuração empilhados transformaram a ferramenta mais sofisticada do projeto na única que destruiu valor. Congelar o encoder, medir recompensa na política limpa e clipar vantagens transformaram-na em inócua — mas inócua não é útil.
  5. O baseline escalar primeiro. Temperature scaling (uma linha de código, um escalar por pergunta) capturou todo o ganho de calibração disponível. Complexidade crescente só se justifica quando a simples esgota — e deve-se provar que ela esgotou antes de escalar.
  6. Ganho marginal decrescente é a regra. O critério de parada, definido antes da primeira rodada, transformou "será que mais uma rodada ajuda?" em uma pergunta com resposta objetiva: não.
  7. A métrica de negócio é cobertura × acurácia no automático. O resto é instrumentação.

Na sequência

O roadmap de qualidade, ordenado por evidência (o item 1 já saiu do papel nesta edição — seção 9):

  1. Treino v3 sobre os rótulos corrigidos feito — v3 recomendado para produção (seção 9.3).
  2. Gold humano de verdade: uma amostra de algumas centenas de chamados rotulados à mão para medir quanto da "prata" resiste — e, com o System 2, um juiz forte para escalar essa rotulagem.
  3. Recuperar cobertura sem perder honestidade: 30% → 80% é o desafio central; passa por mais dados de domínio (decisão e categorias órfãs) e pelo System 2 absorvendo a cauda difícil com justificativa.
  4. Só então: quem sabe uma revisita ao RL — com um baseline simples já esgotado de propósito para medir o que o RL realmente acrescenta.

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.