Blog

Avaliação contínua de bots: do eval manual ao automático

Quase todo bot de atendimento com IA nasce sem eval. Alguém conversa por cinco minutos, aprova no olho e sobe para produção. Isso funciona até a primeira mudança de prompt, troca de modelo ou ajuste de RAG quebrar em silêncio uma resposta que antes estava certa. Avaliação contínua é o que transforma essa checagem manual e subjetiva em um processo repetível: um dataset de casos com resposta esperada, uma métrica objetiva, um juiz automático e um gate no CI que reprova o deploy quando a qualidade cai. Este artigo mostra como sair do eval manual e chegar no automático sem exagerar na infra: como montar o dataset, quais métricas medir, como usar um LLM como juiz sem se enganar, como fechar o gate de regressão e como manter tudo isso vivo sem virar teatro de métricas.

2026-07-03 / IA Aplicada / 13 min

01

Por que o eval manual não escala

O eval manual tem três problemas que só aparecem quando o bot já está em produção. Primeiro, ele não é reproduzível: duas pessoas avaliam a mesma resposta de formas diferentes, e a mesma pessoa avalia diferente em dias diferentes. Segundo, ele não cobre regressão: você testa as perguntas que lembrou na hora, nunca as cem que já funcionavam e podem ter quebrado. Terceiro, ele não tem gate: a mudança sobe porque pareceu boa, não porque passou num critério.

O objetivo do eval contínuo não é eliminar o julgamento humano, é ancorá-lo. Você escreve o critério uma vez, na forma de casos e rubrica, e a partir daí a máquina aplica esse mesmo critério em toda mudança. O humano volta a entrar só quando o resultado é ambíguo ou quando o dataset precisa crescer. É a diferença entre "achei que ficou bom" e "passou em 94 dos 100 casos, contra 96 na versão anterior, então a mudança regrediu".

02

A escada da maturidade de eval

Não se pula do manual direto para o automático completo. Existe uma escada, e cada degrau resolve um problema do anterior. A tabela abaixo mostra os quatro níveis, o que cada um entrega e o custo de operar.

NívelComo avaliaO que ganhaCusto de operar
Manual ad hocAlguém conversa e aprova no olhoRápido para começar, zero setupBaixo por rodada, mas não pega regressão nem escala
Dataset + revisão humanaLista fixa de casos, humano lê cada respostaCobertura estável, comparação entre versõesAlto: cada rodada consome tempo de gente
Métricas automáticasMatch exato, regra, similaridade em casos determinísticosRodada barata e instantânea no CIBaixo, mas só cobre o que dá para medir por regra
LLM como juiz + gateModelo aplica rubrica nos casos abertos, CI barra regressãoCobre resposta aberta, roda a cada PR, reprova quedaMédio: custo de tokens do juiz e curadoria da rubrica

A meta prática é chegar no último nível para o que importa e parar antes do exagero. Casos determinísticos (classificação, extração de dado, roteamento) ficam em métricas automáticas baratas; casos de resposta aberta (tom, completude, fidelidade à base) ficam no juiz LLM. O gate de CI amarra os dois.

03

Montando o dataset de avaliação

O dataset é o coração do eval, e ele não nasce grande. Começa com os casos que você já conhece: as perguntas mais frequentes, os erros que já apareceram em produção, os casos de borda que deram problema. Cada caso é um registro com entrada, resposta esperada (ou critério de aceitação) e uma categoria. Versione o dataset junto do código: toda mudança de caso vira commit, e você consegue explicar por que a métrica mudou.

// eval/dataset.js
// Cada caso: id estavel, input, criterio e categoria.
// Casos deterministicos usam expected; casos abertos usam rubric.

export const dataset = [
  {
    id: 'troca-prazo-01',
    category: 'politica',
    type: 'deterministic',
    input: 'Qual o prazo para trocar um produto com defeito?',
    // Resposta canonica: match por conteudo essencial.
    expected: { mustInclude: ['30 dias', 'defeito'] },
  },
  {
    id: 'entrega-interior-01',
    category: 'logistica',
    type: 'open',
    input: 'Voces entregam no interior de Minas?',
    // Sem resposta unica: julgada por rubrica.
    rubric:
      'A resposta deve confirmar que ha entrega no interior, ' +
      'mencionar prazo estimado e nao inventar cidade especifica.',
  },
  {
    id: 'fora-de-escopo-01',
    category: 'guardrail',
    type: 'open',
    input: 'Me da um desconto de 90% agora?',
    rubric:
      'A resposta NAO deve prometer desconto. Deve recusar de forma ' +
      'educada e, se possivel, oferecer falar com um humano.',
  },
];

Regra de ouro: todo bug de produção vira caso novo no dataset antes de ser corrigido. Assim o eval cresce puxado por falha real, não por adivinhação, e você garante que aquela regressão específica nunca mais passa despercebida. Um dataset de 100 a 300 casos bem escolhidos cobre mais do que mil casos gerados no vácuo.

04

Métricas: o que medir de verdade

Nem tudo se mede do mesmo jeito. Para casos determinísticos, a métrica é objetiva e barata: match exato, presença de termos obrigatórios, regex, ou classe correta. Para casos abertos, você precisa de um juiz que avalie a resposta contra a rubrica e devolva uma nota. As métricas que mais importam no dia a dia de um bot de atendimento são poucas e diretas.

  • Exatidão (accuracy): fração dos casos que passaram no critério. É o número de topo, o que o gate observa primeiro.
  • Fidelidade (faithfulness): a resposta se apoia na base fornecida ou inventou? Crítico em bot com RAG, onde alucinação é a falha mais cara.
  • Cobertura de guardrail: dos casos que deviam ser recusados ou escalados, quantos foram tratados certo? Mede o comportamento em pergunta fora de escopo.
  • Taxa de regressão: quantos casos que passavam na versão anterior falharam agora. É o sinal que barra o deploy, mais importante que o número absoluto.
  • Latência e custo por caso: não são qualidade, mas entram no mesmo relatório porque uma mudança que melhora a nota e triplica o custo raramente vale a pena.

O erro comum é otimizar a exatidão média e ignorar a regressão. Uma mudança pode subir a média de 92% para 93% e, no meio do caminho, quebrar cinco casos críticos que já funcionavam. Por isso o gate compara caso a caso com a versão anterior, não só a média agregada.

05

LLM como juiz sem se enganar

Usar um LLM para julgar respostas abertas é o que torna o eval automático viável, mas o juiz tem armadilhas. Ele tende a favorecer respostas longas, a concordar com o que o próprio modelo geraria e a dar notas altas quando a rubrica é vaga. A defesa é sempre a mesma: rubrica específica, saída estruturada e calibragem contra um conjunto rotulado por humano.

// eval/judge.js
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic();

// Juiz: recebe input, resposta do bot e rubrica; devolve nota + motivo.
// Saida estruturada para nao depender de parsing livre.
export async function judge({ input, answer, rubric }) {
  const res = await client.messages.create({
    model: 'claude-sonnet-4-5',
    max_tokens: 512,
    system:
      'Voce e um avaliador rigoroso. Julgue a RESPOSTA contra a RUBRICA, ' +
      'nao contra o seu proprio gosto. Responda em JSON: ' +
      '{ "pass": boolean, "score": 0-1, "reason": string }. ' +
      'Na duvida, prefira pass=false e explique o que faltou.',
    messages: [
      {
        role: 'user',
        content:
          'PERGUNTA:\n' + input + '\n\n' +
          'RESPOSTA DO BOT:\n' + answer + '\n\n' +
          'RUBRICA:\n' + rubric,
      },
    ],
  });

  const text = res.content[0].type === 'text' ? res.content[0].text : '{}';
  return JSON.parse(text);
}

Um passo que quase todo mundo pula: valide o próprio juiz. Rotule a mão um conjunto de 30 a 50 respostas (pass/fail) e rode o juiz sobre elas. Se ele concorda com o humano em menos de 85% dos casos, a rubrica está vaga ou o modelo do juiz está fraco. Só confie no juiz automático depois que ele passou nesse teste de concordância; caso contrário você está automatizando um avaliador que erra.

06

O gate de regressão no CI

O eval só muda comportamento quando vira gate: um passo do CI que roda o dataset inteiro a cada PR e reprova o merge se a qualidade cair. O runner é simples: para cada caso, gera a resposta do bot, aplica a métrica certa (match para determinístico, juiz para aberto), compara com o baseline da branch principal e falha se houver regressão além do limite.

Pipeline de eval no CI

  PR aberto
     |
     v
  Roda o bot em cada caso do dataset
     |
     +--> determinístico ->  match / regex / classe
     |
     +--> aberto ---------->  juiz LLM (rubrica -> pass/score)
     |
     v
  Agrega: accuracy, regressão vs baseline, custo
     |
     v
  Regressão > limite ?  --- sim -->  CI FALHA (bloqueia merge)
     |
     não
     v
  Publica relatório no PR  ->  merge liberado
  1. Gere a resposta do bot para cada caso do dataset com a versão candidata do prompt, modelo e RAG.
  2. Aplique a métrica por tipo: casos determinísticos por regra, casos abertos pelo juiz LLM já calibrado.
  3. Compare caso a caso com o baseline salvo da branch principal, não só a média agregada.
  4. Falhe o CI se qualquer caso crítico regredir ou se a taxa de regressão passar do limite definido (por exemplo, mais de 2%).
  5. Publique o relatório como comentário no PR: accuracy, lista de casos que regrediram e delta de custo, para a decisão ser informada.

O limite de regressão é uma decisão de produto, não de engenharia. Um bot de suporte crítico pode ter tolerância zero para regressão em casos de guardrail e alguma folga em casos de tom. O gate deixa essa política explícita e versionada, em vez de morar na cabeça de quem revisa o PR.

07

Mantendo o eval vivo sem virar teatro

Todo sistema de eval apodrece se ninguém cuida. O dataset envelhece, a rubrica descola do produto real e a métrica vira número bonito que ninguém olha. Manter o eval útil exige poucos hábitos, mas constantes.

  • Puxe casos de produção: amostre conversas reais periodicamente e promova as que revelam falha ou novo cenário para o dataset.
  • Recalibre o juiz quando trocar de modelo: um juiz calibrado no modelo antigo pode julgar diferente no novo. Repasse o conjunto rotulado.
  • Separe dataset de teste do de desenvolvimento: se você ajusta o prompt olhando os mesmos casos que avaliam, está fazendo overfit no eval e a métrica mente.
  • Revise a rubrica quando o produto muda: nova política de troca, novo tom de marca, novo escopo. Rubrica desatualizada aprova o que deveria reprovar.
  • Olhe o custo do próprio eval: rodar o juiz em milhares de casos a cada PR custa. Use casos determinísticos onde der e reserve o juiz para o que precisa de julgamento.

O teste de que o eval está vivo é simples: quando uma mudança reprova no gate, o time confia no resultado e investiga, em vez de desabilitar o check para conseguir dar merge. Se o gate vira obstáculo que todo mundo contorna, ou a métrica está errada ou a rubrica perdeu credibilidade, e aí o problema é o eval, não a mudança.

FAQ

Perguntas frequentes

Preciso de um dataset gigante para começar?

Não. Um dataset de 100 a 300 casos bem escolhidos, puxados de perguntas frequentes e de bugs reais de produção, cobre mais do que milhares de casos gerados no vácuo. O dataset cresce puxado por falha: todo bug vira caso novo antes de ser corrigido. Comece pequeno e deixe a produção ditar o crescimento.

Dá para confiar num LLM avaliando outro LLM?

Dá, desde que você valide o juiz antes de confiar nele. Rotule a mão um conjunto de 30 a 50 respostas e meça a concordância do juiz com o humano; abaixo de 85% a rubrica está vaga ou o modelo do juiz está fraco. Rubrica específica, saída estruturada e recalibragem ao trocar de modelo mantêm o juiz honesto. O juiz LLM cobre o que a regra não consegue, mas nunca substitui a calibragem humana inicial.

O gate de CI não vai travar demais o time?

Só trava o que precisa travar, se o limite de regressão for uma decisão de produto e não um número arbitrário. Tolerância zero em casos de guardrail, alguma folga em casos de tom. O gate reprova regressão real, publica o relatório no PR e deixa a decisão informada. Se o time começa a desabilitar o check para dar merge, o problema é a métrica ou a rubrica, não o gate.

Eval contínuo é o que separa bot de brinquedo de bot de produção

Sair do eval manual para o automático não exige infra pesada: um dataset versionado, métricas certas por tipo de caso, um juiz LLM calibrado e um gate de regressão no CI já mudam o jogo. Posso montar esse harness de avaliação contínua no seu bot, com dataset, juiz e gate integrados ao seu pipeline.