Certa vez fiz deploy de uma mudança de prompt que deixou meu agente de suporte 4% melhor na métrica que eu acompanhava e 30% pior em fechar tickets de verdade. O eval estava verde. Os usuários estavam furiosos. Foi então que aprendi que a maioria dos evals de agentes mede a coisa errada — eles medem se a saída soa certa, não se o agente fez a coisa certa.
Se você está construindo agentes e seus evals são um punhado de verificações "a resposta parece boa?" pontuadas por outro modelo, você não tem evals. Você tem sensações com um número colado. Veja como escrevo evals para agentes de IA que realmente detectam regressões.
Assert no comportamento, não na prosa
A maior melhoria: pare de avaliar o texto final e comece a avaliar o que o agente fez. Ele chamou as ferramentas certas, em ordem razoável, com os argumentos certos? Modificou os arquivos que devia e deixou o resto intacto? Esses são fatos verificáveis, não opiniões.
Para um agente de código, meu eval não lê o resumo. Ele verifica: a suite de testes passa depois da execução, o agente tocou apenas os arquivos no escopo, evitou editar o lockfile? Três asserções booleanas. Nenhum juiz LLM em lugar algum. Elas nunca falharam aleatoriamente e pegam as falhas que importam.
assert run_tests() == 0, "tests fail after agent run"
assert touched_files <= allowed_files, f"out of scope: {touched_files - allowed_files}"
assert "package-lock.json" not in touched_files
A última veio de um incidente real. Um agente ficava "gentilmente" regenerando o lockfile e quebrando o CI. Uma asserção, nunca aconteceu de novo.
Teste a trajetória, não apenas o ponto final
Agentes falham no meio. A resposta final pode estar correta por sorte depois de um caminho desastroso — seis buscas redundantes, uma chamada de ferramenta com argumentos inúteis que por acaso tratou o erro com elegância, um desvio do qual se recuperou. Se você só verifica o ponto final, está cego para uma trajetória que está a uma pequena mudança de falhar por completo.
Então registro cada evento e faço assert no caminho. Ele chamou a busca antes de responder uma pergunta que precisava de informação fresca? Fez mais de duas chamadas de ferramenta redundantes? Alguma vez chegou a is_error: true em um resultado de ferramenta? Você pode pontuar uma trajetória sem juiz — a maior parte é contar e fazer correspondência de padrões no fluxo de eventos.
O comportamento do modelo mudou recentemente, aliás. Os modelos Opus mais novos recorrem às ferramentas de forma mais conservadora. Uma asserção "buscar primeiro" que passava em um modelo mais antigo pode começar a falhar não porque o agente piorou, mas porque ele agora responde a partir do contexto quando não deveria. Esse é exatamente o tipo de regressão que um eval de trajetória detecta e um eval de saída perde.
Quando você precisar de um juiz LLM, fixe-o
Algumas coisas genuinamente precisam de julgamento — o tom estava certo, o resumo capturou o ponto-chave, a explicação estava realmente correta? Tudo bem. Use um juiz LLM. Mas trate o juiz como código de produção, porque é isso que ele é.
Três regras que nunca quebro. Uma: fixe o modelo do juiz e a versão. Se o seu juiz atualiza silenciosamente, suas pontuações mudam e você vai perseguir uma regressão que na verdade é uma mudança de juiz. Duas: dê ao juiz um rubric concreto, não "avalie isso de 1 a 10." "A resposta cita um arquivo e número de linha específicos? sim/não" supera uma pontuação de sensação sempre. Três: verifique o juiz contra rótulos humanos em uma amostra. Um juiz que você nunca auditou é um gerador de números aleatórios com boas relações públicas.
Aqui está uma armadilha específica dos modelos atuais. Se você diz ao juiz "sinalize apenas problemas de alta gravidade" ou "seja conservador", os modelos mais novos seguem isso literalmente — encontram os bugs, depois recusam-se a reportar os que estão abaixo do seu limiar. Sua recall medida cai e parece que o agente regrediu quando na verdade o juiz simplesmente ficou mais obediente. Diga ao juiz para reportar tudo com uma confiança e gravidade, e filtre downstream. Mova a filtragem para fora da etapa de julgamento.
Construa o conjunto de evals a partir dos seus fracassos
Não sente e faça brainstorming de casos de teste. Você vai escrever os que já trata. Em vez disso, toda vez que um agente estraga tudo em produção, aquele cenário exato vira um caso de eval. O incidente do lockfile, o loop de vai-e-vem, a vez que respondeu a partir de contexto desatualizado — cada um é agora um teste de regressão permanente.
Essa é a parte que as pessoas pulam porque não é glamorosa. Mas um conjunto de evals crescido a partir de incidentes reais vale dez brainstormeados. É estrutural de um jeito que casos sintéticos nunca são, porque cada caso é um bug que realmente te mordeu.
Execute-os a cada mudança de prompt
O ponto inteiro é o loop. Você muda um prompt, executa os evals, vê as asserções de trajetória antes de fazer o deploy. Meu desastre com o agente de suporte aconteceu porque eu olhei rapidamente algumas saídas e fiz o deploy por intuição. Se eu tivesse tido evals de trajetória — "ele realmente resolveu ou apenas soou resolvido" — a queda de 30% teria ficado vermelha antes de atingir um único usuário.
Evals não são uma porta de qualidade que você parafusa no final. São a única coisa que separa "acho que esse prompt é melhor" de "esse prompt é melhor." Um desses é engenharia. O outro é um palpite usando jaleco de laboratório.
Faça-os crescer a partir das suas cicatrizes. Faça assert no que o agente fez. Fixe o seu juiz. E nunca, jamais faça deploy de uma mudança de prompt por sensação.
