Seu eval set é um museu. Ele deveria ser um ralo.
Um test set fixo apodrece no momento em que você começa a passar nele. O conserto é um flywheel: toda conversa real que deu errado vira um novo teste, então você nunca consegue dar overfit num problema que já resolveu.
Apollo Space Research
Apollo Space
Um time escreve duzentos casos de teste para seu agent, roda, ganha um dashboard verde, e lança. Três semanas depois um cliente pergunta ao agent algo que nenhum dos duzentos cobria, o agent atrapalha tudo, e o dashboard continua verde. Ele esteve verde o tempo todo. Ele vai continuar verde enquanto o produto lentamente para de funcionar, porque o test set parou de aprender no dia em que foi escrito.
Esse é o jeito silencioso como toda suíte de eval morre. Não num build vermelho, num verde que não significa mais nada.
O conserto não é um test set maior. É um test set que cresce a partir do trabalho. Toda conversa que deu errado deveria deixar para trás um teste, para que o eval nunca consiga dar overfit num problema que você já resolveu. Este post é sobre como construir um eval que drena falhas reais para fora da produção e transforma cada uma numa pergunta permanente que você nunca mais consegue errar.
O eval ingênuo é um museu, e museus não se movem
O jeito óbvio de avaliar um agent é o jeito que você avaliaria um estudante: escreva a prova uma vez, corrija contra ela para sempre. Você se senta no começo do projeto, imagina as coisas que os usuários vão perguntar, escreve algumas centenas de casos, e a partir daí uma rodada que passa significa “o agent faz o que imaginamos”.
Funciona lindamente por exatamente o tempo em que sua imaginação bateu com a realidade. Ou seja, por uma semana.
Aqui está a falha, e ela é estrutural, não preguiçosa. Os casos que você escreveu são os casos que você já entendia. Você não consegue escrever um teste para uma falha que ainda não imaginou, se você a tivesse imaginado, você a teria tratado, e não haveria nada a testar. Então um eval set fixo mede uma coisa precisamente: sua previsão no dia em que o escreveu. Ele não diz nada sobre o input que aparece na próxima terça, a formulação que ninguém do time jamais usaria, a borda do produto onde os usuários reais vivem. O set é um museu. Os itens em exposição são as falhas que você viu chegando. As que te machucam são as que entraram depois de fechar.
E piora, porque você otimiza contra ele. Todo conserto que você faz é mirado no test set, então o set fica mais fácil de passar a cada sprint. A verdura sobe enquanto a coisa que a verdura deveria prever, ele funciona para uma pessoa real, se afasta por baixo. Você não está mais medindo qualidade. Você está medindo quão bem decorou sua própria prova.
O gargalo nunca desaparece. Ele só se move de “conseguimos passar no teste” para “o teste ainda é sobre alguma coisa”.
O flywheel: uma falha vira um teste, automaticamente
Então paramos de tratar o eval set como uma coisa que você escreve e começamos a tratá-lo como uma coisa que se preenche sozinha.
A versão ingênua diz: um teste é algo que um engenheiro escreve. A nossa versão diz: um teste é algo que uma conversa ruim deposita. Quando uma interação real dá errado, o agent escolhe a ferramenta errada, esquece o que foi dito a ele um minuto atrás, responde uma pergunta na língua do usuário com uma ação na língua errada, alega que fez algo que não fez, essa conversa não é só logada e esquecida. Ela é cunhada num flow: um caso nomeado e reproduzível que reproduz exatamente o que deu errado, estacionado permanentemente no corpus.
O mecanismo é simples de enunciar e esse é o ponto. Uma falha real entra. Capturamos a forma dela, o input, o contexto, qual era a resposta certa, o que o agent fez em vez disso. Transformamos essa forma num caso que roda contra o runtime real do agent, não um mock. A partir daí, aquela falha exata é uma pergunta que o agent tem que responder corretamente para sempre. Conserte uma vez, e o teste fica de guarda para que você nunca mais consiga silenciosamente quebrá-la.
Toda conversa que deu errado deveria deixar para trás um teste, para que o eval nunca consiga dar overfit num problema que você já resolveu.
A forma à direita é a ideia inteira. Uma conversa dá errado. A falha vira um flow. O corpus cresce em um. O agent é agora avaliado contra aquele flow a cada rodada, para sempre. E porque o loop nunca fecha, o corpus acompanha a realidade em vez de acompanhar sua memória da realidade. Você não consegue dar overfit nele, porque ele é alimentado pela exata coisa que o overfitting esconde de você: as falhas que você não viu chegando.
Esse é o movimento que vira um eval de um museu num ralo. Um museu exibe o que você escolheu coletar. Um ralo pega o que quer que de fato flua por ele. Você quer o ralo.
”Burro” é um teste faltando, não uma feature faltando
Há um tipo particular de reclamação que um eval set fixo te ensina a ignorar, e é o sinal mais valioso que você tem.
Imagine um usuário digitando o equivalente conversacional de essa coisa é burra. Ele pediu algo razoável e recebeu algo inútil. Num time de eval-fixo, essa reclamação não tem para onde ir. Ela não está nos duzentos casos. Não move o dashboard. Então ela vira uma mensagem no Slack, depois um sentimento vago de que “o agent anda meio off ultimamente”, depois um lamento numa retro com o qual todos concordam com a cabeça e ninguém consegue agir. O sinal era real. Ele só não tinha forma, então evaporou.
O instinto ingênuo é ler essa reclamação como uma feature faltando, precisamos tratar essa categoria melhor, e adicioná-la a um backlog onde ela compete com tudo o mais e perde.
A reformulação é mais afiada: não é uma feature faltando, é um teste faltando. O usuário acabou de te entregar, de graça, um input real que produziu uma falha real. Isso não é um sentimento para absorver; é um caso para cunhar. Você pega a conversa, captura o que deu errado, e a solta no corpus como uma lacuna localizada, não “o agent parece burro” mas “este flow exato, neste input exato, produziu esta resposta errada exata, e aqui está onde quebrou”.
A diferença é enorme. Um sentimento é algo sobre o qual você discute numa reunião. Uma lacuna localizada é algo que você conserta e depois guarda. Um re-diagnostica o mesmo mal-estar vago toda semana. O outro transforma uma única mensagem raivosa numa melhoria permanente que nunca consegue silenciosamente regredir. A reclamação para de ser ruído e vira o caso de teste mais honesto que você possui, porque nenhuma imaginação de engenheiro a produziu, a frustração real de um usuário real produziu.
Um caso vermelho não é um lamento. É um endereço.
Dois números, nunca um: o proxy rápido e a verdade
Aqui é onde um eval set crescente esbarra num limite duro, e vale ser honesto sobre ele em vez de passar pano.
Você quer que o loop rode rápido. Uma falha deveria virar um teste, o teste deveria rodar em segundos, você deveria conseguir distribuir dezenas deles em paralelo, fazer A/B entre tamanhos de modelo, e ter uma resposta de volta antes de perder o fio. Essa velocidade é o que faz o flywheel girar. Então você constrói um harness local: o runtime real do agent, in-process, reproduzindo flows contra o corpus, imprimindo o que ele classificou, quais ferramentas buscou, o que respondeu, e o que lembrou. Rápido, barato, repetível. O proxy rápido.
O movimento ingênuo é chamar verde no proxy rápido de “pronto”. Não é, e fingir que é recria o problema original do museu um nível acima. Um harness local ainda é um ambiente controlado. É o seu melhor palpite da realidade, rodado rápido, mas é um palpite. A coisa que de fato é verdade é se uma pessoa real, no produto realmente deployado, clicando na superfície real, recebeu um resultado que funcionou.
Então você reporta dois números e nunca os mescla. O número interno é o proxy rápido: como o agent se sai contra o corpus crescente, localmente, em segundos. O número externo é a verdade: como ele se sai quando um humano usa a coisa lançada. Verde-interno significa comportamentalmente promissor, pendente da superfície real. Verde-externo significa de fato funcionou para alguém. No momento em que você colapsa esses dois num único “funciona”, você contou a si mesmo uma mentira reconfortante, a mesma mentira que o dashboard verde do museu contou, só que mais rápido.
Os dois números importam, e importam de modo diferente. O número interno é como você se move rápido sem voar às cegas, ele pega a regressão em segundos, na sua máquina, antes de ela chegar a uma pessoa. O número externo é como você fica honesto, é o único que tem permissão de dizer “isso é real”. Mantê-los separados é a disciplina que impede um loop rápido de silenciosamente virar de volta um museu que só roda mais vezes.
O corpus é o ativo, não o agent
Dê um passo atrás e note o que você está de fato construindo quando roda o loop desse jeito.
Todo time acha que o agent é a coisa valiosa, os prompts, as ferramentas, a orquestração. Eles não são nada. Mas são substituíveis. O modelo por baixo vai mudar. O prompt vai ser reescrito. A camada de ferramentas vai ser trocada. Nada disso é o moat.
O moat é o corpus. Toda falha que seu produto já bateu, cunhada num caso, reproduzível contra qualquer agent que venha a seguir. Esse set é um registro estruturado de todo jeito que seu produto específico, no seu domínio específico, foi errado por pessoas reais. Um novo modelo chega, você o roda contra o corpus e descobre, numa tarde, se ele é de fato melhor no seu trabalho ou só melhor no benchmark de alguém. Você reconstrói o agent do zero, o corpus te diz instantaneamente quais das falhas antigas voltaram. O agent é o candidato. O corpus é a entrevista, e é uma entrevista que fica mais difícil e mais honesta a cada semana, porque é alimentada pela única fonte que não pode ser burlada: o que de fato deu errado.
Esse é o ativo que compõe. Imagine dois times lançando o mesmo agent no dia um. Um escreve um test set fixo e o congela. O outro drena toda falha para um corpus crescente. Seis meses depois, digamos mil conversas reais, o set do primeiro time ainda mede a imaginação do dia um. O set do segundo time mede mil jeitos reais como o produto encontrou o mundo. Eles não são mais a mesma empresa, e a diferença não é o modelo. É que um deles continuou aprendendo de estar errado.
A virada: o custo de uma reclamação que não vai a lugar nenhum
Tire o harness, o corpus e os dois números, e o que sobra é mais antigo que tudo isso.
Toda empresa já tem a matéria-prima do flywheel. Ela chega todo dia, de graça, na forma de usuários te dizendo exatamente onde o produto os decepcionou. A pergunta nunca foi se você tem o sinal. Você está se afogando nele. A pergunta é se alguma coisa o captura, se uma mensagem frustrada vira um teste permanente, ou vira um sentimento que some até sexta.
Uma reclamação que não vai a lugar nenhum é a coisa mais cara numa empresa de software, porque você pagou o preço cheio, a confiança de um usuário, e não recebeu nada de volta. Nenhum conserto que se sustenta, nenhum teste que guarda, nenhuma lição que o sistema não consiga esquecer. Você absorveu o dano e descartou os dados. O flywheel é, por baixo de toda a maquinaria, só a decisão de parar de fazer isso: tratar todo momento em que o produto decepcionou alguém como um presente que você se recusa a desperdiçar.
Essa é a parte que não é sobre evals de jeito nenhum. É sobre se sua empresa fica mais inteligente de estar errada, ou só fica cansada disso. Os times que vencem a próxima década não serão os com os agents mais espertos. Serão aqueles cujos erros só conseguem acontecer uma vez.
É isso que estamos construindo na Apollo Space, não um test set que você escreve e congela, mas um que se preenche sozinho a partir de toda conversa que não saiu do jeito que deveria, para que o sistema seja sempre avaliado pelo que de fato deu errado. Se você já viu um dashboard verde te tranquilizar enquanto o produto silenciosamente parava de funcionar, você já sabe por que seu eval set deveria ser um ralo, não um museu.
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 esperaO imposto oculto dos agents em paralelo é um diamante de migrations
Seis agents escrevendo para um schema conflitam no banco de dados, não no código, e a CI morre em "multiple heads".
EngenhariaUm orchestrator que não sobrevive ao próprio crash não é um
Um crash que apaga o raciocínio do orchestrator perde a única coisa que você não consegue reconstruir.
EngenhariaColoque um portão determinístico na frente do seu revisor mais esperto
A pega-defeito mais barata é um script burro que checa se duas branches mergeadas ainda sobem antes de qualquer julgamento.