A pirâmide de validação AI

TL;DR

Nenhuma camada sozinha protege contra os 45% de código inseguro e supply chain attacks. A solução é defesa em profundidade estruturada como pirâmide: na base, automação massiva (linters, type checkers, SAST escalando para milhares de PRs); no meio, guardrails determinísticos (12 - Guardrails determinísticos) que param classes de ataque conhecidas; no topo, human oversight focado nos poucos casos que merecem revisão humana profunda. Triângulo invertido onde tem o problema.

A pirâmide

graph TD
    A["🔴 Human oversight<br/>(1-5% dos casos)"] --> B["🟡 Deterministic guardrails<br/>(blocking checks)"]
    B --> C["🟢 Automation<br/>(linters, SAST, tests)"]
    C --> D["⚪ Generation<br/>(LLM gerando código)"]

Fluxo: geração → automação → guardrails → humano. Cada camada filtra. Humano só vê o que precisa de julgamento real.

Por que pirâmide e não checklist

A tentação é “escrever uma lista grande de coisas pra revisar”. Falha porque:

  • Volume gerado por IA esmaga revisão linear
  • Humano fadiga em casos rotineiros, deixa passar casos sérios
  • Custo escala linearmente com volume → caro
  • Cada camada está fazendo o trabalho errado

Pirâmide é especialização por camada: máquina faz o que máquina faz bem; humano faz o que humano faz bem.

Camada 1 — Automação (90-95% do trabalho)

A base larga. Roda em todo PR, em todo commit, sem exceção.

FerramentaPega
Type checker (mypy, tsc)Métodos/tipos inexistentes (03 - Alucinações em código — APIs fantasma e parâmetros inexistentes)
Linter (ruff, eslint)Padrões de código, dead code, antipatterns
SAST (Snyk, Semgrep, CodeQL)OWASP-grade vulns (05 - SAST e SCA para código AI)
SCA (Snyk, Socket.dev)Slopsquat, dep vulneráveis (02 - Slopsquatting — o ataque via alucinação)
Test suiteComportamento (09 - Testes imutáveis — a barreira que o agente não pode reescrever)
Format checkEstilo

Critério de qualidade: todas estas DEVEM bloquear PR se falharem. Não devem ser warnings ignorados.

Camada 2 — Guardrails determinísticos (4-9%)

Quando automação genérica não basta — regras específicas do projeto:

GuardrailExemplo
Schema validationOutput do LLM tem extra="forbid" em Pydantic
Permission boundariesAgente não pode chamar tools fora do allowlist (06 - Permissões e sandboxing)
Rate limitsLLM não faz >N tool calls por turno
Sensitive operation gatingMudanças em DB de prod requerem human approval
Output format enforcementJSON mode, structured outputs
Domain-specific rules”Nenhuma string SQL concatenada com user input”
Hallucination checkPacotes verificados em registry oficial antes de install

Ver 12 - Guardrails determinísticos para fundamento.

Critério: regras codificáveis. Se você consegue escrever a regra, escreva a regra. Não delegue julgamento determinístico para LLM.

Camada 3 — Human oversight (1-5%)

Para o que sobrou: julgamento real.

O que humano faz bem:

  • Revisão de arquitetura (decisões com trade-offs ambíguos)
  • Avaliação de mudanças cross-cutting (security policy, auth)
  • Verificação de intent (o código atende ao “porquê” da feature?)
  • Aprovação de operações destrutivas (drop table, force push)
  • Escalação de incidentes detectados pelas camadas inferiores

O que humano NÃO faz bem (deixe para máquina):

  • Detectar XSS em template
  • Achar SQL injection escondido
  • Verificar 50 linhas de imports
  • Confirmar que typescript types batem
  • Checar que pacote npm existe

Review fatigue mata

Time que aprova 100 PRs/semana não revisa o de número 47. Camadas 1 e 2 existem para que a camada 3 só receba 5 PRs/semana que realmente precisam de olhar humano.

Anatomia do pipeline ideal

# .github/workflows/ai-code-validation.yml
on: [pull_request]
 
jobs:
  layer1-automation:
    steps:
      - name: Type check (BLOCK)
        run: mypy src/
      - name: Lint (BLOCK)
        run: ruff check src/
      - name: SAST (BLOCK)
        run: semgrep --config=auto --error
      - name: SCA (BLOCK)
        run: snyk test --severity-threshold=high
      - name: Test suite (BLOCK)
        run: pytest
      - name: Coverage (BLOCK if < 80%)
        run: pytest-cov --fail-under=80
 
  layer2-guardrails:
    needs: layer1-automation
    steps:
      - name: Schema validation
        run: ./scripts/check-schemas.sh
      - name: Permission boundary check
        run: ./scripts/check-tool-allowlist.sh
      - name: Sensitive ops gate
        if: contains(github.event.pull_request.changed_files, 'migrations/')
        run: echo "::warning::DB migration detected - human approval required"
 
  layer3-routing:
    needs: layer2-guardrails
    steps:
      - name: Auto-route review
        run: ./scripts/route-review.sh
        # Sensitive PR → senior + security-reviewer
        # Routine PR → any reviewer

Implementação progressiva

Não tente tudo de uma vez. Roadmap típico (ver também 12 - O roadmap de segurança para times):

SemanaAdiciona
1Type check + linter (bloqueando)
2Test suite obrigatório + coverage threshold
3SAST básico (Semgrep config=auto)
4SCA (Snyk ou Socket.dev)
5-6Schema validation em boundaries
7-8Permission boundaries para agentes
9-10Routing inteligente de review humano
11-12Métricas e ajuste fino

Quando uma camada falha

FalhaSintomaFix
Camada 1 lentaCI demora >15 min, time pula validaçãoOtimize, paralelize, incremental
Camada 1 com falsos positivosTime desativa ruleCalibre rules, suppress com comentário
Camada 2 muito rígidaBloqueio em casos legítimosRefine regras com base em casos reais
Camada 2 muito frouxaIssues passamAdicione regra específica para o pattern
Camada 3 fadigadaReviews superficiaisAumente camadas 1 e 2 para reduzir volume

Métricas da pirâmide

MétricaAlvoSignificado
% PRs bloqueados em camada 130-50%Sinal saudável — automação funciona
% PRs bloqueados em camada 25-15%Guardrails calibrados
% PRs revisados manualmente<10%Humano focado
Tempo médio CI total<15 minNão sufoca produtividade
Defect escape rate<5%Issues que chegam em prod
% issues detectados em prod (não em CI)<10%Pirâmide está pegando

Anti-patterns

  • “Vamos só fazer review humano com mais cuidado” — não escala com volume IA
  • SAST como warning, não erro — vira ruído
  • Camada 2 por LLM (“AI critic”) — contraditório; quem valida o validador?
  • Pular camada 1 “para mover rápido” — produção paga depois
  • Métricas só em camada 3 — perde sinal das anteriores
  • Single-vendor SAST — Veracode mostra: 78% dos issues só pegos por uma das ferramentas; rode 2+
  • Coverage % como proxy de qualidade — teste que roda sem assert de verdade infla o número sem pegar regressão nenhuma; a métrica vira meta, não sinal (efeito Goodhart clássico)
  • Guardrails da camada 2 vivendo soltos em scripts sem review — regra de negócio codificada num shell script isolado, sem changelog nem dono, sofre drift silencioso: ninguém percebe quando ela para de cobrir o caso que deveria bloquear

Armadilhas comuns

Camada 1 lenta vira camada ignorada

CI que demora 20 minutos leva desenvolvedores a abrir PRs sem esperar o resultado, ou a pular validações locais “para ganhar tempo”. O sinal de alerta é quando o time começa a fazer merge antes do CI terminar. Se a camada 1 fica lenta, paralelize as etapas, use cache agressivo de dependências, e separe checks rápidos (linter, type check) dos lentos (testes de integração) em jobs distintos.

Usar LLM como validador da camada 2 é circular

Alguns times tentam usar um “AI critic” para revisar o output de outro LLM como guardrail da camada 2. O problema: o validador tem os mesmos pontos cegos que o gerador, pode ser iludido pelas mesmas construções plausíveis, e não tem garantia determinística. Guardrails da camada 2 precisam ser regras codificáveis com resultado binário — não “o outro LLM achou OK”.

SAST único vendor garante cobertura falsa

O relatório Veracode mostra que 78% das vulnerabilidades são detectadas por apenas uma das ferramentas SAST testadas. Rodar só Semgrep ou só CodeQL deixa classes inteiras de problema sem cobertura. A pirâmide precisa de pelo menos dois scanners na camada 1, complementares em cobertura.

Como explicar em inglês

The validation pyramid for AI-generated code solves a fundamental throughput problem: a human reviewer cannot keep pace with the volume that an LLM-assisted team produces. The pyramid structures validation so that the high-volume, codifiable checks happen automatically — type checking, linting, SAST, SCA — and only the edge cases that genuinely require judgment reach a human reviewer.

The key insight is specialization by layer. Machines are better than humans at consistently catching XSS patterns, missing type declarations, and vulnerable dependency versions — tasks that are repetitive, well-defined, and don’t benefit from context. Humans are better at evaluating architectural trade-offs, security implications of cross-cutting changes, and intent alignment. Mixing those responsibilities in a single flat checklist wastes human capacity on mechanical tasks and exhausts reviewers before they reach the decisions that matter.

A well-implemented pyramid means that 90-95% of issues are caught before a human sees the PR, and the human reviewer spends their time on the 5-10% where their judgment creates real value.

In a technical interview, you might say:

“We structure AI code validation as a three-layer pyramid. The base is full automation — type checker, linter, SAST with two complementary scanners, SCA for dependency safety, and a test suite — all as hard blocks in CI. The middle layer is deterministic guardrails specific to our domain: schema validation with extra=forbid, tool allowlists for agents, and human approval gates for destructive operations. The top is human review, but only for the PRs that actually need judgment — architecture decisions, cross-cutting security changes, intent verification. This way our reviewers see maybe 5-10% of PRs, but those are the ones where human judgment matters.”

PTEN
defesa em profundidadedefense in depth
pirâmide de validaçãovalidation pyramid
automação de basebase automation layer
guardrail determinísticodeterministic guardrail
revisão humanahuman oversight
taxa de escape de defeitosdefect escape rate
fadiga de revisãoreview fatigue
roteamento de revisãoreview routing
validação em camadaslayered validation
pipeline de CICI pipeline

O que vem a seguir

A pirâmide define a estrutura. A camada 1 — automação — é a mais larga e a mais crítica para escalar. Mas ferramentas SAST e SCA genéricas não foram projetadas para código gerado por IA: elas não sabem distinguir padrões que humanos evitariam mas que LLMs reproduzem sistematicamente, e precisam de ajuste para lidar com o volume e os padrões específicos desse fluxo.

A próxima nota detalha como calibrar SAST e SCA especificamente para código AI, incluindo quais regras ativar, quais ferramentas combinar, e como evitar que falsos positivos tornem a camada ineficaz.

Veja também

Referências