Evals em CI: o gate que passa no PR e falha em produção

Um agente de suporte passou a informar que a janela de reembolso era de 30 dias. A política dizia 14. A causa foi uma linha no system prompt, e o build passou verde, porque o pipeline confere sintaxe, tipos e testes de software, e nada disso lê o que o modelo responde. O primeiro a ver a resposta errada foi o cliente.
O caso abre um guia técnico publicado em 01/10/2026 por uma plataforma de agregação de modelos, e explica por que o gate de eval existe: transformar uma linha de prompt em um evento que quebra o pull request. O mecanismo tem quatro furos pequenos, todos de implementação, e cada um entrega o mesmo resultado por um caminho diferente: um check verde que não mediu nada.
O gate protege o prompt, não a rota. Ele compara o modelo com um conjunto fixo de casos, dentro de um ambiente que você controla, e para aí. A rota de produção, com o provider mais barato daquela semana, fica fora do gate até alguém medir.
O que um gate de evals em CI precisa ter antes de existir
Um gate de evals em CI é um job que roda um conjunto fixo de casos a cada mudança relevante e falha o pull request quando a taxa de aprovação cai abaixo de um limiar medido. Antes do workflow, existem três pré-requisitos: o conjunto de casos, a regra de pontuação com o limiar, e repetição suficiente para confiar na taxa.
Caso de teste com uma entrada e uma regra de aceitação, mais nada: a regra pode ser checagem de texto ou checagem do que o agente fez com a ferramenta; o que importa é que uma máquina a execute e que ela esteja no repositório, não na cabeça de quem revisa.
O conjunto fica no mesmo repositório do prompt e só muda por pull request revisado. Editado direto na branch principal, ele não protege nada: a próxima pessoa com pressa ajusta o caso em vez do agente. O guia começa com três casos e cresce por uma regra só, um caso novo para cada falha em produção. Para o conjunto inicial, a recomendação de 20 a 50 tarefas simples tiradas de falhas reais é da Anthropic. Comece pequeno.
O que medir já está mapeado em avaliação de agentes além da resposta final e métricas de avaliação de agentes no piloto. A pergunta aqui é outra: o que o pipeline faz com esse conjunto.
Pré-requisitos antes do primeiro furo
Três coisas precisam existir antes de qualquer workflow: repositório com CI em pull request, chave de API guardada como secret e permissão para editar a proteção da branch. Sem a terceira, o gate nasce sem poder de bloquear merge, e um gate que não bloqueia é relatório caro.
- Repositório com CI em pull request, para o eval ser um job.
- Chave como secret, com plano para o pull request de fork, que não recebe secret nenhum.
- Permissão nas regras de proteção da branch, porque é ali que o check vira obrigatório.
O terceiro item é o que mais desaparece da lista, porque costuma estar com outra pessoa. Sem ela, nada é obrigatório. Quem escreve o workflow raramente administra a proteção da branch, e o resultado é um gate que roda bonito e não bloqueia nada.
O runtime do agente sob teste só precisa ser chamável de um job. O Nexforce Code roda headless em automação e CI; o harness de eval é o seu script.
Furo 1: o filtro e o required check decidem se existe gate
O gatilho precisa ser filtro de caminho no nível do job, e o job precisa ser required status check na proteção da branch. Errar o primeiro produz check verde sem eval; errar o segundo produz eval vermelho que o botão de merge ignora.
Um filtro no nível do workflow parece econômico e é o pior arranjo: quando o caminho não casa, o GitHub não cria job nenhum, o required check fica pendente e o pull request nunca fica pronto para o merge. O eval que não roda vira uma trava permanente.
No nível do job o comportamento engana do outro jeito. Um job que não casa a condição não executa, e o GitHub o reporta como check aprovado. O merge passa, o eval não existiu, e o verde documenta apenas que a condição era falsa.
A lista de caminhos precisa incluir o próprio workflow e o próprio script de eval. Sem eles, um pull request que quebra a lógica de pontuação não dispara o eval, entra sem teste, e a regressão seguinte é atribuída ao modelo.
Falta o required check, que é onde a maioria para. Sem marcar o job como obrigatório, um eval vermelho aparece como X e o pull request continua mergeável, porque o GitHub informa e não bloqueia. Pior: se o job que decide se algo relevante mudou falhar, o GitHub pula o job de eval, e job pulado conta como aprovado. Por isso os dois checks são obrigatórios.
| Arranjo | O que o GitHub reporta | Efeito no merge |
|---|---|---|
Job de eval pulado por condição if | check aprovado | entra sem eval |
| Workflow pulado por filtro de caminho | required check pendente | merge travado |
| Eval vermelho sem required status check | X vermelho, sem bloqueio | entra mesmo assim |
| Job de filtro e job de eval marcados como required | pendente, verde ou vermelho com significado | espera o eval |
Concurrency com cancel-in-progress cancela a execução anterior quando alguém empurra de novo na mesma branch, e sem isso cada push paga um eval que ninguém lê. Pull request de fork não recebe secrets e falha por chave ausente: rodar o eval também no push para a branch principal cobre a lacuna.
Furo 2: sem provider fixado, você mede o roteador
O mesmo slug de modelo pode ser servido por providers diferentes em duas execuções, e a diferença aparece no relatório como regressão de prompt. Fixar um provider único na chamada do eval, sem fallback, mantém a rota constante para que a variável medida seja o prompt.
O slug identifica o modelo, não o lugar de onde ele respondeu. Dois endpoints com a mesma etiqueta devolvem respostas diferentes, e o relatório, que só conhece a etiqueta, registra a diferença como se o prompt tivesse piorado.
O resultado é o pior tipo de falso positivo: bloqueia um pull request correto e ensina o time a desconfiar do gate.
Na chamada do eval, um provider. E nenhum fallback. Na API da plataforma que publicou o guia, isso são uma ordem de providers e uma flag que desliga a substituição (provider.order e allow_fallbacks); campos daquela API, não padrão de mercado, e em outro gateway o equivalente prende a chamada a um endpoint só.
Fixar o provider fecha o endpoint e deixa a revisão aberta. O slug também não identifica qual build do modelo respondeu, então um build novo servido sob o mesmo slug e o mesmo provider reproduz exatamente o falso positivo deste furo, com a fixação já no lugar e nenhum campo do relatório para registrar a diferença. É limite do instrumento, não detalhe de configuração.
O limite fica escrito: fixar o provider dentro do eval é controle de medição, não cobertura de rota. Mantém a rota constante para que a diferença medida seja do prompt, e a rota de produção continua fora do gate até alguém medir a rota, com outro conjunto de casos. Avaliação de endpoint e política de roteamento trata desse lado: lá, limiar é o corte que decide para onde o request vai; aqui, limiar decide se o pull request entra.
Em produção, a rota é uma política: escolha de modelo por custo, latência e contexto, failover, teto de gasto por chave e traço por chamada. O Nexforce Router é onde essa política roda nos agentes que a empresa coloca em operação, e é por isso que o eval não pode confundir a política com o prompt. Quem escolhe modelo mede outra coisa, em três avaliações agênticas para escolher modelo.
Quem roda agente em produção troca de provider por preço no mesmo mês em que mexe no prompt, e o eval acusa regressão de prompt quando o que mudou foi a rota.
Furo 3: limiar escolhido no olho bloqueia ruído
Escolher o limiar no olho é o erro mais comum, porque o número parece razoável: um limiar alto soa como exigência séria. O mesmo conjunto, rodado seis vezes sem tocar em nada, não devolve a mesma taxa em todas as rodadas. O piso é a pior delas. Um piso baixo tem um reflexo errado e uma ordem certa. O reflexo é baixar o limiar. A ordem começa longe do número: a asserção, depois os parâmetros de determinismo, e por último a amostragem. O limiar é a última coisa que se mexe.
A primeira verificação é a própria regra de aceitação. Uma asserção que exige a palavra exata reprova toda vez que o modelo escreve o sinônimo, e o prompt não tem como impedir isso. A taxa cai, o piso cai, e o número no relatório mede a fragilidade do teste, não a qualidade da resposta. Baixar o limiar antes de olhar a asserção transforma essa fragilidade em política permanente: o caso que reprovava por asserção ruim passa a não poder reprovar nada, porque o limiar foi calibrado para acomodá-lo.
A segunda é o determinismo. temperature e seed só ajudam em modelos que declaram os dois em supported_parameters; enviá-los sem require_parameters: true faz o provider receber e ignorar os valores, o que é pior do que não enviar, porque produz sensação de controle. Há modelo que não declara nenhum dos dois.
A terceira é a amostragem, e o caminho que funciona em qualquer modelo é repetir a execução com voto de maioria. Custa mais e não depende do provider. O que a maioria compra é estabilidade contra ruído; o que ela entrega em troca é sensibilidade. Um caso que falha em minoria das amostras conta como aprovado, então um agente que piorou e passou a falhar em minoria delas continua verde, e só aparece quando a falha vira maioria. A regressão intermitente, a mais difícil de ver em produção, fica fora do relatório por construção.
Com as três verificações feitas, sobra medir: seis rodadas na mesma branch sem mudança, e o limiar não pode ficar acima do piso.
Com três casos e um deles instável em seis execuções, o piso é 0,67, e um limiar de 0,9 bloqueia um pull request sem regressão nenhuma. O problema não é o 0,9, é o tamanho. Com três casos a taxa só assume quatro valores, e um limiar no piso tem resolução de um caso: ele reprova quando dois casos quebram, não quando um quebra. Um caso pode piorar inteiro sem que o pull request pare. A resolução do gate é o inverso do tamanho do conjunto, e é ela que decide qual queda o pull request consegue enxergar.
A conclusão é crescer o conjunto, não conviver com o limiar frouxo. O guia tira a mesma conclusão e aponta a direção de 20 casos ou mais; a faixa de 20 a 50 tarefas simples tiradas de falhas reais, para o conjunto inicial, é a recomendação da Anthropic citada no começo. Conjunto pequeno com limiar rebaixado é a definição de gate de decoração.
Falta separar dois fracassos, e o script já os separa se você deixar. O primeiro código cobre "o agente piorou"; o segundo, "não deu para medir".
| Código de saída | Significado | Ação |
|---|---|---|
| 1 | taxa de aprovação abaixo do limiar | tratar como regressão de agente |
| 2 | o eval não pôde rodar | checar chave, provider e caso quebrado |
Se os dois pintam de vermelho igual, o time aprende a ignorar vermelho, e um gate ignorado custa mais caro do que nenhum.
Furo 4: o teste que pode ser afrouxado não é um teste
CODEOWNERS sozinho pede revisão, não bloqueia merge. Sem marcar a opção que exige aprovação do dono do código, o caminho mais barato para destravar um pull request vermelho é editar o caso que falhou, e o gate passa a proteger o merge em vez da produção.
Considere o incentivo antes da ferramenta. A pessoa tem um pull request vermelho às seis da tarde, o caso que falhou aponta para uma resposta que ela julga aceitável, e existe uma linha no conjunto que se ajusta em trinta segundos. Ajustar o prompt leva uma hora e mexe em algo que ela não escreveu.
Nesse arranjo, o conjunto de testes perde. Não por má-fé, por desenho.
A defesa é tratar o conjunto como código de produção. A proteção da branch é que exige a aprovação do dono do arquivo; sem essa marcação, o pedido de revisão é consultivo. Com ela, afrouxar o caso exige a assinatura de quem entende que aquela linha é o contrato do agente com o cliente. A edição fica no diff, e quem revisa vê a expectativa mudar de 14 dias para 30.
Como saber que o gate está funcionando
Na primeira mudança de prompt depois de instalar o gate, abra o log da execução e confirme que o eval rodou. Um padrão de caminho errado deixa o job verde sem executar caso nenhum, e a prova de que o gate existe está no log, não no check.
O check verde é a evidência mais fraca do sistema. Um teste de dez segundos que não chamou a API e um teste de quatro minutos que rodou o conjunto inteiro produzem o mesmo símbolo na tela.
Três verificações resolvem. Ler o log e encontrar a lista de casos com a taxa de aprovação; se o log só tem a mensagem de sucesso, o eval não rodou. Quebrar um caso de propósito e ver o pull request ficar vermelho. E confirmar o job de eval como pendente durante a execução, porque um check que nunca fica pendente não é obrigatório.
Vale repetir o teste a cada mudança no workflow. Filtro de caminho é o tipo de configuração que alguém ajusta numa sexta-feira para destravar um merge, e a mudança de prompt da semana seguinte já não dispara nada.
Quanto custa rodar isso
O custo é o número de casos multiplicado pelas amostras por caso e pela frequência de pull requests que mexem no prompt. O script imprime o custo de cada execução a partir do campo usage.cost, que é campo da API da plataforma que publicou o guia; em outro gateway ele não existe, e o custo sai de tokens multiplicados por preço. É esse número que decide se o gate cabe no orçamento. Sem ele, sobra fé.
A conta cresce linearmente com as amostras, e quem aumenta amostras para estabilizar a medição multiplica o custo pela mesma constante; a calibragem do limiar aparece na fatura, não no relógio do pipeline.
Um script com checagem de limiar basta sozinho. Plataformas de eval acrescentam relatório, histórico de execuções ou métricas prontas em cima do mesmo padrão de código de saída, e as citadas pelo guia são DeepEval, Braintrust, Arize e Galileo. A troca é decisão de operação, não de qualidade.
O que fazer na segunda-feira
Cinco passos, nesta ordem, cada um deixando um artefato no repositório: o conjunto de testes, o workflow com filtro no job e required check, o arquivo de donos, o limiar com as seis execuções registradas e o custo por execução impresso no log.
- Escreva três casos a partir de falhas reais do agente e commite no mesmo repositório do prompt. Artefato: o conjunto versionado.
- Crie o job de eval com filtro de caminho no nível do job, incluindo o próprio workflow e o próprio script na lista. Artefato: o workflow.
- Marque o job de filtro e o job de eval como required status checks na proteção da branch. Artefato: a regra de proteção, registrada no runbook.
- Rode o conjunto seis vezes contra a branch principal sem mudar nada, registre a pior taxa e configure o limiar abaixo dela. Piso baixo se corrige na asserção e na amostragem primeiro, e o conjunto cresce antes de o limiar descer. Artefato: o número documentado, com a data.
- Ligue o report de custo no log e revise o valor no primeiro mês. Artefato: o custo por execução.
O passo que as equipes pulam é o quarto, porque não produz nada visível e entrega um número que ninguém quer descobrir baixo. Nada na lista exige comprar algo, e os artefatos ficam no repositório ou no runbook. O checklist de plataforma de agentes em produção cobre o que vem depois: o gate é a primeira camada de medição.
Perguntas frequentes
Um eval em CI substitui teste unitário? Não. Teste unitário verifica o código que você escreveu; o eval verifica o comportamento do modelo diante de uma entrada. Os dois convivem no mesmo pipeline e falham por motivos diferentes: um aponta para uma função quebrada, o outro para uma resposta que mudou. O gate cobre a camada que o teste unitário não alcança: não verifica diretamente o seu código de orquestração; testa o que o agente responde e quais ferramentas ele chamou.
Preciso de uma plataforma de eval para começar? Não. Um script que roda os casos, aplica a regra de pontuação e sai com código diferente de zero abaixo do limiar resolve o problema do gate. Plataformas acrescentam relatório e histórico sobre o mesmo padrão de saída, e a troca se justifica quando o time precisa comparar execuções ao longo do tempo, não antes disso. O script resolve primeiro.
Como evitar que o gate deixe o pull request lento?
Filtro de caminho no nível do job, para o eval rodar só quando prompt, conjunto de testes ou o próprio gate mudam, e concurrency com cancel-in-progress para cancelar a execução anterior quando alguém empurra de novo na mesma branch. Amostragem repetida custa tempo, e a calibragem define quantas amostras são necessárias para não bloquear ruído. Gate lento é gate que o time aprende a contornar.
O eval falhou e o agente parece igual. O que fazer? Primeiro olhe o código de saída: se for o código de eval que não rodou, o problema é chave, provider ou caso quebrado, não qualidade. Se for o código de regressão, rode o conjunto na branch principal sem mudar nada e compare com o piso registrado. Diferença dentro do ruído é limiar alto, não agente pior. Compare os dois números antes de mexer no prompt.
Referências e Leitura Complementar
- Guia técnico sobre gate de pull request em evals de LLM, publicado em 01/10/2026 por uma plataforma de agregação de modelos (leitura em 21/10/2026).
- Recomendação de 20 a 50 tarefas simples em conjuntos iniciais: Anthropic, Demystifying evals for AI agents, citada pelo guia (leitura em 21/10/2026).
- Comportamento de check pendente e de job pulado: GitHub Docs, Skipping workflow runs e About protected branches (leitura em 21/10/2026).
- Avaliação de agentes além da resposta final
- Métricas de avaliação de agentes no piloto
- Avaliação de endpoint e política de roteamento
- Três avaliações agênticas para escolher modelo
- Checklist de plataforma de agentes em produção
O furo que fica depois do gate
O argumento aqui não é que o gate não serve. Ele serve, e serve barato, desde que seja um instrumento calibrado, com dono e limite de erro conhecidos.
O que ele não faz é olhar para a rota. A rota fica fora do relatório. Um agente em produção responde por uma política que muda de semana em semana, por preço, por latência ou por indisponibilidade do provider, e nenhuma dessas mudanças passa por um pull request.
A próxima medição, portanto, não é do prompt. É da rota: qual endpoint respondeu, com que latência, a que custo, e se a resposta que o cliente recebeu veio do modelo que a política prometia. Enquanto isso não estiver no mesmo relatório, o gate continua verde e a produção continua sendo o lugar onde a verdade aparece.

Implante Work e Code Agentssem nenhum custo de licença
Automatize tarefas operacionais e escrita de código com agentes autônomos integrados aos seus sistemas
Teste GrátisArtigos relacionados

Um milhão de skills de agente em sete meses, quase metade instalada uma vez
O relatório State of agent skills, da Vercel, registra 1 milhão de skills e quase 280 milhões de installs em sete meses, com quase metade do catálogo instalada uma única vez. A leitura corporativa é que install mede oferta, e o resultado de um agente depende de revisão, permissão e manutenção.
Read more
O benchmark de agentes de IA mostra que o harness muda o custo?
Um benchmark da Ora com o mesmo modelo em dois harnesses mostra 7% menos passos, 2x sucesso nativo e custo total cerca de 15% menor após corrigir cache de prompt. O que medir no custo do seu agente.
Read more
Agentes de IA em produção: checklist da plataforma
Antes de colocar agentes de IA em produção, sua plataforma precisa de 6 controles essenciais de execução, estado, sandbox, observabilidade e custos.
Read more