Engenharia

Um eval é a única definição honesta de "funciona"

"Funciona" é um sentimento; um flow que roda o agent real é um resultado.

ASR

Apollo Space Research

Apollo Space

· 12 min de leitura

Alguém escreve um teste pequenininho para um agent de IA: um chat roteirizado onde um cliente inventado diz “sou o José da contabilidade, quem sou eu?” e o agent responde “você é o José da contabilidade”. O teste fica verde. O dashboard fica verde. E numa daily, alguém diz as palavras que deveriam fazer o estômago de qualquer líder de time afundar: memória funciona agora.

Não funciona. O que acabou de acontecer é que uma string entrou e a mesma string voltou. Nenhum cliente real, nenhuma sessão real, nenhuma recall real sob pressão, um teatro de bonecos avaliado pelo bonequeiro. Mas o checkmark está verde brilhante, e verde é contagioso. Até sexta, “memória funciona” virou um fato do qual três outras features silenciosamente dependem.

Esse único checkmark verde é o artefato mais perigoso da engenharia de agents. Este post é sobre por quê, e sobre a única coisa que encontramos que o substitui.

“Funciona” é um sentimento; um flow que roda o agent real é um resultado.

A versão ingênua: verde é o objetivo

A forma óbvia de saber que seu agent funciona é a forma que todo dashboard te treina a pensar. Você escreve testes. Eles passam. A barra enche. Verde significa pronto.

Isso é ótimo, genuinamente ótimo, para código que faz uma coisa determinística. Uma função que soma dois números ou os soma ou não, e um teste que passa é uma prova real, porque existe exatamente uma resposta certa e o teste a verifica.

Um agent não é isso. Um agent decide. Ele lê um pedido ambíguo, escolhe uma tool, recalls algo de três turnos atrás, escolhe o que dizer, e muda de ideia com base em qual foi a última resposta. Não há uma única resposta certa para asserir contra, há um comportamento, se desenrolando ao longo de uma conversa, que é ou bom ou ruim em contexto. Então quando um time recorre à única tool que conhece, o teste determinístico, ele acaba testando a única coisa que consegue fixar: uma string fixa entrando e uma string fixa saindo.

E essa é a armadilha. O teste que você consegue escrever para um agent quase nunca é o teste que importa.

Um teste que passa numa conversa roteirizada prova que o roteiro rodou. Não diz nada sobre se o agent consegue pensar.

O teste do José-da-contabilidade é o espécime perfeito. Parece um teste de memória. Tem o formato de um teste de memória. Mas nunca exercita memória, ele alimenta a resposta como a pergunta, então mesmo um agent sem memória alguma passa fácil. O time não mentiu. Eles escreveram um teste real, ele realmente passou, e a coisa que provou era inútil. Esse é o modo de falha, e ele não vem de descuido. Vem de tratar “verde” como o objetivo quando verde sempre foi só um proxy.

De um lado, um sentimento auto-avaliado, um agent reporta que funciona, uma demo de happy-path, manda pra produção. Do outro, um resultado, um flow no corpus roda o agent real e produz um trace com pass ou fail. A seta entre eles é o gap que um eval existe para fechar.

O fix é mudar o que “pronto” significa

Se um teste que passa pode ser inútil, você não pode deixar um teste que passa definir pronto. Você tem que definir pronto como algo que um teste inútil não consegue fingir.

A ideia-chave é simples. Uma afirmação comportamental só conta se ela traça até um flow, um cenário real que roda o runtime de agent de verdade, ponta a ponta, e produz um trace que você consegue ler. Não um mock do agent. Não uma tool stubbed retornando um valor enlatado. O mesmo motor que conversa com um cliente real, rodado contra um cenário construído para fazer o comportamento de fato acontecer.

“Funciona” é um sentimento; um flow que roda o agent real é um resultado.

Veja o que isso faz com a afirmação de memória. Um flow que genuinamente testa memória não pode alimentar a resposta como a pergunta. Ele tem que ser uma conversa com pelo menos dois turnos, onde o turno um estabelece algo que o agent precisa lembrar e o turno dois depende de recordar isso sem ser relembrado. Turno um: eu toco um pequeno escritório de contabilidade e só cuido de declarações trimestrais, nunca folha de pagamento. Cinco turnos depois, com outros tópicos no meio: você consegue assumir minha folha de pagamento? Um agent com memória funcionando diz não, essa não é sua área. Um agent que está fingindo oferece ajuda com folha de pagamento, alegremente, tendo esquecido com quem está falando. Não há string que você consiga passar para fingir isso. O comportamento ou sobrevive à distância entre os dois turnos ou não.

Essa é a diferença entre um teste e um flow. Um teste pergunta o código rodou. Um flow pergunta o agent se comportou, e a única forma de responder é fazer o comportamento acontecer de verdade e observar.

Um flow vermelho é um endereço, não uma reclamação

Aqui está a objeção que vem em seguida, e é justa. Se você para de confiar no checkmark verde e começa a rodar centenas de flows de comportamento real, muitos deles vão falhar. Isso não é só trocar o falso conforto de um dashboard por um dashboard diferente cheio de vermelho?

Seria, se um flow que falha te dissesse a mesma coisa inútil que um teste que falha diz. Mas não diz, e essa é a parte que vale desacelerar.

Quando um teste determinístico falha, você ganha “esperava X, recebeu Y” e um número de linha. Quando um flow falha, você ganha um transcript, a conversa inteira que o agent de fato teve, as tools que ele buscou, a coisa que recordou ou não, o momento em que deu errado. Um flow vermelho não é um veredito. É um gap localizado com endereço de retorno. O agent esquece uma restrição depois de quatro turnos de conversa não relacionada não é um lamento sobre o sistema parecer burro. É uma coordenada. Você sabe qual comportamento, em qual turno, sob qual pressão.

Essa é a diferença silenciosa entre uma suíte de evals e uma suíte de testes. Uma suíte de testes te diz que algo quebrou. Um eval te diz o que o agent ainda não consegue fazer, e onde se posicionar para consertar.

“O sistema parece burro” é um sentimento. “Ele larga a restrição de folha de pagamento no turno seis” é uma ordem de serviço.

E uma vez que um flow vermelho é um endereço, o loop quase se escreve sozinho. Um flow que falha aponta para um comportamento; um fix mira esse comportamento; você re-roda o flow para ver se o comportamento mudou. Sem adivinhar se você ajudou. O flow que achou o gap é o mesmo flow que certifica que o gap fechou. Você nunca está debugando uma vibe, você está debugando um transcript, contra um cenário que pode rodar de novo sob demanda.

O loop interno roda um corpus de flows contra o runtime real; um flow vermelho vira um gap localizado que é consertado em isolamento e re-rodado. O loop externo é a superfície deployada onde um humano de fato usa. Verde interno é um proxy rápido; o pass externo é a verdade.

Dois loops, e nunca confunda os dois

Há uma forma de levar essa ideia longe demais, e ela falha na direção oposta, então vale nomear.

Suponha que você construa a suíte de evals, a faça crescer para centenas de flows, cada um rode o runtime real, e todos fiquem verdes. É tentador chamar isso de pronto. Não é, e confundir isso com pronto é só o erro do checkmark-verde vestindo roupa melhor. Um flow roda o agent real, mas o roda num harness, num cenário que você escreveu, de um terminal. Um usuário real o roda através de um produto deployado, numa superfície que ele não entende, com intenções que você nunca imaginou.

Então seguramos dois loops, e nunca deixamos um fingir ser o outro.

O loop interno é rápido. É a suíte de evals, centenas de flows contra o runtime vivo, rodáveis em segundos, paralelos, baratos o bastante para rodar a cada mudança. É onde um flow vermelho vira um fix e um fix é re-checado. É o proxy: perto o bastante da verdade para se guiar por ele, rápido o bastante para se guiar com ele.

O loop externo é lento, e é a verdade. É uma pessoa real na superfície deployada, fazendo a coisa que veio fazer, e funcionando. Sem harness, sem arquivo de cenário, sem andaime amigável, o produto, na selva.

Um loop interno que passa ganha uma frase e não mais: comportamentalmente verde, pendente da superfície real. Ele não ganha “pronto”. Reportar os dois como um número, colapsando “os flows passam” em “funciona”, é o erro do José-da-contabilidade uma altitude acima. O report honesto são dois números, mantidos separados: quantos flows passam no harness, e se um humano conseguiu o que veio buscar na coisa viva. Junte-os e você está de volta a mentir com um checkmark, só que um mais caro.

Essa é a disciplina inteira. O loop interno te deixa se mover rápido sem voar às cegas. O loop externo mantém o loop interno honesto sobre o que de fato provou.

O corpus está vivo

Mais uma peça, porque uma suíte de evals fixa apodrece do mesmo jeito que uma suíte de testes fixa.

Se o conjunto de flows nunca muda, você eventualmente faz overfit nele. O agent fica bom exatamente nos cenários que você pensou em escrever, e cego para cada um que não pensou, que são a maioria deles, porque as situações que quebram um agent em produção são as que ninguém imaginou numa reunião. Um corpus congelado vira um cobertor de conforto: tudo verde, o tempo todo, tudo nas perguntas para as quais você já sabia as respostas.

Então o corpus tem que crescer, e ele cresce da realidade. Toda conversa real que um agent tem é matéria-prima para um novo flow. Um usuário formula um pedido de um jeito que ninguém antecipou; essa formulação vira um flow. O agent lida mal com um edge que nenhum teste cobriu; esse edge vira um flow, tagueado com de onde veio. O conjunto de coisas que você mede se expande para combinar com o conjunto de coisas que de fato acontecem, então o eval não pode ser burlado, porque você não o escreveu de antemão a partir da sua própria imaginação. Você o colheu do mundo.

É isso que transforma evals de uma auditoria única num motor. O monólogo de um usuário frustrado vira um flow; o flow acha o gap; o gap é consertado; o comportamento consertado é travado pelo flow que o achou. Toda conversa torna a próxima versão mais difícil de enganar.

O que um eval de fato é

Então recue e olhe o que de fato estivemos descrevendo, porque a palavra “eval” está fazendo muito trabalho silencioso.

Um eval não é um teste. Um teste pergunta se o código fez o que o autor esperava. Um eval pergunta se um agent se comportou bem numa situação que importava, e responde tornando a situação real e observando o que acontece. É a diferença entre perguntar a um piloto se ele consegue pousar o avião e colocá-lo no simulador num vento cruzado. Um é uma afirmação. O outro é um voo.

Esse reframe é o post inteiro. “Funciona” é um sentimento; um flow que roda o agent real é um resultado. Todo o resto, os loops interno e externo, o corpus vivo, o flow-vermelho-como-endereço, é só a maquinaria que torna a segunda coisa construível na velocidade em que a primeira é afirmável.

A virada: honestidade é algo que você engenheira, não algo que você tem

Perceba sobre o que isso é de verdade, debaixo dos loops e do corpus. Não é sobre agents. É sobre a tentação mais antiga em construir qualquer coisa: acreditar que a coisa é boa porque você quer que ela seja boa, e recorrer à medição que confirma isso.

Todo time que já enviou produto conhece essa tentação pelo tato. O dashboard verde antes de um lançamento. A demo que funcionou as três vezes que você praticou. A métrica que subiu porque você a definiu para isso. Nenhuma dessas é uma mentira, exatamente, são esperanças vestidas de fantasia de evidência, e a razão de serem tão perigosas é que parecem rigor. Uma disciplina de eval é, no fim, uma forma de recusar ser consolado pelo seu próprio otimismo. É um padrão que você constrói fora de você mesmo, para que no dia em que você mais quiser que a coisa funcione, algo além do seu querer decida.

A parte difícil disso nunca foi a engenharia. O harness são algumas centenas de linhas. A parte difícil é a disposição humana de manter um número vermelho num dashboard que você poderia tão facilmente tornar verde, de olhar para um transcript real onde seu agent falhou com uma pessoa real e anotá-lo como um flow em vez de explicá-lo para fora. Essa disciplina não vem do tooling. Vem de um time que prefere saber a se sentir bem.

E essa é a única definição honesta de “funciona” que alguém já teve. Não o checkmark. A coisa que o checkmark deveria representar, de fato verificada, na coisa real, diante de alguém que precisava dela.


É isso que estamos construindo na Apollo Space: um operating system que conquista a palavra “funciona” do jeito difícil, rodando o agent real contra a situação real e lendo o que de fato aconteceu, em vez de confiar na luz verde. Se você já enviou algo que o dashboard jurava estar bem e um usuário provou o contrário, você já sabe qual número deveria estar observando.

A Apollo cuida da operação repetitiva da sua empresa pro seu time não precisar.

Entre na lista de espera: acesso antecipado, preço de usuário fundador e um lugar na primeira fila enquanto a gente constrói.

Entrar na lista de espera