Durante grande parte da história humana, avaliamos a qualidade do código por meio de revisão de código: alguém lê o que você escreveu e garante que esteja limpo, bem pensado, rápido, compreensível e bem testado. Para agentes, essa abordagem não escala bem; há código demais para qualquer pessoa ler. Como resultado, cada vez mais nossos controles de qualidade precisam acontecer no harness, no ambiente e no sistema operacional ao redor do agente. Eu ainda leio e reviso código, mas sou muito intencional sobre onde me sinto confortável usando restrições como a verificação.
A qualidade de software agora depende das restrições que você define ao redor dos seus agentes.

A lista do Guillermo é um bom teste para saber se você pode se dar ao luxo de pular a leitura. Observe que cada "sim" é, na verdade, uma declaração sobre o quão baixas são as apostas — sem usuários, código descartável, protótipo. Quando as apostas sobem, algo precisa ler o código. Se não é você em cada diff, então têm que ser as restrições.
As restrições definem o que o sistema pode fazer, lançando testes e restrições determinísticas contra as propostas de um agente. É definindo e mantendo essas restrições que construímos ciclos que entregam software de produção de alta qualidade de forma confiável, mesmo quando os agentes criam centenas de milhares ou milhões de mudanças todos os dias.

Chamamos essas restrições de quality gates, e elas assumem muitas formas.
Elas incluem testes unitários convencionais, testes de propriedade e testes de aceitação. Elas incluem teste de mutação, em que geramos variações do código, executamos contra os mesmos testes e garantimos que ninguém está introduzindo bugs escondidos que estamos deixando passar. São métricas em torno da qualidade do código, como complexidade ciclomática e tamanho de linha, que ajudam a manter as coisas legíveis.

Duas pessoas podem discordar sobre ler ou não o código e ainda assim concordar sobre o mecanismo. Guillermo lê. Bob não lê nada disso. Ambos estão descrevendo uma provação — a diferença está apenas em se um humano fica dentro dela (não endosso as outras opiniões do Bob).
As restrições também desempenham um papel importante em quais propostas o sistema aceita e aplica como mudanças de código. Quando uma proposta de mudança passa do interpretador que executa o agente para o controlador do agente e segue para produção, já fizemos verificações suficientes nela para ter confiança de que é seguro publicar e que o impacto da mudança está bem dentro do escopo do agente.
Um agente pode propor qualquer coisa. Suas restrições decidem se uma proposta é segura o suficiente, correta, dentro do escopo e útil para que você e seu time entreguem.
Esse modelo oferece muito, mas também deixa de fora muitas peças, e essas omissões merecem reflexão hoje. Uma questão é a autonomia; os agentes podem aplicar bem suas intenções, mas podem falhar quando há informações ausentes ou quando o que tentam fazer é ambíguo. Isso se aplica tanto à tarefa em si quanto à forma como ela é parametrizada pelo harness, pelo ambiente e por outros componentes.
Muitas das razões pelas quais humanos falham em entregar ótimo código são compartilhadas com o que os agentes podem fazer: ambientes frágeis que não aguentam estresse dirigido por scripts, builds não determinísticos, permissões ausentes e testes fracos. Isso motiva um ambiente melhor que dá aos agentes feedback confiável, permite modos de falha de baixo dano e facilita a construção progressiva de sucesso.

O ambiente que buscamos é um onde o agente pode fazer trabalho real, receber feedback em que confia e falhar sem causar muitos danos.
A outra questão importante é a confiança. Não podemos delegar nossa intenção de forma crédula a algo tão inteligente e robusto quanto um agente moderno sem verificar sua correção. Começamos com confiança, mas ela precisa ser conquistada.

Algumas restrições moldam o trabalho antes que ele comece. Outras dão feedback enquanto o agente trabalha. Outras decidem se a saída dele pode cruzar a fronteira da produção.
Existem várias maneiras de modelar como colocamos uma estrutura de verificação ao redor de um sistema.
Na minha experiência, ajuda ter um conjunto mais amplo, mas escolhido intencionalmente, de verificações para suas restrições em vez de depender apenas de testes unitários. A ideia é que cada verificação tem uma responsabilidade distinta, que pode variar de segurança de tipos e desempenho a varredura de segurança nas fases finais. As pessoas também podem definir suas próprias restrições, incluindo regras de arquitetura que ferramentas de linting como ESLint podem impor. Muitas dessas ferramentas têm hooks integrados que podem ser usados para acionar agentes, ou humanos, quando algo quebra.
Por enquanto, grande parte da diferença entre a saída útil de um agente e porcaria ainda se resume à habilidade do time que opera o ciclo.
A IA nos dá geração de código em alto volume e velocidade, mas isso também pode significar que fica mais difícil para os humanos revisarem cada mudança individual. Em vez disso, você precisa ser intencional sobre para onde está indo a atenção deles. Se você colocar uma verificação humana em um sistema que, de outra forma, se move na velocidade da máquina, não se surpreenda se isso impactar a produtividade. A atenção humana é escassa e valiosa, então devemos direcioná-la proativamente para os problemas mais sutis que exigem nosso julgamento. Os humanos a jusante só devem ser acionados quando as proteções automatizadas das restrições falharem.
A "revisão de código" humana no futuro vai parecer muito diferente
A correção é uma dimensão importante, mas você pode se importar com outras também, como manutenibilidade, desempenho, segurança, eficiência e compreensibilidade. Assim como a correção se desdobra em muitos tipos de sinal, o resto da qualidade também se desdobra. E embora importe quantas restrições temos em vigor, importa mais se elas são desafiadoras o suficiente para atingir nosso padrão de qualidade e prontidão para produção.
Qualidade de software não é uma métrica única. Pense nela como uma coleção de sinais de importância variada para você e seu time.
A contrapressão pode ser implementada por meio de muitas ferramentas: compiladores rejeitando código inválido, testes falhando, políticas de segurança bloqueando más práticas, CI se recusando a fazer deploy. Idealmente, ela existe ao longo de todo o ciclo, não como uma revisão única bem no final de todo o trabalho.

O mapa de Dex Horthy do mesmo ciclo, de Why Software Factories Fail. A caixa verde é o argumento dele de que, no momento, a revisão humana deve voltar ao ciclo em vez de ser substituída por ele.
Restrições e contrapressão permitem que os agentes detectem trabalho ruim antes que ele se torne um problema
O que acontece se não conseguirmos aplicar a restrição porque o volume de mudanças é maior do que nossas ferramentas conseguem consumir? Acabamos criando uma fila e dependendo de um sistema de verificação que se move na velocidade humana. Para escalar, queremos empurrar o máximo possível para o ciclo de verificação ao longo do processo e não esperar até o final. Se conseguirmos escalar dentro de nossas verificações automatizadas, podemos aumentar a velocidade e a vazão de todo o nosso sistema de entrega. Se ficarmos sem espaço no ciclo de verificação, precisamos fazer uma de várias coisas.
Primeiro, podemos escalar nosso sistema de verificação e criar mais capacidade para restringir e fazer contrapressão às mudanças que chegam. Segundo, podemos reduzir a taxa com que os agentes geram novas mudanças para que a verificação consiga acompanhar o volume de trabalho. Terceiro, podemos baixar nosso padrão de qualidade para que a verificação não faça tanta contrapressão quanto faria de outra forma. Do ponto de vista de escalabilidade, precisamos estar prontos para fazer todas essas coisas. Ao mesmo tempo, não devemos deixar de perceber que poderíamos, na verdade, fazer mais ao remover restrições em algumas direções. Talvez possamos aumentar a velocidade das mudanças geradas por agentes ao fornecer enxames de desenvolvedores de agentes ou fábricas de software automatizadas para criar mudanças sem esperar que revisemos cada uma delas.
E em alguns lugares podemos querer dar mais liberdade a eles, desde que mantenhamos restrições mais rígidas em outros. Ao oferecer restrições mais rígidas onde mais nos importamos, podemos maximizar nossa vazão sem sacrificar a qualidade. Ao longo dessas decisões, há muitas opções. Obviamente, precisamos fazer trocas entre diferentes dimensões da qualidade. Como enfatizamos, a segurança é muito importante, mas também tivemos que escolher entre entregar segurança e entregar o produto no prazo. Existe um espectro que vai do foco em inovação em uma ponta ao foco em qualidade na outra. Em algum ponto do caminho, precisamos fazer escolhas sobre onde queremos estar nesse espectro.
Queremos enviar feedback claro do ambiente e do sistema de volta para nossos agentes ou times, para que as pessoas possam focar nas preocupações mais subjetivas de bom gosto, intenção e arquitetura. Se pudermos ajudar os humanos a permanecer dentro da faixa segura das restrições, podemos evitar que eles precisem se esforçar para descobrir onde as coisas deram errado.
A qualidade de software inclui mais do que apenas correção. Qualidade de software também significa manutenibilidade, bom desempenho, segurança, eficiência e facilidade de compreensão. Todas as restrições que nos ajudam a atingir esses padrões e mantêm nossa produção fluindo criam contrapressão em nosso pipeline de entrega.
Precisamos tomar decisões deliberadas sobre onde aplicar restrições fortes e onde removê-las ou afrouxá-las. Aplique restrições fortes onde elas estão servindo a ambos os objetivos. Não as mantenha se não estiverem servindo a um ou a ambos. Esteja pronto para elevar ou baixar os padrões conforme o caso exigir. E lembre-se: essas restrições em diferentes pontos do sistema de software são o que tornam a qualidade de software aplicável.
Devemos aplicar restrições fortes onde elas melhor servirem a esse duplo propósito e considerar remover ou afrouxar as restrições que não estão servindo bem a nenhum dos dois propósitos. Também devemos estar prontos para elevar ou baixar os padrões de qualidade conforme necessário. Na prática, são essas restrições em vários pontos do nosso sistema de software que dão força à qualidade. Em muitos casos, podemos criar mais contrapressão e mais restrições implantando novas ferramentas ou fortalecendo ferramentas que já estão em uso. Todas essas coisas podem ser usadas para fazer contrapressão à maioria das solicitações de mudança. Queremos construí-las ao longo de todo o pipeline.
Não queremos esperar até o final do pipeline, quando nosso sistema de CI simplesmente nos dirá que não podemos fazer deploy sem corrigir problemas. Queremos usar esses sinais o mais cedo possível, por todos os caminhos possíveis. A restrição máxima neste sistema é aquela que impomos a nós mesmos: responder pelas decisões e ações que tomamos para construir o sistema e operá-lo. Mas, como todas as outras restrições, precisamos fazer trocas criteriosas sobre o quanto queremos que nosso próprio julgamento restrinja, faça contrapressão e atue como uma verificação final.
A qualidade está nas restrições que colocamos ao redor dos nossos agentes. Então, ao pensar em qualidade para seus próprios aplicativos, pegue esta declaração do problema e crie seu próprio plano orientado por restrições.

Falando em qualidade, os agentes estão escrevendo seu código. Sonar oferece os quality gates para deixá-lo pronto para produção. Ele executa a mesma verificação completa em cada commit: análise profunda entre arquivos, um mapa de onde o risco está e um quality gate que mantém todos os humanos e agentes no mesmo padrão.
Este artigo foi classificado como 100% escrito por humanos pelo Pangram 4.





