Existe uma versão deste post onde eu digo que a IA me tornou 10 vezes mais produtivo, que tudo funcionou de primeira e que agora estou entregando software enquanto tomo café com os pés para cima.
Este não é esse post.
Algumas semanas atrás, o Codeminer42 me desafiou a construir um projeto paralelo do zero usando apenas ferramentas de IA. Nada de escrever código à mão. Cada linha precisava vir de prompts. Meu trabalho era descrever o que eu queria, ler o que retornava e corrigir problemas com mais prompts. A empresa me forneceu uma assinatura do Claude Code para isso, e a regra era simples: se eu quisesse que algo existisse na base de código, eu tinha que pedir.
Acabei construindo dois projetos em vez de um. Um web app completo em Rails 8 com integração de teclado MIDI, e um app autônomo para Wear OS para treinamento intervalado de caminhada e corrida, com timers hápticos e mais de 150 testes automatizados. Publiquei ambos os projetos. Cada um me ensinou coisas que eu não poderia ter aprendido de outra forma.
Se você não está familiarizado com o que Engenharia Agentica significa, Edy Silva escreveu uma ótima introdução neste blog que vale a pena ler primeiro.
A configuração
Minha stack era simples: Claude Code CLI como o agente principal, servidores MCP (Chrome DevTools e Google Stitch para o primeiro projeto) para dar ao Claude acesso ao navegador e ferramentas de design. VS Code para o projeto Rails, Android Studio para Wear OS. E um arquivo CLAUDE.md em cada projeto que eu continuava atualizando conforme avançava.
Uma coisa que vale mencionar sobre como eu trabalho com o Claude Code: prefiro confirmar cada ação antes que ela aconteça. Quando o Claude quer editar um arquivo, criar uma pasta ou executar um comando, eu reviso e aprovo primeiro. Isso torna as coisas um pouco mais lentas, mas eu sempre sei o que está acontecendo na base de código e percebo problemas antes que eles se acumulem.
O Codeminer42 também me forneceu a chave da API da Anthropic que eu precisava para ambos os projetos. Um deles, na verdade, chama essa API de dentro do próprio aplicativo, mas chegarei a isso.
Ah, e atingi os limites de sessão algumas vezes durante as duas semanas, especialmente nos dias mais longos. Honestamente, eu entendo por que as pessoas reclamam disso ultimamente. É genuinamente irritante quando você está no meio de algo e o Claude simplesmente para. Felizmente, o Codeminer42 expandiu meus limites quando precisei, o que me salvou mais de uma vez, embora ainda seja algo que você precise planejar.
Project #1: Piano Learner
What it is
Uma aplicação web em Rails 8 para aprender piano, com integração de teclado MIDI em tempo real, análise de músicas gerada por IA via API da Anthropic, notação musical via VexFlow, um motor de prática baseado em BPM e um sistema de pontuação. Quase 300 testes automatizados entre RSpec e Vitest. Cinco dias.
A biblioteca de músicas lista cada faixa disponível para prática### Teaching Claude to See
Construir a página da lista de músicas foi um dos primeiros testes reais do fluxo de trabalho. Pedi ao Claude para construí-la, ele a construiu, executou os testes, corrigiu algumas coisas e tudo passou. Ótimo, certo?
Não exatamente. Quando abri a página no navegador, os elementos não estavam aparecendo da maneira que eu esperava. Os testes estavam verdes, o código parecia correto, mas o resultado visual real estava errado. Foi quando lembrei que Miguel Marcondes, um colega desenvolvedor no Codeminer42, havia mencionado um MCP do Chrome que permite conectar o navegador diretamente ao Claude Code. Achei que esse seria um bom momento para experimentá-lo.
Então eu instalei. E o Claude abriu o Chrome dentro do WSL, o que não era nem de longe o que eu queria. Eu precisava que ele se conectasse à minha instância existente do Chrome no Windows por meio de uma sessão de depuração remota, e não que iniciasse um novo navegador dentro do ambiente Linux.
Então comecei uma nova sessão do Claude Code e pedi que ele me ajudasse a descobrir como alterar a configuração do MCP para fazer o que eu realmente precisava. Ele me mostrou alguns arquivos de configuração. Ainda assim, nenhum deles funcionou. Em seguida, pedi que ele verificasse o repositório do Chrome MCP no GitHub para encontrar as flags corretas para habilitar a depuração remota, e também que olhasse a documentação do Claude Code para encontrar onde ficam os arquivos de configuração reais do MCP. Essa combinação funcionou. O Claude encontrou as duas informações, eu atualizei o arquivo certo com as flags certas e, de repente, eu tinha uma sessão do Chrome ativa conectada ao Claude Code.
A partir desse ponto, eu podia enviar capturas de tela diretamente pelo MCP e pedir ao Claude para analisar o que estava visualmente errado. Isso mudou a forma como trabalhei com o frontend pelo restante do projeto.
Claude chamando Claude
No Dia 3, adicionei um recurso onde o app chama a API do Claude para gerar guias de estudo para cada música. Então o Claude Code, a ferramenta que eu estava usando para construir o projeto, estava escrevendo o código que chama o Claude como um recurso dentro do projeto. A IA estava programando como falar consigo mesma.
Sinceramente, isso não estava no plano original. Em vez disso, surgiu do que o projeto precisava. Os guias que ele produziu eram como os de um professor e diretos: exercícios de prática com tempos sugeridos, dicas baseadas em marcos, descrições emocionais de cada acorde. Eu reescrevi o prompt uma vez porque a primeira versão não estava totalmente certa. Depois disso, funcionou bem.
A página de análise divide uma música em seções com tempos e dicas sugeridas### Trocando de modelos no meio do projeto
Usei dois modelos do Claude durante este projeto. Inicialmente, o Sonnet cuidou do trabalho inicial: scaffolding, modelos, controllers, colocando a estrutura básica para funcionar. Depois, o Opus assumiu quando as coisas ficaram mais complexas, como o motor de timing BPM, o algoritmo de pontuação, a integração com VexFlow e a melhoria da qualidade dos testes. O Sonnet era mais rápido e ótimo para construir as coisas rapidamente. No entanto, o Opus era mais lento, mas tomava decisões visivelmente melhores quando o problema era mais difícil. No geral, saber quando mudar importou mais do que eu esperava.
Google Stitch, no início
Minha melhor amiga tinha me mostrado o Google Stitch algumas semanas antes do desafio. Ela estava animada com ele e disse que o recurso era impressionante. Mesmo assim, eu estava um pouco cético. Na verdade, pelo que eu tinha visto, ele ainda cometia erros, especialmente em tipografia.
Mas durante o desafio, decidi dar a ele uma chance real. Primeiro, escrevi alguns prompts descrevendo o design que eu queria, enviei o arquivo de instruções do projeto para que ele tivesse contexto e então pedi ao Stitch para gerar algo. Infelizmente, os resultados não foram bons o suficiente. Ele criou recursos que não existiam no projeto, inconsistências começaram a aparecer e, eventualmente, após mais algumas solicitações, ele simplesmente parou de responder.
Então, me contentei em exportar o que consegui obter como imagens e usei as mesmas como referência visual para o Claude localmente. Nada sofisticado, apenas capturas de tela para indicar.
Um design system, construído por acidente
Então, enquanto olhava as opções de exportação, notei que uma delas dizia "MCP Server". Naquele momento, eu já estava familiarizado com a configuração do Chrome MCP e, esperando que esta fosse menos dolorosa de configurar, tentei. Ele se conectou ao Claude sem muitos problemas.
O problema foi o que aconteceu em seguida: em vez de ler meu design existente e trabalhar a partir dele, o Claude usou a conexão para começar a criar um design completamente novo do zero. Então eu o parei antes que fosse longe demais e disse para ele me fazer perguntas antes de tocar em qualquer coisa. Surpreendentemente, isso realmente ajudou. Ele me guiou por algumas perguntas sobre a direção que eu queria, ofereceu algumas sugestões que eu não tinha considerado e, eventualmente, a partir dessa conversa, construímos juntos um sistema de design adequado.
Enquanto isso, eu estava ouvindo a trilha sonora do anime Cyberpunk 2077 durante tudo isso, e o clima dela acabou moldando toda a direção visual mais do que qualquer prompt que eu escrevi. As cores neon, os fundos escuros, os detalhes brilhantes. Honestamente, eu não tinha planejado nada disso. Apenas veio do que estava tocando. Às vezes, as melhores decisões de design não são decisões.
O resultado foi a interface que você pode ver abaixo.
O modo de prática mostra as próximas notas na pauta em tempo real
A tela de pontuação aparece logo após você terminar uma música### A confissão do CLAUDE.md
Um dos meus maiores erros neste projeto: eu só comecei a criar o arquivo CLAUDE.md no quinto dia. Até então, eu já havia passado quatro dias reexplicando a estrutura do projeto, convenções e regras no início de cada sessão, porque o Claude não tem memória entre sessões.
Assim que eu finalmente o escrevi (cerca de 350 linhas abrangendo arquitetura, rotas, comandos de teste e uma lista crescente de antipadrões), as sessões futuras continuaram exatamente de onde a anterior parou. Na verdade, a seção de antipadrões foi especialmente valiosa. Cada vez que o Claude cometia um erro que eu corrigia uma vez, eu o adicionava ao arquivo para que não acontecesse novamente:
- "Evite specs de teste pendentes ou vazias"
- "Não escreva request specs apenas para smoke-tests"
- "Sempre teste métodos de consulta de status de IA"
Eu deveria ter começado isso no Dia 1. Essa é provavelmente a coisa mais útil que posso dizer a qualquer pessoa que esteja começando com o Claude Code.
A funcionalidade que construímos e deletamos (curiosidade)
No Dia 2, o Claude construiu um pipeline completo de importação de arquivos: mais de 600 linhas de código funcional com modelos, importadores e jobs de segundo plano para lidar com arquivos de música MIDI e ABC. No entanto, ao final do mesmo dia, percebi que não precisávamos da funcionalidade. Então, deletamos tudo.
Em um projeto normal, jogar fora 600 linhas de código funcional pareceria uma perda real. No entanto, aqui foi apenas uma decisão fácil. Na verdade, essa mudança na forma como eu pensava sobre desperdício foi uma das coisas mais sutis que mudaram durante essas duas semanas.
Pelos números
| Dias corridos | 5 |
|---|---|
| Total de commits | 55 |
| Linhas adicionadas | ~16.800 |
| Código Ruby | ~4.600 linhas |
| Código JavaScript | ~2.000 linhas |
| Total de testes | ~288 (RSpec + Vitest) |
| Migrações de banco de dados | 13 |
Projeto #2: TrotClock
O que é
Um app standalone para Wear OS para treinamento de intervalo de caminhada/corrida, construído com Kotlin e Jetpack Compose. Você configura sessões personalizadas com padrões de caminhada e corrida, inicia um cronômetro de contagem regressiva no pulso, e ele guia você pelo aquecimento, intervalos e desaquecimento com feedback haptico. Não é necessário celular.
Do plano ao app funcional em três dias
Antes de escrever qualquer Kotlin, passei a primeira sessão no modo de plano do Claude Code, onde o agente atua mais como um arquiteto do que como um escritor de código. Analisamos o esquema do banco de dados (eu insisti em uma tabela de junção relacional em vez de armazenar dados de intervalo como JSON, o que removeu uma dependência inteira), a exigência do serviço de primeiro plano (no Wear OS, o timer precisa continuar rodando mesmo quando o pulso abaixa e a tela desliga) e cada biblioteca na lista de dependências. Em certo momento, perguntei ao Claude: "explique por que você está adicionando todas essas bibliotecas para um aplicativo tão simples". Ele teve que justificar cada uma delas.
O plano final foi um roteiro de 8 fases, orientado por TDD, abrangendo modelos de domínio, banco de dados, camada de repositório, timer de sessão, serviço de primeiro plano, ViewModels, telas do Compose e navegação. Assim que fechamos o plano, a execução avançou surpreendentemente rápido. Basicamente, passamos da estrutura básica para um aplicativo funcional em algumas sessões focadas, com o Claude construindo cada camada sobre a anterior e escrevendo testes junto com o código de produção.
O loop de auditoria que mudou minha abordagem
Perto do fim do terceiro dia, Edy compartilhou comigo uma habilidade /audit para o Claude Code. Basicamente, é um prompt estruturado que avalia a base de código em várias dimensões de qualidade e fornece uma pontuação com descobertas específicas. Então, decidi usá-lo em um loop: executar a auditoria, deixar o Claude corrigir o que encontrou, executar a auditoria novamente.
Três rodadas em uma noite. A pontuação foi de 8,2 para 8,9 e depois 9,0. Cada rodada revelou lacunas específicas, como a falta de testes na camada de serviço, documentação imprecisa ou classes utilitárias não cobertas, e eu as resolvi em commits direcionados antes de executar a próxima verificação. Foi ideia minha continuar o loop até que a pontuação parasse de subir, e funcionou melhor do que eu esperava.
A maioria das pessoas usa ferramentas de IA como um motor de busca. Pergunta uma vez, recebe a resposta, segue em frente. No entanto, o loop de auditoria foi a primeira vez que eu realmente entendi o que significa deixar o agente de fato iterar.
Configurando uma nova sessão com intervalos personalizados de caminhada e trote
O relógio faz a contagem regressiva da fase de caminhada antes de mudar para o trote
Todas as sessões passadas permanecem visíveis em uma única lista### By the numbers
| Dias de desenvolvimento3 | Total de commits | 26 |
|---|---|---|
| Código de produção | ~1.700 linhas (34 arquivos Kotlin) | |
| Código de teste | ~2.700 linhas (21 arquivos de teste) | |
| Total de testes | 157 (unitários + instrumentados) | |
| Proporção teste-fonte | 1,58x | |
| Progressão da pontuação de auditoria | 8.2 → 8.9 → 9.0 |
O que deu errado
A configuração do sandbox
Em certo momento, tentei configurar o recurso nativo de sandbox do Claude Code. M.Akita escreveu um post chamado "AI Agents: Garantindo a Proteção do seu Sistema" explicando por que executar um agente de IA sem qualquer isolamento é arriscado. Basicamente, tal agente pode ler, editar e excluir arquivos em qualquer lugar do seu sistema, executar comandos arbitrários e fazer coisas que você nunca pretendeu. A recomendação dele é executar o Claude dentro de um sandbox adequado para que ele tenha um ambiente contido para trabalhar.
A configuração em si foi mais difícil do que eu esperava. Tive problemas de configuração que levaram mais tempo para depurar do que as próprias funcionalidades que eu estava tentando criar. O Claude continuava fazendo suposições sobre o ambiente que não se confirmavam dentro do sandbox. Eventualmente, consegui fazer funcionar parcialmente, mas nunca confiei o suficiente para depender totalmente dele. Revisitar isso está definitivamente na minha lista, porque o raciocínio por trás disso é sólido. Na época, porém, eu simplesmente não tinha experiência suficiente para superar isso.
Primeiras tentativas erradas em tarefas complexas
Em tarefas complexas, especialmente qualquer coisa envolvendo configuração de ambiente, sistemas de build ou setups não padronizados, a primeira tentativa do Claude costumava estar errada. Por exemplo, configs de build ruins, sintaxe de API incorreta, CSS que parecia certo no código, mas quebrava no navegador. No entanto, em tarefas simples e bem definidas, geralmente estava tudo bem. Basicamente, quanto mais específico e incomum o ambiente, pior tendia a ser a primeira tentativa.
O que mais ajudou foi dividir o trabalho em pedaços menores em vez de dar ao Claude solicitações grandes e abertas. No fim, quanto mais precisamente eu descrevia o que queria, melhor era o resultado na primeira tentativa.
Claude declarando vitória cedo demais
Este foi o padrão mais frustrante que encontrei, e aconteceu mais de algumas vezes. O Claude terminava uma tarefa, me dizia que tudo estava funcionando, e simplesmente não estava. Uma vez, faltava um pacote de segurança crítico em um setup de sandbox. Outra vez, uma config de build tinha erros silenciosos. O Claude revisou o próprio trabalho e decidiu que estava tudo bem.
A solução que adotei é estrutural: os testes decidem se algo está pronto, não o Claude. Depois que isso aconteceu vezes suficientes, adicionei git hooks e execuções de testes automatizados como checkpoints obrigatórios após cada sessão. Se o Claude diz que terminou, mas os testes discordam, não terminamos. O Claude não pode dar nota ao próprio dever de casa.
A mudança no modelo mental
O novo gargalo é a clareza, não o código
Aqui está o que ninguém me disse ao começar: o gargalo deixa de ser "consigo escrever este código?" e se torna "consigo descrever este problema com clareza suficiente para que o agente o resolva?"
Isso parece mais fácil. No entanto, geralmente não é, pelo menos não no início.
Escrever um bom CLAUDE.md, delimitar a abrangência de uma tarefa a ponto de o agente não seguir pelo caminho errado, saber quando questionar a escolha de uma tecnologia, manter-se cético o suficiente para perceber quando o Claude diz que algo está pronto antes de realmente estar, essas são habilidades que levam tempo para serem desenvolvidas. Elas não se parecem muito com o desenvolvimento de software tradicional.
Fundamentos importam mais, não menos
E aqui está algo em que continuo pensando conforme as ferramentas de IA melhoram: os fundamentos de uma boa engenharia de software estão se tornando mais importantes, não menos. Por exemplo, saber como os sistemas são estruturados. Entender quando aplicar um padrão de projeto e quando isso é superengenharia. Além disso, ter uma noção real das trocas entre segurança, desempenho e escalabilidade. Nada disso é automatizado. Pelo contrário, é exatamente isso que permite julgar se o que o agente produziu é realmente bom, e não apenas se roda sem erros.
À medida que os modelos melhoram, a lacuna entre os desenvolvedores que entendem essas coisas e aqueles que não entendem continuará crescendo. Infelizmente, prompts melhores não fecharão essa lacuna. Em vez disso, o agente multiplica o que você já sabe. Então, se o que você sabe é sólido, isso é algo bom.
O veredito honesto
Após duas semanas, dúzias de sessões e dois projetos publicados, posso dizer que o valor é real. Para começar, aqueles loops de auditoria realmente funcionam. Além disso, transitar entre diferentes stacks pareceu rápido. Passar de Rails para Kotlin, para scripts bash e para automação de navegador, tudo em duas semanas, é algo que eu não teria acreditado antes de fazer.
Mas há um custo real em tempo e foco gasto corrigindo primeiras tentativas erradas, verificando coisas que o Claude afirma que estão funcionando e re-explicando contextos que não sobreviveram ao limite da sessão. Isso é algo que quero melhorar com o tempo através de arquivos CLAUDE.md melhores, escopos de tarefas mais rigorosos e checkpoints mais automatizados configurados desde o início.
No geral, a principal lição que tiro: bons fundamentos de engenharia de software importam mais em um fluxo de trabalho agente, não menos. Você precisa saber o que está pedindo, reconhecer quando o que retornou não está correto e entender a base de código bem o suficiente para guiar as coisas em direção a algo que você realmente queira manter. Nenhum prompt resolve isso.
Moisés Carvalho é um desenvolvedor fullstack na Codeminer42. Você pode encontrá-lo no GitHub em imperadorsid.
Código-fonte: Piano Learner · TrotClock**
We want to work with you. Check out our Services page!

