Iteração com IA não é “até parecer certo.” É ciclo estruturado de refinamento.
TL;DR
- Especificação é iterativa — a primeira versão da spec é sempre incompleta; o refinamento durante a construção descobre lacunas que a spec estática não enxerga, e a qualidade final sobe a cada iteração.
- Rejeição é ferramenta — cancelar uma sugestão sem refinar é desperdiçar o ciclo; rejeitar com critério é alimentar a próxima iteração com sinal de alta qualidade.
- Alternativas precisam ser exploradas — a primeira sugestão raramente é a melhor; pedir duas ou três variações com critérios diferentes antes de decidir é o que separa decisão técnica de aceitação preguiçosa.
- Integração é a validação real — código que compila isolado pode falhar no sistema; a iteração que termina em merge direto, sem passar por integração com tráfego real, não terminou.
- Documentação durante a iteração — registrar Architecture Decision Records enquanto se itera fixa a memória do time; registrar depois do merge é descrever o que ninguém lembra com precisão.
Especificação é iterativa, não estática
A primeira especificação entregue à IA generativa é sempre incompleta. Não é falha de quem escreveu. É propriedade do processo. A compreensão completa do problema emerge durante a construção, e a especificação só alcança o problema real depois de uma ou duas voltas no ciclo prompt → geração → revisão.
O ciclo operacional tem cinco etapas sequenciais:
- Escrever spec inicial — o que está sendo construído, em que contexto, com quais restrições não-negociáveis; a spec não precisa ser completa na primeira passada.
- Enviar prompt e receber sugestão — entrega o que a IA pode fazer com o contexto disponível; tratar a resposta como primeira aproximação, não como solução.
- Revisar o resultado — ler linha a linha, comparar com a spec, identificar o que foi entendido e o que foi ignorado.
- Descobrir lacunas — registrar tudo que apareceu na revisão e que não estava na spec: edge cases, restrições implícitas, integrações assumidas, semântica de erro.
- Refinar spec e repetir — incorporar as lacunas, reenviar, ler de novo, até que a sugestão carregue a complexidade do problema real.
A métrica empírica observada em sessões de code review assistido por LLM é direta: duas a três iterações de especificação produzem código de qualidade uma ordem de grandeza superior ao código gerado com especificação única. A diferença não está na IA, está no segundo e terceiro refinamento da spec.
A leitura errada do ciclo é tratar a incompletude inicial como fracasso. A leitura correta é tratar como evidência: o problema real era mais complexo do que a primeira descrição capturava, e a iteração é o método que descobre essa complexidade. Quem tenta escrever a spec perfeita antes de enviar o primeiro prompt não está sendo disciplinado. Está adiando o trabalho de descobrir o que não sabe.
Rejeição é ferramenta válida
Vibe code aceita a primeira sugestão. Desenvolvimento rigoroso rejeita quando a sugestão não resolve o problema. Rejeição não é derrota. É o sinal de alta qualidade que alimenta a próxima iteração do ciclo.
Os cinco critérios de rejeição são técnicos, não estilísticos:
- Spec não foi entendida — a sugestão ignora uma restrição explícita da spec; nesse caso, o problema é a spec (reformular) ou a leitura (refazer).
- Alternativa não foi considerada — a primeira abordagem não é a única viável; pedir outra abordagem enriquece a decisão.
- Teste falha — código que não passa em teste de unidade ou de integração não está pronto, independente de quão elegante pareça.
- Performance é inaceitável — a sugestão resolve o problema mas com custo operacional que o sistema não absorve; nesse caso, refinar a direção, não a estética.
- Código é incompreensível — se o revisor humano não consegue explicar a sugestão em três frases, o código está no caminho errado.
A frase de rejeição tem forma fixa e conteúdo variável: “Isso não resolve porque [razão específica]. Tente outra abordagem que [direção].” A razão é específica — não “não gostei”, não “tem algo estranho”, não “quase”. A direção indica o eixo que precisa mudar — complexidade, modelo de dados, contrato de interface, estratégia de teste. Sem a direção, a IA refina a mesma abordagem; com ela, a próxima iteração tem sinal utilizável.
Rejeição sistemática reduz o tempo médio para a iteração útil em sistemas onde a IA generativa é usada em fluxo contínuo. A métrica oposta — taxa de aceitação de primeira sugestão — correlaciona negativamente com qualidade final observada em code review. A intuição de que aceitar rápido é produtivo está invertida. Aceitar rápido é abdicar da custódia técnica que o nome “pair” prometia e que a máquina, por definição, não exerce.
Alternativas devem ser exploradas
A primeira sugestão de IA generativa não é a melhor sugestão. É a sugestão mais provável dado o prompt recebido, e probabilidade alta não é sinônimo de qualidade alta. A prática que separa aceitação preguiçosa de decisão técnica é solicitar, para problemas não-triviais, duas a três alternativas com critérios de variação explícitos.
O protocolo de exploração tem três passos:
- Pedir opção A com critério padrão — o que a IA entrega sem instrução adicional; documentar suposição e limitação.
- Rejeitar e pedir opção B com critério diferente — variar o eixo: prioridade de legibilidade sobre performance, ou cobertura de edge cases sobre simplicidade, ou composição sobre abstração.
- Rejeitar e pedir opção C com foco oposto a B — forçar a IA a explorar direção que a opção B ignorou; a divergência entre B e C é onde aparece a decisão técnica real.
A diferença de qualidade entre opção A e opção C é geralmente significativa. Não porque a IA melhore a cada iteração — a qualidade estatística da predição não muda. A diferença está no espaço de busca coberto: três iterações com critérios diferentes cobrem três regiões do espaço de solução; uma iteração cobre uma. Em problemas com mais de uma dimensão de trade-off, explorar mais de uma região é o que permite comparar antes de decidir.
A armadilha é pedir a opção B sem critério explícito. A IA então produz uma variação cosmética da opção A, e a “exploração” vira confirmação da primeira escolha com trabalho extra. O critério de variação precisa ser declarado no prompt: “Tente com ênfase em performance, ignorando cobertura de edge cases” produz resultado diferente de “tente uma versão mais simples”. Sem critério declarado, a variação é aleatória, e aleatoriedade não é exploração.
Integração é validação real
Código correto isoladamente pode ser incorreto no sistema. A iteração que termina no editor local — sem rodar contra a base de código real, sem passar pela suíte de testes de integração, sem trafegar contra dados de produção sintéticos — não terminou. Está em estado intermediário, e estado intermediário é onde mora a maioria dos bugs que chegam a produção.
O ciclo de integração tem quatro estágios:
- Compilar e rodar testes de unidade — verifica a correção local; não verifica comportamento sistêmico.
- Integrar com a base e rodar testes de integração — verifica contrato de interface, ordem de chamadas, efeito colateral sobre dados adjacentes.
- Subir para staging com tráfego sintético ou shadow — verifica comportamento sob volume, latência e padrões de uso realistas.
- Deploy canário em produção com observability ativa — verifica comportamento sob carga real, com rollback reversível em minutos.
A prática que mata iteração estruturada é pular o segundo estágio e ir direto de “passou no ambiente local” para merge. O atalho economiza horas na primeira semana e custa semanas quando o bug aparece em produção três semanas depois, em horário de pico, com fila de pedidos pendentes. Caso de campo em sistema de pagamento: três sugestões consecutivas de IA foram aceitas sem contestação ao longo de uma semana, e o sistema entrou em produção com race condition em path de cancelamento. O sintoma apareceu em horário de pico, e o post-mortem listou a ausência de revisão contestatória e de integração real como fatores contribuintes.
A iteração estruturada termina em merge apenas depois que o código rodou no sistema. Não no editor. Não na branch. No sistema, com dados, com tráfego, com monitoração ligada. Esse é o critério que separa iteração real de iteração aparente.
Documentação é iteração de compreensão
A memória do time sobre por que uma decisão foi tomada se degrada em ritmo incompatível com a velocidade de iteração assistida por IA. Em ciclo de dez iterações por dia, dez decisões técnicas por dia são tomadas, e a maioria desaparece da memória coletiva em duas semanas. O que sobra é o código; o que se perde é o raciocínio que produziu o código.
Architecture Decision Records (ADR) durante a iteração — não depois — fixam três propriedades que a documentação pós-merge não captura:
- Problema original — qual era a restrição que motivou a decisão; sem isso, a próxima pessoa que olhar o código vai propor a mesma solução alternativa que foi rejeitada.
- Alternativas consideradas — o que foi tentado e descartado, e por quê; sem isso, o time refaz o trabalho de eliminação.
- Trade-offs aceitos — qual foi o custo da decisão em favor de quê; sem isso, a próxima iteração trata o trade-off como bug a ser corrigido.
O formato canônico de ADR durante iteração é curto: cinco linhas por iteração, datado, vinculado ao commit. Não é documento de especificação; é memória de decisão. A granularidade que funciona é uma ADR por iteração significativa, não uma ADR por feature ou por sprint.
A prática que mata a memória do time é documentar depois do merge. Nesse ponto, a memória do que foi decidido já degradou, e a documentação descreve o que o autor lembra seletivamente — com viés de confirmação para a decisão que prevaleceu. Documentar durante a iteração é mais barato, mais fiel, e mais útil para quem vai herdar o código em três meses.
Encerramento — proposição operacional
Iteração com IA não é pedir três vezes a mesma coisa até parecer certa. É ciclo disciplinado de: especificar com o que se sabe, gerar, revisar, identificar lacunas, refinar a spec, repetir. A qualidade final é função do número de iterações com critério, não da qualidade da IA subjacente.
Três critérios de calibração antes de aprovar a próxima sessão de desenvolvimento assistido por IA:
- A spec foi iterada pelo menos duas vezes antes do merge? Se a resposta for não, a qualidade da primeira entrega foi aceita sem custódia.
- Alternativas foram pedidas com critério explícito de variação? Se a resposta for não, a decisão técnica foi tomada sobre probabilidade, não sobre comparação.
- O código rodou em staging com tráfego real antes do merge? Se a resposta for não, a validação foi feita no editor, e o sistema vai pagar a conta da incompletude.
A diferença entre sistema que escala e sistema que vira caso de post-mortem raramente está na escolha de ferramenta. Está no critério de decisão que antecede a iteração, e na disciplina de execução dentro dela.
Leitura relacionada
- Vibe code com IA é desastre: como o desenvolvimento com IA exige rigor — diagnostica o padrão de aceitação preguiçosa que este post transforma em ciclo de iteração; os dois posts se complementam como problema e método.
- Você não pode debugar o que não entende. Por que compreensão é a prática número um com IA — mostra o que a iteração deste post está refinando de fato: a compreensão que emerge quando o dev revisa linha a linha a cada volta do ciclo.
- Seu processo de validação de código com IA é inadequado. Aqui está por quê e o que fazer. — detalha os quatro pilares de validação (testes, staging, canary, observability) que transformam a última iteração deste post em entrega verificável em produção.

4 Comentários