CI/CD + eval gates
Uma regressão detectada depois do deploy custa mais que a mesma regressão bloqueada antes da publicação. CI/CD transforma verificações e empacotamento em um processo repetível, mas um pipeline verde só representa os critérios que ele realmente executou. Um teste que roda apenas lint não demonstra qualidade do agente; um eval sem dados congelados pode produzir uma falsa sensação de proteção.
Nesta aula vamos criar um gate de testes e avaliação que controla a promoção de um artefato versionado. Prompt, agente, modelo, provedor, documentos e avaliadores precisam de identidade rastreável. Retomaremos os casos das semanas 36–37 e as credenciais por ambiente da semana 42. A entrega deve falhar automaticamente quando existe regressão e preservar evidência suficiente para revisar a decisão.
JavaScriptAgentesAvaliaçãoInfraestruturaAo terminar esta aula
- Gate precisa rejeitar regressão e falta de evidência.
- Versão inclui prompt, modelo, dados, ferramenta e avaliador.
- O artefato publicado deve ser o artefato aprovado.
Antes de continuar: Laboratório: Queues/Workers/async agents
CI/CD: verificar, construir e promover o mesmo artefato
InfraestruturaContinuous integration executa verificações quando mudanças entram no fluxo do repositório. Continuous delivery prepara uma versão publicável de forma repetível; deployment automático é uma escolha adicional de política. Separe jobs de teste, avaliação, build e promoção. Um job posterior deve depender do sucesso do anterior, em vez de reconstruir silenciosamente um artefato diferente depois de avaliar o primeiro. A versão implantada precisa ser a que recebeu aprovação.
GitHub Actions organiza workflows, eventos, jobs e steps. Para um projeto Node, uma sequência local reproduzível é instalar pelo lockfile, executar testes determinísticos, rodar o gate e construir o pacote. Declare permissões mínimas por job e não forneça credenciais de produção a toda execução de pull request. O pipeline também pode falhar por infraestrutura do runner; preserve logs e classifique a causa. Reexecutar uma falha sem entender se é teste ou ambiente pode esconder flakiness relevante.
Test gates e eval gates não medem a mesma coisa
AvaliaçãoTestes determinísticos verificam esquemas, autorização, idempotência e funções com resultado definido. Evals verificam comportamento do agente em casos e rubricas, frequentemente com variabilidade. Ambos são necessários: um modelo que escolhe o pedido errado exige avaliação de comportamento, e um backend que aceita outro tenant exige teste de autorização. Defina regras de bloqueio para falhas críticas, piso de conclusão e perdas por categoria. Não deixe a média compensar uma violação de permissão.
Uma avaliação com modelo real deve ter dataset, parâmetros e versão do avaliador registrados. Decida como lidar com falhas externas e resultados inconclusivos: rerun limitado, revisão ou bloqueio. Reduzir toda incerteza a “pass” cria publicação sem evidência. Para CI rápida, um conjunto pequeno pode fornecer sinais, mas preserve uma rodada mais abrangente para promoção. Os tamanhos e limiares do laboratório são escolhas didáticas, não uma garantia estatística de ausência de regressão.
Versionamento de prompts e agentes
AgentesUm prompt é parte do comportamento do sistema e deve ter versão ou hash de conteúdo. O agente também inclui código, ferramentas, parâmetros, instruções e política de recuperação. Versionar apenas o arquivo principal não permite reproduzir a execução se a rubrica, documento ou ferramenta mudou. Crie um manifesto que relacione commit, promptHash, datasetHash, evaluatorVersion, schemaVersion e dependenciesLockHash. O manifesto acompanha o artefato e o relatório de avaliação.
MLflow oferece recursos de rastreamento de versões e registro de prompts, mas a disciplina de identidade pode começar em arquivos no repositório. Um alias como production é uma referência mutável, não a versão imutável que foi avaliada. Resolva o alias e registre o identificador concreto no momento da execução. Não atualize um prompt remoto com o mesmo nome depois do gate sem gerar nova versão e nova avaliação. Mudanças pequenas de texto podem alterar chamadas de ferramenta ou comportamento de recusa.
Modelo, provedor e dependências também fazem parte da versão
FundamentosUm nome de modelo pode representar uma versão estável ou um alias que evolui conforme o provedor. Registre o identificador usado, data do experimento e metadados retornados quando disponíveis. Quando existir versão fixável, avalie o trade-off entre estabilidade e atualização. Uma mudança de provedor também pode alterar limites, esquema de uso, streaming e política de dados, mesmo mantendo um formato semelhante de API.
↗ Model selection↗ ML Model Registry↗ Version Tracking for Agents and LLMs
O manifesto não torna um serviço externo perfeitamente reproduzível: infraestrutura e comportamento podem mudar. Ele reduz ambiguidade e permite investigar diferenças. Inclua versões de SDK, lockfile, imagem e migrações. Se o gate utiliza juiz LLM, o juiz também precisa de identidade. Atualizar o avaliador junto com a candidata dificulta distinguir melhora do agente de mudança da régua. Quando isso for necessário, calibre a nova régua em casos independentes e mantenha resultados comparáveis ou documente a quebra de série.
↗ Model selection↗ ML Model Registry↗ Version Tracking for Agents and LLMs
Secrets no pipeline e evidência revisável
FundamentosCredenciais de avaliação e implantação devem ser separadas e restritas ao ambiente e ao job que precisa delas. Segredos não devem entrar em artefatos, fixtures ou logs. Mascaramento de logs ajuda, mas não detecta todas as transformações e exposições. Defina permissões mínimas e não execute código não confiável com credenciais amplas. Um workflow que imprime todo o ambiente para depurar pode divulgar dados que nunca deveriam fazer parte do relatório.
↗ Using secrets in GitHub Actions↗ Manage secrets securely in Docker Compose
O relatório do gate deve informar versão, número de casos, falhas críticas, contagens por categoria e motivo de aprovação. Anexe outputs sanitizados e hashes, não chaves. Se o conjunto estiver indisponível ou contiver IDs ausentes, falhe com razão explícita; não aceite um total zero como taxa perfeita. A publicação é uma decisão derivada da evidência e do contrato. A semana seguinte usará o mesmo artefato para canary e rollback, preservando a relação entre avaliação e operação.
↗ Using secrets in GitHub Actions↗ Manage secrets securely in Docker Compose
Gate que falha com regressão e com relatório incompleto
FundamentosSalve gate.cjs. A fixture avalia três casos pareados e falha por uma perda crítica. Execute node gate.cjs e observe código de saída um; depois corrija o caso de autorização para observar saída zero. Esse código é o comando que um job de CI pode executar, sem depender de um SDK ou credencial.
const assert=require('node:assert/strict');
function gate(rows,expectedIds){
const ids=rows.map(r=>r.id);
if(new Set(ids).size!==ids.length || ids.length!==expectedIds.length ||
expectedIds.some(id=>!ids.includes(id))) return {pass:false,reason:'incomplete'};
const critical=rows.filter(r=>r.critical && !r.candidate);
const regressions=rows.filter(r=>r.baseline && !r.candidate);
return {pass:critical.length===0 && regressions.length===0,
reason:critical.length?'critical':regressions.length?'regression':'ok'};
}
const rows=[
{id:'common',baseline:true,candidate:true,critical:false},
{id:'auth',baseline:true,candidate:false,critical:true},
{id:'abstain',baseline:true,candidate:true,critical:false}
];
assert.equal(gate([],['common']).pass,false);
assert.equal(gate([...rows,rows[0]],rows.map(r=>r.id)).reason,'incomplete');
const result=gate(rows,['common','auth','abstain']);
console.log(JSON.stringify(result));
process.exitCode=result.pass?0:1;A saída de processo conecta a avaliação ao pipeline: um comando com exit code um deve impedir promoção quando o job depende dele. O gate rejeita vazio e duplicatas, evitando um sucesso aparente com captura incompleta. A regra “nenhuma perda” é deliberadamente estrita para a fixture; produtos podem usar limites diferentes, desde que definidos antes e sem flexibilizar requisitos críticos.
Exercício aplicado
O pipeline aprova uma candidata com zero casos porque a API de avaliação falhou, e o deploy resolve um alias de prompt atualizado depois do gate. Corrija as duas fronteiras.
- Exija todos os IDs esperados e resultado não vazio.
- Trate falha de avaliação como erro ou inconclusivo bloqueante.
- Registre prompt imutável no manifesto.
- Promova o mesmo artefato que foi avaliado.
Abrir resolução comentada
Um conjunto vazio não fornece evidência e deve bloquear. O gate valida completude antes de calcular qualquer score. A indisponibilidade externa não equivale a aprovação.
O alias mutável permite mudar o comportamento depois da avaliação. Resolva e fixe a versão concreta no artefato; uma atualização exige novo gate. A integridade entre relatório, manifesto e pacote torna a decisão revisável.
const assert=require('node:assert/strict');
function gate(rows,expectedIds){
const ids=rows.map(r=>r.id);
if(new Set(ids).size!==ids.length || ids.length!==expectedIds.length ||
expectedIds.some(id=>!ids.includes(id))) return {pass:false,reason:'incomplete'};
const critical=rows.filter(r=>r.critical && !r.candidate);
const regressions=rows.filter(r=>r.baseline && !r.candidate);
return {pass:critical.length===0 && regressions.length===0,
reason:critical.length?'critical':regressions.length?'regression':'ok'};
}
const rows=[
{id:'common',baseline:true,candidate:true,critical:false},
{id:'auth',baseline:true,candidate:false,critical:true},
{id:'abstain',baseline:true,candidate:true,critical:false}
];
assert.equal(gate([],['common']).pass,false);
assert.equal(gate([...rows,rows[0]],rows.map(r=>r.id)).reason,'incomplete');
const result=gate(rows,['common','auth','abstain']);
console.log(JSON.stringify(result));
process.exitCode=result.pass?0:1;Como conferir seu resultado
- Regressão crítica retorna exit code não zero.
- Dataset vazio ou incompleto bloqueia.
- Manifesto liga prompt, agente, dados e avaliador.
- Build depende do gate e preserva o artefato aprovado.
Aplique em um problema novo
Primeiro resolva sem consultar a resposta. Explique suas decisões e guarde a evidência. A conclusão de leitura é independente desta autoavaliação.
Confira seus pré-requisitos
- Ligar manifesto e artefato avaliado.
- Definir gate com completude/criticidade.
Gate recebeu zero casos; build usou promptHash H2, relatório H1. API está indisponível. Decida publicação.
Conferir raciocínio e critérios de domínio
Hash divergente quebra identidade do artefato; versão H2 exige avaliação própria.
Zero casos é ausência de evidência, não score perfeito.
Bloquear promoção com motivo; retries limitados/revisão não transformam indisponibilidade em pass.
Evidências para autoavaliação ou revisão por pares
- Integridade: Hash divergente quebra identidade do artefato; versão H2 exige avaliação própria.
- Completude: Zero casos é ausência de evidência, não score perfeito.
- Promoção: Bloquear promoção com motivo; retries limitados/revisão não transformam indisponibilidade em pass.
Um erro frequente
Alias production é versão imutável.
Alias é referência mutável; registrar versão concreta avaliada.
Teste sua compreensão
Responda com suas palavras antes de abrir o comentário. Saber explicar uma decisão é parte do domínio.
1. Um alias identifica uma versão imutável?
2. Falha de API de avaliação pode virar pass?
Não.
Sem evidência, o gate precisa bloquear ou exigir revisão.
3. Por que separar teste e eval?
Porque verificam contratos diferentes.
Autorização de backend é determinística; comportamento de modelo pode ser variável.
Seu progresso fica salvo neste navegador. Concluir a leitura não substitui demonstrar o domínio nos exercícios.
Referências e aprofundamento
Documentação oficial e trabalhos originais. As referências registram o escopo e as limitações para você conferir o que sustentam.
- Understanding GitHub Actions
GitHub • consulta: 2026-10-06
FundamentosWorkflows, eventos, jobs, steps, dependências e build/test/deploy automatizados.
Limites: Gates de eval são política da aplicação implementada em scripts e limiares, não garantia nativa de qualidade.
- Evaluation best practices
OpenAI • consulta: 2026-10-06
OpenAIDatasets representativos, casos difíceis, avaliação contínua, rubricas, comparação pareada, sucesso de ferramentas e tarefas.
Limites: Juízes LLM têm viés de posição e extensão; calibrar com avaliações humanas. Um score não garante verdade factual.
- Version Tracking for Agents and LLMs
MLflow • consulta: 2026-10-06
AgentesIA & MLVersionamento e rastreamento de aplicações de agentes e sua associação a traces e avaliações.
Limites: Versionar código/configuração não congela comportamento de aliases de provedores externos.
- Prompt Registry
MLflow • consulta: 2026-10-06
FundamentosRegistro, versões e aliases de prompts e associação ao ciclo de avaliação.
Limites: Aliases são mutáveis; registrar versão concreta para comparação e reprodução.
- Using secrets in GitHub Actions
GitHub • consulta: 2026-10-06
FundamentosSecrets por repositório, ambiente e organização e seu uso em workflows.
Limites: Disponibilidade e acesso variam por evento e configuração; não imprimir segredos.
- Manage secrets securely in Docker Compose
Docker • consulta: 2026-10-06
DockerSecrets montados em arquivos e concessão explícita por serviço.
Limites: O arquivo de origem também precisa de proteção; suporte apresentado para Linux containers.
- ML Model Registry
MLflow • consulta: 2026-10-06
IA & MLRegistro central de modelos, versões, aliases e rastreamento de ciclo de vida.
Limites: Registro organiza artefatos; permissões, implantação e políticas precisam de configuração.
- Model selection
OpenAI • consulta: 2026-10-06
OpenAIEscolha e iteração de modelos usando qualidade, custo e latência com evals.
Limites: Nomes, disponibilidade e tarifas mudam; o curso deve usar experimentos e critérios, não ranking fixo.