Como comparar duas IAs de decisão pela divergência entre elas (e não só pela taxa de acerto)

Para comparar duas IAs de decisão, não basta olhar a taxa de acerto: dois modelos com a mesma acurácia podem errar em casos opostos. O método é rodar os dois no mesmo conjunto rotulado, montar a matriz de confusão de cada um (separando falso positivo de falso negativo, com precisão e recall), medir a concordância entre eles com o kappa de Cohen (cohen_kappa_score no scikit-learn) e aplicar o teste de McNemar só nos pares discordantes. Aí você escolhe pelo custo do erro: menos FN quando perder um caso dói mais, menos FP quando o alarme falso é o problema
Duas IAs de decisão com a MESMA taxa de acerto podem errar em casos completamente diferentes
E isso muda qual delas você deve colocar em produção 😀
Fala aí, beleza? O Jev, da TypeSafe AI, foi anunciado em 15 de setembro de 2026 como o primeiro modelo público da categoria que a empresa chama de System One Models
E ele não é um chatbot: você manda um estado (a informação a avaliar) e perguntas (o que decidir), e ele devolve uma decisão estruturada, ou seja, uma opção, um score ou uma probabilidade
Nada de texto redigido
Aí que fica interessante: como a saída é estruturada, dá pra colocar o Jev lado a lado com um concorrente qualquer (por exemplo, um LLM generalista com saída estruturada) e comparar item a item, como se fossem dois avaliadores humanos classificando os mesmos casos
O método que te mostro aqui tem três peças: a matriz de confusão de cada modelo, a concordância entre os dois e a análise só dos casos em que eles discordam
Bora ver na prática?
O que você precisa antes de comparar o Jev com outro modelo
Antes de qualquer código, se liga no que precisa estar na mesa:
- Um conjunto de itens com o rótulo real conhecido: é a verdade do seu problema, o gabarito. Sem isso não existe acerto nem erro, só opinião de IA
- O mesmo conjunto passado pelos dois modelos: cada item recebe a decisão do Jev e a decisão do concorrente
- Python com scikit-learn: vamos usar
confusion_matrixecohen_kappa_score, as duas emsklearn.metrics - Acesso ao Jev: ele está disponível no Vercel AI Gateway, na Cloudflare, no OpenRouter (ID
typesafe/jev-1.13) e pela API direta
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 120 aulas
- 4 projetos
- 9h 45min
Tome cuidado com a API direta: o acesso ainda parece desigual entre contas, então se a sua não liberou, as outras vias resolvem 🙂
E o custo?
O Jev 1.13 sai por US$ 0,042 por milhão de tokens de entrada e US$ 0,00 na saída, e o preço no OpenRouter é igual ao direto da TypeSafe
Porém a própria empresa avisa que esse preço inicial pode estar subsidiado, então confira a tarifa atual antes de ir pra produção
O foco aqui é o método de comparação, então instalação e código de chamada ficam de fora: no Passo 2 você vê só os tipos de pergunta da API e o que cada um devolve, que é o que interessa pra montar a tabela
Passo a passo: comparando duas IAs de decisão pelo tipo de erro
A ideia central é simples: acurácia te diz QUANTO cada modelo erra, mas não diz ONDE
E o onde é o que importa na hora de decidir
- Monte o dataset pareado
Cada linha precisa ter o mesmo item, o rótulo real, a decisão do modelo A e a decisão do modelo B
Os dados abaixo são ILUSTRATIVOS, só pra estrutura do código ficar clara, não são resultado de teste nenhum:
# Dados ilustrativos: 1 = positivo (sim), 0 = negativo (não)
y_real = [1, 0, 1, 1, 0, 0, 1, 0, 1, 0]
y_jev = [1, 0, 0, 1, 0, 1, 1, 0, 1, 0]
y_rival = [1, 1, 1, 1, 0, 0, 0, 0, 1, 0]
Erro comum deste passo: avaliar cada modelo num conjunto diferente
Se o Jev viu os casos fáceis e o concorrente viu os difíceis, a comparação pareada vai pro lixo, beleza?
- Colete as decisões do Jev com o tipo de pergunta certo
A API do Jev tem três tipos de pergunta:
- Choice: devolve a opção escolhida (
.choice), uma probabilidade pra cada opção (.probabilities) e a confiança (.confidence) - Score: devolve um score que pode cair entre níveis (
.score), mais probabilidades e confiança - Noul: devolve um único número de 0 a 1 (
.noul), a probabilidade de a resposta ser sim
Pra escolher entre opções, Choice
Pra sim ou não, Noul
E guarde a confiança junto! Ela vai de 0 a 1 e é calculada pelo formato da distribuição de probabilidades (detalhes aqui): toda a massa numa opção dá 1.0, e quanto mais espalhada a distribuição, menor a confiança
A TypeSafe diz que essa confiança é calibrada, e isso é uma afirmação do próprio fabricante, então vale conferir com os seus dados
Se usar Noul, você precisa transformar o número em sim ou não, e o corte é escolha SUA, depende do problema:
def noul_para_rotulo(valores_noul, corte):
# corte: você define, de acordo com o custo de cada tipo de erro
return [1 if v >= corte else 0 for v in valores_noul]
Erro comum deste passo: descartar a confiança
Aí você perde justamente a chance de ver onde o modelo erra com convicção, que é o erro mais perigoso
- Monte a matriz de confusão de cada modelo
Que matriz?
É uma tabela 2×2 que cruza a classe prevista com a classe real, e dela saem dois tipos de erro bem diferentes:
- Falso positivo (FP): caso negativo previsto como positivo, o erro tipo I, o alarme falso
- Falso negativo (FN): caso positivo previsto como negativo, o erro tipo II, o caso perdido
Com isso você calcula precisão (a fração das afirmações "é positivo" que estão certas, penaliza FP) e recall (a fração dos positivos reais que foram encontrados, penaliza FN):
from sklearn.metrics import confusion_matrix
def perfil_de_erro(nome, y_real, y_pred):
print(nome)
print(confusion_matrix(y_real, y_pred))
vp = sum(1 for r, p in zip(y_real, y_pred) if r == 1 and p == 1)
fp = sum(1 for r, p in zip(y_real, y_pred) if r == 0 and p == 1)
fn = sum(1 for r, p in zip(y_real, y_pred) if r == 1 and p == 0)
precisao = vp / (vp + fp) if (vp + fp) else 0
recall = vp / (vp + fn) if (vp + fn) else 0
print(f"FP={fp} FN={fn} precisão={precisao:.2f} recall={recall:.2f}")
perfil_de_erro("Jev", y_real, y_jev)
perfil_de_erro("Rival", y_real, y_rival)
Repara que eu conto FP e FN na mão, assim não tem dúvida de qual número é qual 🙂
Erro comum deste passo: parar na acurácia
Acurácia junta FP e FN no mesmo balde, e é exatamente isso que a gente quer separar
- Meça a concordância entre os dois com o kappa de Cohen
O kappa mede o quanto dois avaliadores concordam ao classificar os mesmos itens, descontando a concordância que aconteceria por acaso
A fórmula é κ = (Po – Pe) / (1 – Pe), em que Po é a concordância observada e Pe a esperada por acaso, calculada a partir das proporções de cada avaliador
No scikit-learn é uma linha só (documentação do cohen_kappa_score):
from sklearn.metrics import cohen_kappa_score
kappa = cohen_kappa_score(y_jev, y_rival)
print(f"kappa entre Jev e rival: {kappa:.2f}")
O resultado vai de -1 a 1: 1 é concordância total e 0 é nenhuma concordância além do acaso
Pra ler o número, a escala de Landis e Koch (1977) ajuda:
| Kappa | Leitura |
|---|---|
| menor que 0 | ruim |
| 0,00 a 0,20 | leve |
| 0,21 a 0,40 | razoável |
| 0,41 a 0,60 | moderada |
| 0,61 a 0,80 | substancial |
| 0,81 a 1,00 | quase perfeita |
E se as saídas tiverem ordem, como os níveis de um Score?
Aí entra o parâmetro weights, que aceita None, 'linear' ou 'quadratic', e passa a tratar discordância entre níveis vizinhos como menos grave que discordância entre extremos
Erro comum deste passo: usar a concordância percentual bruta
Quando uma classe domina, dois avaliadores que só chutam o rótulo mais comum vão coincidir MUITO, e a porcentagem fica inflada. O kappa tira essa linha de base
- Monte a tabela de discordância e rode o McNemar
O teste de McNemar compara dois classificadores avaliados nos mesmos itens usando uma tabela 2×2 de resultados pareados
| Rival acertou | Rival errou | |
|---|---|---|
| Jev acertou | os dois acertaram | c |
| Jev errou | b | os dois erraram |
Aqui o modelo 1 é o Jev: b são os itens que ele errou e o rival acertou, c são os que ele acertou e o rival errou
Só b e c entram na conta: χ² = (b – c)² / (b + c), com hipótese nula de que nenhum dos dois é melhor que o outro
A conta é curta, então dá pra fazer em Python puro mesmo:
b = sum(1 for r, a, z in zip(y_real, y_jev, y_rival) if a != r and z == r)
c = sum(1 for r, a, z in zip(y_real, y_jev, y_rival) if a == r and z != r)
if b + c == 0:
print("Nenhum par discordante: não dá pra comparar")
else:
chi2 = (b - c) ** 2 / (b + c)
print(f"b={b} c={c} qui-quadrado={chi2:.2f}")
E por que ignorar os itens em que os dois concordam?
Porque eles não dizem nada sobre qual é melhor, só os discordantes informam a diferença entre os modelos
Erro comum deste passo: tirar conclusão com pouquíssimos pares discordantes
O resultado depende inteiramente desse punhado de casos, então com dois ou três discordantes qualquer veredito é chute com cara de estatística haha
Quando as duas IAs acertam igual, mas erram em pontos opostos
Esse é o cenário que engana mais gente, então vale parar nele
Duas IAs com a mesma acurácia podem ter perfis de erro opostos: uma concentra falsos positivos (dá alarme demais) e a outra concentra falsos negativos (deixa caso passar)
No placar geral, empate. Na prática, são ferramentas diferentes
Como reconhecer esse cenário nos números?
- Precisão e recall invertidos: um modelo tem precisão alta e recall baixo, o outro o contrário
- Kappa mais baixo do que a acurácia sugeriria: se os dois acertam muito mas discordam bastante entre si, é sinal de que acertam e erram em itens diferentes
- b e c parecidos no McNemar: o χ² fica perto de zero, então não tem vencedor estatístico, mas os perfis de erro continuam distintos
Se liga nisso: "sem vencedor estatístico" não quer dizer "tanto faz"
Quer dizer que a escolha sai do campo da estatística e vai pro custo do erro no seu negócio
Quando o caso perdido custa mais caro
Pensa numa triagem em que deixar passar um caso positivo dói muito mais do que revisar um alarme à toa
Aqui você prefere o modelo com menos FN, ou seja, maior recall
Quando o alarme falso custa mais caro
Agora o contrário: cada positivo dispara uma ação cara ou chata pro usuário, tipo bloquear algo ou acionar alguém
Aí o modelo com menos FP, maior precisão, é o que faz sentido
Quando usar a discordância como sinal de revisão
E se os dois erram em pontos opostos, por que não usar isso a seu favor?
Quando o Jev e o concorrente discordam num item, esse item vira candidato a revisão humana
Os casos em que os dois concordam seguem automáticos, e o humano só olha onde as IAs brigaram 😀
Essa lógica de decidir qual modelo responde o quê conversa direto com o controle do roteador de modelos, porque no fundo é a mesma pergunta: quem decide, e quando
Tudo isso aqui é exemplo didático, beleza? Não estou atribuindo perfil de erro real nem ao Jev nem a nenhum concorrente, quem vai dizer isso é a tabela com os SEUS dados
Conclusão: acurácia é o começo, não o veredito
Recapitulando o método:
- Matriz de confusão: separa FP de FN e te dá precisão e recall de cada modelo
- Kappa de Cohen: mede o quanto os dois concordam descontando o acaso
- McNemar: testa se um é melhor que o outro usando só os pares discordantes
- Leitura dos discordantes: mostra ONDE cada um erra e se a discordância serve de gatilho pra revisão
O próximo passo é bem concreto: separa uma amostra rotulada do seu próprio problema, roda o Jev e o modelo que você usa hoje nela e monta a tabela de discordância antes de pensar em qualquer migração
Se a comparação apontar pro Jev, vale padronizar o uso no time desde o começo, pra cada dev não sair configurando de um jeito
E antes de produção, confere a tarifa vigente do Jev, já que a própria TypeSafe avisa que o preço inicial pode estar subsidiado
Até o próximo post! 🙂
Perguntas frequentes
Qual a diferença entre acurácia e kappa de Cohen ao comparar duas IAs de decisão
Acurácia só diz quanto cada modelo acerta sozinho, sem olhar pro outro. O kappa de Cohen mede a concordância entre os dois nos mesmos itens, descontando o que seria concordância por acaso. Dois modelos com acurácia parecida podem ter kappa baixo, e isso é sinal de que eles erram em casos diferentes.
O teste de McNemar substitui o kappa de Cohen na comparação entre Jev e outro modelo
Não, eles respondem perguntas diferentes. O kappa mede o quanto os dois concordam no geral. O McNemar usa χ² = (b − c)² / (b + c), olhando só pros pares discordantes, pra testar se um modelo erra mais que o outro justamente nesses casos.
Como interpretar o valor do kappa de Cohen depois de comparar duas IAs de decisão
A escala de Landis e Koch (1977) ajuda: abaixo de 0 é ruim, de 0,00 a 0,20 é leve, de 0,21 a 0,40 é razoável, de 0,41 a 0,60 é moderada, de 0,61 a 0,80 é substancial e de 0,81 a 1,00 é quase perfeita. O resultado do cohen_kappa_score do scikit-learn vai de −1 a 1, então dá pra encaixar direto nessa régua.
Dá pra comparar o Jev com um LLM generalista usando esse mesmo método
Dá, desde que o concorrente também devolva uma saída estruturada no mesmo formato de classificação. O ponto chave é que o Jev entrega opção, score ou probabilidade, não texto redigido, então a comparação item a item funciona como se fossem dois avaliadores classificando os mesmos casos.
Por que a confiança do Jev importa na hora de comparar os erros entre modelos
Porque ela mostra se o modelo errou com convicção ou na dúvida, e isso muda o risco de colocar aquele modelo em produção. A confiança do Jev vai de 0 a 1 e sai da concentração das probabilidades: quanto mais a massa fica numa opção só, mais perto de 1.0. A TypeSafe chama essa confiança de calibrada, e isso é uma afirmação do próprio fabricante.
Quanto custa gerar os dados do Jev pra fazer essa comparação
O Jev 1.13 cobra US$ 0,042 por milhão de tokens de entrada e US$ 0,00 na saída, mesmo preço no OpenRouter e direto na TypeSafe. A própria empresa avisa que esse valor inicial pode estar subsidiado, então vale conferir a tarifa atual antes de rodar qualquer comparação pensando em produção.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares

Checklist de segurança n8n VPS pública: guia essencial para proteger sua instalação
Checklist de segurança n8n VPS pública: guia essencial para proteger sua instalação A popularidade da automação de processos com o n8n está em alta, principalmente […]
O que significa “ChatGPT network error” e como resolver
O “ChatGPT Network Error” é uma ocorrência frequente na rotina de muitos usuários do ChatGPT. Porém, poucos compreendem seu significado, quando esse erro surge, etc. […]

Como usar o Antigravity do Google: guia completo do zero ao primeiro app
Aprenda neste guia prático como usar o Antigravity do Google: descubra a instalação, configuração, criação de projetos com o Agent Manager e o primeiro deploy, […]
