Benchmarks de IA ignoram 90% do trabalho: teste com Bun
Segundo a Mercor, 90% das horas trabalhadas nos Estados Unidos vão para tarefas que os benchmarks de IA não cobrem direito. Você já viu o gráfico da vez: um modelo novo bate recorde num teste qualquer e todo mundo comemora. Só que o teste mede um pedaço muito pequeno do que a gente faz no dia a dia. Este texto é sobre essa diferença entre benchmarks de IA e trabalho real, e sobre como usar o Bun para medir o que importa para você.
O que a Mercor mediu nos benchmarks de IA
A pesquisa saiu no Labor Index da Mercor. A ideia é simples de explicar: pegar as tarefas que as pessoas fazem no trabalho, ver quanto tempo elas tomam e checar quais benchmarks testam cada uma.
O resultado é desconfortável. A maior parte das horas de trabalho cai em tarefas que nenhum benchmark popular avalia bem. Os testes se concentram onde é fácil dar nota: questão de múltipla escolha, problema de matemática com resposta única, função isolada com teste unitário pronto.
O trabalho de verdade vive em outro lugar. Fica em reunião, em decisão com informação faltando, em ler código dos outros, em negociar escopo, em entender o que o cliente quis dizer quando escreveu "deixa mais moderno".
Isso não quer dizer que a IA não sirva para essas tarefas. Quer dizer que ninguém está medindo. São coisas bem diferentes.
Por que isso importa para quem programa
A gente se acha a exceção. Afinal, programação é a área mais coberta por benchmark que existe: SWE-bench, HumanEval, LiveCodeBench, Terminal-Bench e mais uma dúzia que surgiu no mês passado.
Só que pense na sua última semana. Quanto tempo você passou escrevendo código novo a partir de uma descrição clara? E quanto tempo foi:
- descobrindo por que o deploy funciona em staging e quebra em produção;
- lendo um PR de 40 arquivos e decidindo se aprova;
- migrando uma tabela do PostgreSQL sem derrubar nada;
- explicando para o produto por que aquela "mudança rápida" leva duas semanas.
Benchmark de código costuma testar a parte do trabalho que já vem com enunciado bem escrito. Na vida real, montar o enunciado é metade do serviço.
Tem também o problema da contaminação. Muito benchmark público acaba vazando para o treino dos modelos. Um modelo que vai bem num teste que já viu está decorando a prova, e você não sabe o quanto disso aconteceu.
Benchmark diz o que o modelo sabe fazer na prova. Seu backlog diz o que você precisa que ele faça.
O que muda no seu fluxo de trabalho
A conclusão prática não é "ignore os benchmarks". Eles servem como filtro grosso: um modelo que vai mal em todos provavelmente vai mal no seu projeto também.
A conclusão é outra: para decidir qual modelo usar no seu código, você precisa de um teste seu. Um eval pequeno, feito com tarefas reais do seu repositório, que você roda sempre que um modelo novo sai ou quando muda o prompt do seu agente.
Parece trabalho de time de pesquisa, mas não é. Se você tem um test runner, já tem 80% da infraestrutura. E aqui o Bun ajuda bastante: bun test sobe rápido, roda TypeScript sem configuração e tem Bun.spawn e Bun.file prontos para o resto.
Como montar um eval próprio com Bun
A estrutura que eu uso é bem simples. Cada caso é um JSON com o prompt e o arquivo de teste que o código gerado precisa passar.
{
"nome": "paginação por cursor no endpoint de pedidos",
"prompt": "Implemente paginação por cursor em listarPedidos(). Hoje usa OFFSET.",
"arquivo": "src/pedidos.ts",
"teste": "src/pedidos.test.ts"
}
O importante é que os casos venham do seu histórico. Pegue tarefas que você já resolveu de verdade: aquele bug de fuso horário, a refatoração do serviço de pagamento, a query que estava fazendo N+1. Você já tem a resposta certa e o teste que prova que funciona.
Depois, um arquivo de teste que percorre os casos, pede o código ao modelo, aplica numa cópia do projeto e roda os testes originais:
// evals/codigo.test.ts
import { test, expect } from "bun:test";
import { Glob, $ } from "bun";
import { gerarCodigo } from "./modelo";
const casos = await Array.fromAsync(new Glob("evals/casos/*.json").scan("."));
for (const caminho of casos) {
const caso = await Bun.file(caminho).json();
test(caso.nome, async () => {
const tmp = `/tmp/eval-${crypto.randomUUID()}`;
await $`cp -r fixture ${tmp}`;
const codigo = await gerarCodigo(caso.prompt, caso.arquivo);
await Bun.write(`${tmp}/${caso.arquivo}`, codigo);
const proc = Bun.spawn(["bun", "test", caso.teste], { cwd: tmp });
expect(await proc.exited).toBe(0);
}, 120_000);
}
O gerarCodigo é só um fetch para a API do modelo que você quer avaliar. Troque o modelo por variável de ambiente e rode:
MODELO=modelo-a bun test evals/
MODELO=modelo-b bun test evals/
No fim, você tem um placar do tipo "17 de 20 casos passaram" para cada modelo. Esse número vale mais para a sua decisão do que qualquer ranking público, porque saiu do seu código.
Algumas dicas que aprendi errando:
- Comece com 10 casos. Dez casos reais valem mais que cem inventados. Você expande depois.
- Rode cada caso mais de uma vez. Modelo não é determinístico. Se passa 2 de 3 vezes, anote isso.
- Isole o ambiente. Código gerado pode rodar
rmno lugar errado. Use diretório temporário, container ou sandbox. Não rode isso no seu repositório principal. - Guarde as saídas. Quando um caso falhar, você quer ler o que o modelo escreveu, não só ver um vermelho no terminal.
E as tarefas que não cabem num teste?
Essa é a objeção honesta, e é exatamente o ponto da pesquisa da Mercor. Revisar PR, desenhar arquitetura e decidir o que não fazer não viram um expect().toBe() facilmente.
Dá para chegar perto. Para revisão de código, monte casos com PRs antigos que tinham um bug conhecido e veja se o modelo aponta o problema. Para decisão de arquitetura, guarde o contexto de uma decisão que você já tomou e compare o raciocínio do modelo com o seu. Aqui a nota é manual mesmo: você lê e marca "ajudou", "não ajudou" ou "atrapalhou".
Dá trabalho? Dá. Mas é o mesmo tipo de trabalho que você teria para avaliar um dev júnior novo no time. Ninguém contrata alguém só porque a pessoa tirou nota alta numa prova de múltipla escolha. Bom, ninguém deveria.
Minha opinião sobre benchmarks de IA
Acho a pesquisa da Mercor mais útil que metade dos lançamentos de modelo deste ano, justamente porque ela não vende nada: só mostra onde a régua não chega.
A minha leitura é que a gente terceirizou a avaliação para quem tem interesse em mostrar número bonito. Quem lança o modelo escolhe o benchmark, e o benchmark escolhe a tarefa fácil de medir. Ninguém precisa mentir para o resultado sair distorcido.
A saída está ao alcance de qualquer dev: uma pasta evals/, vinte casos do seu histórico e um bun test. Leva uma tarde para montar e economiza meses de "acho que esse modelo é melhor". Se quiser ver como eu aplico isso em projetos de verdade, dá uma olhada nos meus projetos.
Resumo para o LinkedIn
Segundo a Mercor, 90% das horas de trabalho caem em tarefas que nenhum benchmark de IA mede direito. Os testes ficam onde é fácil dar nota: múltipla escolha, matemática com resposta única, função isolada. Mas o meu dia real é ler PR de 40 arquivos, migrar tabela sem derrubar nada e entender o que o cliente quis dizer com "deixa mais moderno". Por isso parei de escolher modelo pelo ranking da semana. Montei uma pasta evals/ com 20 tarefas que já resolvi de verdade e rodo tudo com bun test. "17 de 20 passaram" no meu código vale mais que qualquer gráfico de lançamento. Escrevi no blog como montar o seu em uma tarde. Quem já faz algo parecido, me conta como mede. #InteligenciaArtificial #Bun #DesenvolvimentoDeSoftware #LLM #TypeScript