Seu agente melhorou mesmo? Testes de regressão para sistemas de IA

O fluxo mais comum para ajustar um agente ainda é preocupantemente manual: alguém muda o prompt, faz três ou quatro perguntas de teste no chat, acha que ficou melhor, e sobe para produção. Isso não é validação. É uma amostra de tamanho quatro, escolhida por quem já está com viés de confirmação a favor da própria mudança.

O problema que engenharia de software já resolveu há décadas, só que para IA

Testes de regressão existem exatamente para isso: garantir que uma mudança não quebra silenciosamente algo que já funcionava. A diferença é que ninguém pensa duas vezes antes de rodar a suíte de testes inteira depois de alterar uma função. Alterar um prompt, por outro lado, ainda costuma passar sem esse mesmo cuidado, como se prompt fosse uma categoria de código que não precisasse do mesmo tipo de disciplina.

Um conjunto fixo de casos de teste, cobrindo os cenários que a aplicação realmente precisa lidar bem, rodado automaticamente contra a versão nova do prompt (ou do modelo, ou da lógica de orquestração), resolve o mesmo problema que testes de regressão sempre resolveram: detectar, antes de produção, que uma mudança pensada para melhorar um caso específico piorou outros três que ninguém estava observando no momento.

Por que comparação exata de string não funciona aqui

A tentação natural é tratar isso como teste de software comum: entrada fixa, saída esperada fixa, comparação exata. O problema é que a saída de um LLM não é determinística da mesma forma que a saída de uma função pura: a mesma entrada pode gerar respostas com redação diferente entre execuções, mesmo mantendo o mesmo significado e a mesma correção.

Isso exige trocar a asserção de “a resposta é exatamente esse texto” por asserções comportamentais: a resposta contém a informação esperada, a resposta não contém uma afirmação que deveria ter sido evitada, a ferramenta certa foi chamada com os parâmetros certos, a resposta respeita um formato estrutural esperado. São critérios que toleram variação superficial de redação sem deixar de capturar uma regressão real de comportamento.

[Theory]
[MemberData(nameof(CasosDeRegressao))]
public async Task Agente_DeveManterComportamentoEsperado(CasoDeTeste caso)
{
    var resposta = await agente.ResponderAsync(caso.Pergunta);

    Assert.Contains(caso.InformacaoEsperada, resposta.Texto, StringComparison.OrdinalIgnoreCase);
    Assert.DoesNotContain(caso.AfirmacaoProibida, resposta.Texto, StringComparison.OrdinalIgnoreCase);
    Assert.Equal(caso.FerramentaEsperada, resposta.FerramentasChamadas.FirstOrDefault());
}

O ponto central não é a sintaxe específica desse exemplo, é a ideia de que cada caso do conjunto de regressão carrega uma expectativa comportamental verificável automaticamente, em vez de depender de alguém lendo a resposta e decidindo, na hora, se “parece boa”.

Comparando antes e depois, não só validando o depois

Rodar o conjunto de regressão contra a versão nova sozinha já ajuda, mas o valor real aparece ao comparar o resultado da versão nova com o resultado da versão anterior nos mesmos casos exatos. Isso revela não só se a versão nova passa nos critérios mínimos, mas especificamente quais casos que antes passavam deixaram de passar, o tipo de informação que “parece melhor numa olhada rápida” nunca vai revelar, porque ninguém compara mentalmente dezenas de respostas antigas contra dezenas de respostas novas com precisão suficiente.

O conjunto de teste precisa cobrir o que dói, não só o que é fácil

Um conjunto de regressão só com perguntas simples e óbvias não detecta muita coisa, porque essas raramente são as que quebram. Vale priorizar casos que já causaram problema antes, casos de borda conhecidos do domínio, e casos onde o comportamento correto é sutil o suficiente para ser fácil de errar sem perceber. Um conjunto de regressão pequeno e bem escolhido detecta mais problema do que um conjunto grande cheio de repetição do óbvio.

Testar na mão ainda tem seu lugar, só não deveria ser o único lugar

Testar manualmente uma mudança continua sendo útil para exploração inicial, para sentir rapidamente se uma ideia de prompt faz sentido antes de investir mais tempo nela. O problema é usar essa exploração informal como critério final de aprovação para produção. Regressão automatizada não substitui esse primeiro momento exploratório. Substitui a etapa seguinte, onde alguém precisa decidir, com alguma confiança real, se a mudança pode ir para produção sem quebrar o que já funcionava.