Do 'Vibe Coding' à Engenharia de Precisão: O Fim dos Testes no Olhômetro — aula do módulo Por que Testar LLMs é Diferente, na trilha Fundamentos de Evals &…
Leitura de aproximadamente 5 minutos.
Módulo: Por que Testar LLMs é Diferente · Curso: Fundamentos de Evals & Engenharia de Testes de IA · Formação: Formação IA Harness: Test & Evaluation Harness para IA
O desenvolvimento moderno assistido por Inteligência Artificial popularizou o termo "Vibe Coding" — a prática onde o desenvolvedor itera rapidamente via prompts conversacionais, avalia duas ou três saídas no olho humano e assume que a aplicação está pronta para produção porque a "vibe" da resposta pareceu correta.
Em protótipos e provas de conceito, essa abordagem acelera os primeiros minutos de exploração. No entanto, quando esse sistema é exposto a milhares de usuários simultâneos com entradas imprevisíveis, o vibe coding colapsa. Modelos probabilísticos não possuem garantias determinísticas de compilação: uma resposta perfeitamente formatada hoje pode quebrar silenciosamente amanhã sob variações sutis de pontuação, idioma ou latência de rede.
Nesta aula, você aprenderá a transição arquitetural do desenvolvimento intuitivo para a Engenharia de Precisão, estabelecendo suítes automatizadas de avaliação de IA (Evaluation Harness) que tratam prompts com o mesmo rigor com que engenheiros de software tratam código crítico.
O teste manual de prompts em interfaces como ChatGPT, Claude Chat ou Google AI Studio sofre de três vícios cognitivos fatais para a engenharia de software:
1. Viés de Confirmação: O autor do prompt tende a testar apenas os casos felizes (happy paths) que ele mesmo imaginou ao formular a instrução. 2. Amostragem Insuficiente: Três execuções manuais representam uma fração estatisticamente irrelevante de um espaço amostral que contém infinitas combinações de tokens. 3. Incapacidade de Detecção de Regressão: Quando o prompt é ajustado para consertar um caso de borda específico, o operador humano não reexecuta manualmente as dezenas de exemplos anteriores para verificar se continuam funcionando.
A consequência direta é o chamado "Prompt Drift": a cada iteração cosmética no texto da instrução, a assertividade global da aplicação degrada de forma silenciosa e invisível para o time de desenvolvimento.
Na engenharia de hardware e software automotivo, um test harness (ou chicote de testes) é a bancada isolada onde um componente é submetido a estímulos extremos e mensurado continuamente.
Em sistemas de IA generativa, um Evaluation Harness é uma suíte automatizada composta por quatro pilares complementares:
+------------------------------------------------------------------------+
| O CICLO DE EVALUATION |
+------------------------------------------------------------------------+
| 1. Golden Dataset (Entradas de Produção + Critérios de Sucesso) |
| | |
| v |
| 2. Execution Runner (Dispara Modelos, Temperatura e Rate Limits) |
| | |
| v |
| 3. Scoring Engine (Assertivas Exatas + Semânticas + LLM Juiz) |
| | |
| v |
| 4. Relatório & Portão de Qualidade (Pass/Fail no CI/CD) |
+------------------------------------------------------------------------+
Ao contrário de testes unitários tradicionais baseados em asserções booleanas estritas (assert output === expected), o Harness avalia tanto propriedades determinísticas (estrutura de schema, presença de campos obrigatórios) quanto propriedades semânticas (relevância, ausência de alucinação e conformidade com diretrizes de segurança).
Abaixo, construímos um runner básico em TypeScript capaz de testar uma versão de prompt contra um conjunto de fixtures, medindo a taxa de sucesso com base em asserções estruturadas:
// harness/simple-runner.ts - Runner de avaliação determinística
import { GoogleGenAI } from '@google/genai';
interface TestCase {
id: string;
input: string;
expectedCategory: string;
maxLatencyMs: number;
}
interface TestResult {
id: string;
passed: boolean;
actualCategory: string;
latencyMs: number;
error?: string;
}
const goldenDataset: TestCase[] = [
{ id: 'TC01', input: 'Quero cancelar minha assinatura anual', expectedCategory: 'CHURN', maxLatencyMs: 2500 },
{ id: 'TC02', input: 'Onde baixo a nota fiscal do mês passado?', expectedCategory: 'FINANCEIRO', maxLatencyMs: 2500 },
{ id: 'TC03', input: 'Como configuro o webhook de pagamento?', expectedCategory: 'SUPORTE_TECNICO', maxLatencyMs: 2500 },
];
export async function runPromptEvaluation(systemPrompt: string): Promise<{ accuracy: number; results: TestResult[] }> {
const ai = new GoogleGenAI();
const results: TestResult[] = [];
let passedCount = 0;
for (const tc of goldenDataset) {
const start = Date.now();
try {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
config: {
systemInstruction: systemPrompt,
temperature: 0.1,
responseMimeType: 'application/json',
},
contents: tc.input,
});
const latencyMs = Date.now() - start;
const parsed = JSON.parse(response.text || '{}');
const passed = parsed.category === tc.expectedCategory && latencyMs <= tc.maxLatencyMs;
if (passed) passedCount++;
results.push({ id: tc.id, passed, actualCategory: parsed.category, latencyMs });
} catch (err: any) {
results.push({ id: tc.id, passed: false, actualCategory: 'ERROR', latencyMs: Date.now() - start, error: err.message });
}
}
return {
accuracy: (passedCount / goldenDataset.length) * 100,
results,
};
}
Assim como o TDD (Test-Driven Development) transformou o desenvolvimento web tradicional, o EDD (Eval-Driven Development) redefine o fluxo de engenharia de IA:
1. Colete os Casos Reais: Antes de alterar o prompt, adicione a entrada do usuário que causou o bug ao seu Golden Dataset. 2. Execute a Baseline: Rode a suíte e registre a nota de acurácia da versão atual (ex: 82.5%). 3. Altere o Prompt ou Modelo: Faça o ajuste na instrução de sistema ou migre para um modelo mais leve/econômico. 4. Verifique o Delta: O novo prompt resolveu o caso adicionado sem derrubar a pontuação geral da suíte? Se a nota saltou para 85.0%, o commit está liberado. Se a nota caiu para 79.0%, a alteração introduziu uma regressão silenciosa e deve ser barrada.