Lições de uma sessão real de pair programming com Claude

Faz um tempo que faço pair programming com IA em código de produção de verdade. Não por novidade, não para testar — porque funciona. O que quero discutir aqui não é se IA é útil. Essa questão já está resolvida, pelo menos pra mim. O que quero discutir é como torná-la útil de verdade — as decisões que transformam uma ferramenta capaz em uma parceira de design genuína.

Este artigo é sobre uma sessão específica. Eu tinha uma classe de 295 linhas que precisava virar um módulo bem estruturado — limpo o suficiente para quem sabe virar uma gem. Trabalhei com o Claude do início ao fim. O projeto foi o LexxyPrawn: um módulo Ruby que transforma o JSON do editor de rich-text Lexxy em um PDF gerado pelo Prawn. O contexto é específico; as lições, não.

O que vem a seguir é um relato detalhado de como essa sessão realmente aconteceu — os prompts que funcionaram, as conversas de design que moldaram o resultado, e os padrões que continuo usando. O código era Ruby. As lições valem para qualquer linguagem, qualquer stack, qualquer dev que já usa IA no dia a dia e quer ir mais fundo.

Parte 1 — Uma Sessão de AI Pair Programming

O Ponto de Partida

Uma única classe de 295 linhas que traduzia JSON de um editor rich-text para PDF – lidando com títulos, parágrafos, listas, citações, links, divisores, tabelas e anexos de imagem, mais toda a formatação inline de texto, em um único arquivo. Sem testes. O objetivo: isolá-la em um módulo limpo e extraível como gem.

Como Trabalhamos

Não começamos escrevendo código. Começamos com um plano – decidindo o design antes de tocar em qualquer arquivo. Depois construímos incrementalmente, um tipo de nó por vez, cada etapa com seus próprios testes e uma checagem do linter antes de avançar. No final, o monolito antigo havia sumido, substituído por 17 arquivos focados.

O que fez o ritmo funcionar foi uma restrição explícita desde o primeiro prompt: a IA pediria permissão antes de cada nova etapa. Diffs pequenos e revisáveis em vez de uma mudança gigante. Essa regra impediu a sessão de virar um amontoado de código que eu teria que limpar depois.

Onde Ficou Interessante

A parte mecânica — extrair, testar, repetir — foi tranquila. A parte interessante foi todo o resto.

Houve momentos em que paramos para avaliar 3 abordagens diferentes para um problema de design antes de escolher uma. Um momento em que percebi que algo estava errado, identifiquei o problema, e aquele instinto virou a melhor refatoração da sessão. Um momento em que paramos de confiar na memória e fomos ler o código-fonte da biblioteca antes de continuar. E uma regressão que apareceu no meio da sessão — um comportamento de formatação que quebrou silenciosamente na refatoração — que corrigimos do jeito certo: teste primeiro, provar que falha, aí sim corrigir.

70 testes, 102 asserções, 0 falhas ao final. Mas esse número não é o ponto.

O Que Ficou Depois da Sessão

À medida que convenções iam surgindo — preferências sobre nomenclatura, formatação, estilo de código — elas eram registradas como regras permanentes em vez de correções pontuais. No final, essas regras estavam sendo aplicadas automaticamente ao código novo, sem precisar lembrar.

É essa parte que se acumula. Não o código de uma sessão específica, mas o entendimento compartilhado que se carrega para a próxima.

A Parte 2 é sobre os prompts específicos que fizeram tudo isso acontecer.

Parte 2 — Prompts que Geraram Ótimas Interações

Os prompts que realmente fizeram essa sessão avançar, agrupados pelo padrão de colaboração que cada um demonstra — com uma nota sobre como cada um se desenrolou.

  1. Comece com Visão e Limites

“We will now refactor Lexxy::PdfRenderer. First and foremost, I envision this class becoming a gem in the future… DO NOT write all of the new nodes in one step, let’s write them one by one, extracting from pdf_renderer one content at a time, and you willask me permission for each one.”

“Vamos agora refatorar o Lexxy::PdfRenderer. Antes de mais nada, eu imagino essa classe se tornando uma gem no futuro… NÃO escreva todos os novos nós de uma vez, vamos escrevê-los um por um, extraindo do pdf_renderer um conteúdo por vez, e você vai me pedir permissão para cada um.”

Como foi: Esse único prompt definiu o destino (um módulo extraível como gem), a estrutura (uma classe por nó) e o ritmo de trabalho (incremental, com permissão a cada passo). Como o ritmo era explícito, a sessão inteira virou uma série de etapas pequenas e revisáveis em vez de um diff gigante. A cláusula “você vai me pedir permissão para cada um” foi a instrução mais importante — ela manteve o humano no controle o tempo todo.

Lição: o melhor prompt inicial não define só o que construir — define como vocês vão trabalhar juntos.

2. Seja Curioso — Questione Qualquer Coisa que Pareça Estranha

“now LexxyPrawn::Node. Why is there only 4 aliases?”

“agora LexxyPrawn::Node. Por que tem só 4 aliases?”

“why base implements a private method for pdf and config, but not for fragments?

“por que a base implementa um método privado para pdf e config, mas não para fragments?”

Como foi: Ambas eram perguntas genuínas, não correções — e as duas encontraram algo. A primeira revelou que 3 dos 4 aliases eram redundantes (mapeando um nome para ele mesmo), então os deletamos. A segunda expôs uma inconsistência de design real e levou a uma decisão deliberada de adicionar o delegador que faltava. A curiosidade fez mais trabalho de design do que qualquer instrução.

Lição: trate o output da IA como um rascunho a ser interrogado. “Por que está assim?” é uma pergunta poderosa.

3. Exija Opções Antes de Decidir

“pros and cons about the tempfile lifecycle proposes”

“prós e contras das propostas de ciclo de vida do tempfile”

“I want you to fold option C so we can better analyze.”

“quero que você inclua a opção C para analisarmos melhor.”

Como foi: Em vez de aceitar a primeira sugestão, pedi uma análise real de trade-offs e explicitamente trouxe uma terceira opção para a mesa. Chegamos a um modelo de ownership com escopo de bloco que era significativamente melhor do que onde havíamoscomeçado. A decisão foi minha, tomada com informação completa.

Lição: force a comparação. “Me dá os trade-offs” transforma a IA de uma máquina de respostas em uma parceira de design.

4. Traga Evidência Real e Questione o Plano

“before going further with the markup approach, check this snippet from prawn-tablemanual…”

“antes de continuar com a abordagem de markup, confira esse trecho do manual doprawn-table…”

“lets discuss, from what I understood from the snippet, the text_fragment can be used in the cell as it is, no need for markup tags, no?”

“vamos discutir — pelo que entendi do trecho, o text_fragment pode ser usado na célula como está, sem precisar de tags de markup, não?”

Como foi: Essa interação foi bem interessante. Colei o manual da biblioteca e questionei o plano com uma hipótese razoável. Em vez de contornar a dúvida, a IA foi ler o código-fonte do prawn-table para resolver definitivamente. O questionamento transformou a resposta de baseada em memória para baseada em evidência.

Lição: uma IA raciocina a partir da memória de treinamento por padrão. Jogar documentação real na mesa – e questionar a abordagem – força a verificação.

5. Confie nos Seus Instintos Arquiteturais

“something bothering me is that wrapped_table node deals directly withaction_text_attachment, although there is a node specialized on it… If CellContent delegates its real ‘rendering power’ to Nodes, we could fix both image and text formatting cases.”

“o que me incomoda é que o wrapped_table node lida diretamente com o action_text_attachment, sendo que existe um nó especializado nisso… Se o CellContent delegar seu ‘poder de renderização’ real para os Nodes, poderíamos resolver tanto o caso de imagem quanto o de formatação de texto.”

Como foi: Percebi a duplicação antes de a IA sinalizar. Esse instinto levou à melhor refatoração da sessão. A IA adicionou uma restrição que eu não havia percebido ainda, mas a direção foi inteiramente minha.

Lição: o seu “isso me incomoda” é sinal, não ruído – identifique o desconforto mesmo antes de ter a solução.

6. Ensine Regras Duráveis, Não Correções Pontuais

“add a new code rule to CLAUDE.md: keyword params with the same name as the variables, can omit the variable…”

“adicione uma nova regra de código ao CLAUDE.md: keyword params com o mesmo nome das variáveis podem omitir a variável…”

“another rule: prefer to use meaningful variable names… except the traditionals, like i for loops or f/ff for simple_form.”

“outra regra: prefira usar nomes de variáveis significativos… exceto os tradicionais, como i para loops ou f/ff para simple_form.”

“but add a new styling rule: whenever you write a block, add an empty line above (unless the block is the first code in the scope) and below…”

“mas adicione uma nova regra de estilo: sempre que escrever um bloco, adicione uma linha em branco acima (a menos que o bloco seja o primeiro código no escopo) e abaixo…”

Como foi: Cada uma dessas virou uma convenção permanente do projeto em vez de uma correção pontual. No final, a IA estava aplicando as regras automaticamente ao código novo sem precisar ser lembrada. Uma até capturou um gotcha do Ruby no meio da sessão — que foi adicionado de volta na regra.

Lição: quando você corrige uma IA, se pergunte se é uma regra. Codificar uma vez rende em todos os arquivos seguintes. Suas convenções se acumulam.

7. Mantenha o Nível de Qualidade

“fix it” (sobre uma regressão de sub/superscript pré-existente que havia sido identificada)

“corrige isso”

Como foi: Prompt curto, retorno grande. A correção veio com um teste de regressão TDD — e, criticamente, provamos que o teste falhava contra o comportamento com bug antes de restaurar a correção.

Lição: quando a IA expõe um bug latente, “corrige isso” deve implicar “e prove que continua corrigido.”

O fio condutor: os prompts mais fortes não eram os mais longos nem os mais técnicos. Eram os que mantinham o humano no controle do design – questionando, exigindo opções, trazendo evidência, codificando regras e controlando o ritmo. A IA digitou; o humano fez a engenharia.

Conclusão — Tudo que Importa, no Mesmo Lugar

No final dessa sessão, tínhamos 17 arquivos focados, 70 testes, 0 falhas e o línter limpo. Mas o output real não foi o código. Foi um conjunto de padrões de colaboração que se sustentaram em condições reais — um legado bagunçado, ambiguidade arquitetural genuína, uma regressão ao vivo, e uma biblioteca cujo comportamento precisamos verificar na fonte.

Aqui estão todas as lições, reunidas:

1. O melhor prompt inicial define como você quer trabalhar, não só o que construir.

Visão + limites + ritmo — os 3, desde o início.

2. “Por que está assim?” é uma pergunta poderosa.

Curiosidade acima de instruções. Questione o output antes de aceitar.

3. “Me dá os trade-offs” transforma uma máquina de respostas em parceira de design.

Não aceite a primeira sugestão. Force a comparação.

4. Traga evidência real e questione o plano.

Uma IA raciocina a partir da memória por padrão. Documentação real — e questionamento genuíno — forçam verificação.

5. Seu desconforto arquitetural é sinal, não ruído.

Identifique-o antes mesmo de ter a solução. A IA ajuda a articular a restrição; a direção vem de você.

6. Quando você corrige uma IA, pergunte se é uma regra.

Codificar uma vez rende em todos os arquivos seguintes. Suas convenções se acumulam.

7. “Corrige isso” deve implicar “e prove que continua corrigido.”

Testes de regressão não são opcionais. Se um bug vale corrigir, vale um teste que teria pego antes.

Os momentos mais valiosos dessa sessão não foram aqueles em que a IA escreveu código. Foram as conversas de design — o vai e vem sobre ownership, duplicação, verificação. O tipo de pensamento que acontece entre dois engenheiros que confiam um no outro o suficiente para questionar.

É assim que parece um bom pair programming. E foi isso que aconteceu aqui.

Ah, e mais uma coisa.

Você acabou de ler um artigo sobre colaboração humano-IA no desenvolvimento de software. A estrutura, a prosa, a introdução, a conclusão, as sete lições — tudo foi escrito pelo Claude, com base em notas de sessão e documentação de arquitetura fornecidas pelo desenvolvedor. Sem edição humana. A contribuição do humano foi a sessão em si: as decisões, os instintos, as perguntas e o código.

Então quando eu disse a IA digitou — era mais literal do que você imaginava.

A questão não é se a IA consegue escrever seus artigos. É se você está fazendo as perguntas certas.

Escrito por: Fillipe Palhares