- Em um ambiente de desenvolvimento em colaboração com IA, os humanos precisam definir com clareza a direção e as decisões do projeto para manter a qualidade
- Por meio de documentação precisa, é preciso garantir que tanto a IA quanto outros desenvolvedores compreendam claramente os requisitos e as restrições
- Ao construir um sistema de debug e um processo de code review, reforça-se a confiabilidade do código gerado por IA e o processo de validação
- Com marcação de funções de risco de segurança, separação de testes e regras rígidas de linting, garante-se a estabilidade e a consistência do código
- Por meio da divisão do trabalho em unidades menores e da minimização da complexidade, mantém-se o controle sobre a geração de código por IA e maximiza-se a eficiência
1. Estabelecer uma visão clara
- Os humanos entendem o mundo, a equipe e o comportamento dos usuários, mas a IA não tem experiência, portanto precisa de instruções explícitas
- Em um projeto, decisões não documentadas acabarão sendo tomadas pela IA
- É preciso discutir antecipadamente arquitetura, interfaces, estruturas de dados e algoritmos e definir como os testes serão feitos
- Decisões de longo prazo e difíceis de mudar devem ser necessariamente geridas diretamente por humanos
2. Manter documentação precisa
- Para que a IA gere código adequado ao objetivo, é indispensável transmitir requisitos detalhados
- Como outros desenvolvedores também precisam fornecer as mesmas informações à IA, documentos em formato padronizado devem ser incluídos no repositório de código
- Registrar em detalhe requisitos, restrições, arquitetura, padrões de codificação, design patterns etc.
- Usar diagramas UML, fluxogramas e pseudocódigo para representar visualmente estruturas complexas
3. Construir um sistema de debug que apoie a IA
- É preciso preparar um sistema de debug eficiente para que a IA possa validar rapidamente o funcionamento do código
- Ex.: coletar logs de todos os nós de um sistema distribuído e fornecer informações resumidas como “os dados foram enviados para todos os nós”
- Isso permite reduzir o custo de execução de comandos e acelerar a identificação de problemas
4. Indicar o nível de code review
- É preciso diferenciar a intensidade da revisão de acordo com a importância do código
- Ex.: adicionar o comentário
//A após uma função escrita por IA para indicar se houve revisão humana
- Esse sistema facilita a identificação e a gestão de código não revisado
5. Escrever especificações de alto nível e testar diretamente
- A IA pode trapacear com mocks ou valores hardcoded para passar nos testes
- Para evitar isso, é preciso escrever diretamente testes baseados em propriedades (property-based testing)
- Ex.: reiniciar o servidor e verificar a consistência dos valores no banco de dados
- O código de teste deve ser separado em uma área distinta para que a IA não possa modificá-lo
6. Separação dos testes de interface
- É preciso fazer com que a IA escreva testes de interface sem conhecer o contexto de outros trechos de código
- Assim, os testes mantêm a objetividade por não sofrerem influência da IA responsável pela implementação
- Esses testes também devem ser protegidos para que a IA não os modifique arbitrariamente
7. Regras rígidas de linting e formatação
- Um estilo de código consistente e regras de linting são essenciais para manter a qualidade e detectar erros cedo
- Tanto a IA quanto os humanos conseguem verificar a qualidade do código com mais facilidade
8. Usar prompts de agentes de código por contexto
- Usar arquivos de prompt por projeto, como
CLAUDE.md, reduz o custo inicial de entendimento da IA
- Ao incluir padrões de codificação, design patterns e requisitos, aumenta-se a qualidade e a eficiência da geração de código pela IA
9. Identificar e marcar funções com risco de segurança
- É preciso marcar explicitamente funções sensíveis à segurança, como autenticação, autorização e tratamento de dados
- Ex.: usar comentários
//HIGH-RISK-UNREVIEWED, //HIGH-RISK-REVIEWED
- Se a IA modificar essas funções, deve-se configurar a alteração automática do status de revisão
- Os desenvolvedores devem sempre verificar se esse status está correto
10. Minimizar a complexidade do código
- Mesmo uma única linha de código desnecessária ocupa espaço na janela de contexto da IA e aumenta o custo
- Deve-se manter a estrutura o mais simples possível para elevar a compreensão tanto da IA quanto dos humanos
11. Explorar problemas por meio de experimentos e protótipos
- É possível experimentar várias soluções aproveitando a natureza de baixo custo da geração de código por IA
- Criam-se vários protótipos com especificações mínimas para explorar a melhor abordagem
12. Proibir geração massiva sem critério
- Tarefas complexas devem ser divididas em unidades menores para que a IA as processe em etapas
- Ex.: gerar funções ou classes individuais em vez do projeto inteiro
- É preciso verificar se cada componente está de acordo com a especificação e,
se a complexidade do código sair do controle, será necessário retornar o projeto ao estado inicial
1 comentários
Comentários do Hacker News
Ainda acho importante escrever código com as próprias mãos e organizar o pensamento durante o processo
Para mim, o código funciona como um mecanismo de imposição que me obriga a lapidar os detalhes
Tenho a sensação de que só escrever a especificação não dá essa mesma profundidade
Quando deixo esse processo para um LLM, é como um avião entrando em estol, e eu travo mentalmente
O estresse de resolver problemas diminui, mas também some a motivação para pensar e criar
Ao meu redor há quem goste de deixar a IA escrever o código, mas eu não faço parte desse grupo
Tenho dificuldade em acreditar em quem diz que cria um SaaS tomando café enquanto roda 5 agentes
Se você quer código de boa qualidade, acho que precisa mergulhar fundo no código você mesmo
Ainda assim, a IA foi bem útil para tarefas simples e repetitivas, como escrever testes ou resolver problemas de configuração
Por exemplo, reviveu com Claude um projeto que eu tinha abandonado 5 anos atrás, e em poucas horas parecia que metade já tinha avançado
Mas hoje parece que voltei para uma abordagem centrada em especificação
Graças aos agentes, consigo repetir rapidamente ciclos de tentativa e descarte e ainda manter um fluxo de desenvolvimento iterativo
Vejo a especificação e os testes como o trabalho real, e sigo ajustando-os para organizar meu raciocínio
Só com especificações não dá para capturar toda a complexidade do mundo real
O código escrito por LLM com frequência é verboso e vai em direções estranhas, então precisa de gestão direta
Em compensação, o LLM é bem bom como parceiro para discutir e refinar ideias
Agora que escrever código ficou mais barato e rápido, talvez seja hora de reforçar a etapa formal de design
Acho que o que mais impactou a qualidade do código para mim foi configurar de forma sistemática ferramentas de análise estática
No ecossistema TypeScript, combinei
tsc,eslint,sonarjs,knip,jscpd,dependency-cruiseresemgrep, tudo integrado no comandopnpm checkTambém configurei para rodar automaticamente com pre-commit hook, evitando problemas que o LLM deixou passar
Isso também facilita corrigir manualmente quando o LLM trava
Quando o estilo do código é consistente, a revisão fica muito mais tranquila, e a mistura de código gerado por IA com código humano causa menos confusão
Mas mesmo passando em lint e testes, ainda aparece código que funciona de forma diferente do pretendido
Por exemplo, uma API que retorna um array vazio em vez de 404: sintaticamente está certa, mas semanticamente está errada
Esse tipo de avaliação de precisão comportamental ainda é a parte mais difícil
Às vezes, acho que a manutenibilidade deve vir antes das regras de lint
Sempre faço refatoração periódica cada vez que adiciono funcionalidades
A cada poucas features, reviso e organizo toda a base de código
Programo há 40 anos, e nunca estive tão satisfeito com meu código quanto agora
Mas com LLM, o custo da refatoração ficou praticamente próximo de zero
Agora não há mais motivo para deixar código ruim como está
Acho que o valor real está em usar ferramentas que aumentam eficiência para também elevar a qualidade
Criei uma ferramenta interna que, a cada commit, marca as linhas de código como bom (verde) / precisa refatorar (amarelo) / precisa reescrever (vermelho)
É mais limpo e sistemático do que comentários “TODO refactor”, e pretendo abrir o código em breve
Hoje acho que, para trabalhar com IA, desenvolvimento orientado por especificação é a opção mais estável
Passo mais tempo refinando a especificação e trocando ideias com a equipe e com a IA
Quando a especificação está incompleta, a IA gera código sem sentido
Quando o entendimento do domínio aprofunda, muitas vezes parece melhor mandar implementar tudo de novo desde o início
Na época havia a visão de que “se definirmos apenas os requisitos, o sistema se constrói sozinho”
No fim isso fracassou e o ágil virou padrão, mas agora parece que a tecnologia pode tornar esse sonho possível de novo
O valor real da IA está na velocidade e na capacidade de lidar com ambiguidade
Mas, se você passar por todos os procedimentos, no fim tudo fica lento como waterfall
Talvez seja melhor escrever o código você mesmo e usar a IA como primeira revisora
Continuar validando rapidamente em pequenas partes ainda é uma abordagem ágil
Gostei especialmente da sugestão de marcar funções relacionadas à segurança. Isso ajuda a manter o contexto em alterações futuras
“Dividir em partes pequenas” é o básico, mas é algo que iniciantes frequentemente deixam passar
É engraçado ver as pessoas redescobrindo, graças à IA, boas práticas básicas
Na verdade, isso tudo já deveria estar sendo feito há muito tempo
Agora que o tempo gasto codando diminuiu, sobra mais espaço para esse tipo de trabalho
Além disso, a IA realmente usa a documentação, então escrever boa documentação passou a ter valor direto
Antes você escrevia documentação e ela era ignorada; o LLM lê tudo
Antes eu escrevia especificações detalhadas antes de começar a programar, mas depois percebi que entrar direto no código era mais rápido
E agora será que estamos voltando de novo para um modelo centrado em especificação?
Se você escreve uma especificação sem entender completamente o problema, no fim vai acabar aprendendo enquanto codifica
Parece que hoje estamos em algum ponto no meio disso
Mas agora, com IA, o custo do código errado ficou quase zero, então a especificação parece ter perdido parte do valor
Isso é parecido com a forma de programar de que Joe Armstrong falava
Agora vivemos numa época em que isso é realisticamente possível
Quando assumi uma posição de liderança, eu escrevia tickets extremamente detalhados
Em parte pelos juniores, mas também para eu mesmo não esquecer os detalhes
Porém a gerência dizia que isso era “perda de tempo”, e acabei perdendo esse hábito
Agora, ironicamente, me exigem escrever especificações ainda mais elaboradas, só que mais rápido
Ao usar agentes de IA, fico curioso sobre a proporção entre Markdown e código, e sobre a legibilidade do resultado
Também me pergunto se o tempo de revisão realmente não fica maior do que escrever o código diretamente
É irônico ver desenvolvedores defendendo com entusiasmo uma IA que pode acabar substituindo eles próprios
Este tweet relacionado satiriza esse fenômeno
Talvez a mensagem de “se você não usa Claude, vai ficar para trás” venha daí
mas na prática isso tem grande chance de levar a queda na demanda e na remuneração de desenvolvedores
O risco é ainda maior para quem só atua no nível de combinar pacotes NPM