Refinamento iterativo: exemplos, testes e interview pattern
Objetivos de aprendizagem
- Usar 2–3 exemplos concretos de input/output quando descrições em prosa são interpretadas de forma inconsistente (task statement 3.5).
- Aplicar iteração guiada por testes: escrever a suíte primeiro e iterar compartilhando as falhas.
- Usar o interview pattern para levantar considerações de design antes de implementar em domínios pouco familiares.
- Decidir entre reportar todos os problemas numa única mensagem (problemas que interagem) ou sequencialmente (problemas independentes).
- Corrigir edge cases fornecendo casos de teste específicos com entrada e saída esperada.
Exemplos concretos vencem prosa ambígua
Quando você descreve uma transformação em prosa ("normalize os números de telefone") e recebe resultados inconsistentes entre execuções, o problema não é capacidade — é ambiguidade: a prosa admite várias interpretações válidas. O exam guide é explícito: exemplos concretos de input/output são a forma mais eficaz de comunicar a transformação esperada. Dois ou três exemplos bem escolhidos eliminam classes inteiras de interpretação errada:
Normalize telefones para E.164 (Brasil como default). Exemplos:
- "(11) 98765-4321" → "+5511987654321"
- "011 8765 4321" → "+551187654321" (fixo, sem 9)
- "+1 (415) 555-0100" → "+14155550100" (mantém país explícito)
Se o número for inválido/incompleto, retorne null — não invente dígitos.
Escolha os exemplos como escolheria casos de teste: um caso típico, um caso com formato alternativo e um caso de borda (inclusive o comportamento de erro). Exemplo que só repete o caso óbvio não desambigua nada.
Iteração guiada por testes
O fluxo test-driven com o Claude Code: 1) escreva (ou peça e revise) a suíte de testes cobrindo comportamento esperado, edge cases e requisitos de performance antes da implementação; 2) peça a implementação; 3) rode os testes e compartilhe as falhas literais (nome do teste, assertion, valores esperado/obtido); 4) repita até verde. A falha de teste é o feedback mais objetivo possível — muito superior a "ainda não está certo".
"""Suite escrita ANTES da implementacao — os testes definem o contrato.
Compartilhar a saida do pytest com o Claude a cada iteracao e o passo 3
do ciclo: a falha literal (esperado vs obtido) guia a correcao.
"""
import pytest
from phone import normalize_phone
def test_celular_com_ddd_entre_parenteses():
assert normalize_phone("(11) 98765-4321") == "+5511987654321"
def test_fixo_sem_nono_digito():
assert normalize_phone("011 8765 4321") == "+551187654321"
def test_mantem_codigo_de_pais_explicito():
assert normalize_phone("+1 (415) 555-0100") == "+14155550100"
@pytest.mark.parametrize("invalido", ["", "abc", "119"])
def test_invalido_retorna_none_sem_inventar_digitos(invalido):
assert normalize_phone(invalido) is None
Note o último teste: edge case com entrada e saída esperada explícitas. É assim que o exame espera que você corrija, por exemplo, valores nulos num script de migração — não com "trate valores nulos direito", e sim com o caso concreto que falha hoje e o resultado esperado.
Interview pattern: perguntas antes de código
Em domínios que você não domina (estratégia de cache, sistemas distribuídos, um subsistema legado), você não sabe o que não sabe — e um prompt direto herda seus pontos cegos. O interview pattern inverte o fluxo: peça ao Claude que faça perguntas antes de implementar ("Antes de escrever código, entreviste-me sobre requisitos, restrições e failure modes que eu deva considerar"). Isso traz à tona considerações que você não tinha antecipado — invalidação de cache, modos de falha, requisitos de consistência — antes de o código existir, quando mudar de rumo é barato.
flowchart TD
A[Pedido em domínio pouco familiar] --> B[Interview pattern:
Claude pergunta requisitos,
restrições, failure modes]
B --> C[Decisões de design explícitas]
C --> D[Suíte de testes escrita primeiro
comportamento + edge cases + performance]
D --> E[Implementação]
E --> F{Testes passam?}
F -- Não --> G[Compartilhar falhas literais
esperado vs obtido]
G --> E
F -- Sim --> H[Concluído]
Uma mensagem ou várias? Problemas que interagem vs independentes
Você revisou a saída e encontrou vários problemas. Como reportar?
| Situação | Estratégia | Por quê |
|---|---|---|
| Os problemas interagem (corrigir um afeta o outro — ex.: o tratamento de timezone e o de formato de data no mesmo parser) | Todos numa única mensagem detalhada | Corrigir isoladamente gera soluções que se invalidam mutuamente; o Claude precisa ver o conjunto para desenhar uma correção coerente |
| Os problemas são independentes (typo na doc, log faltando, teste flaky sem relação) | Sequencialmente, um por vez | Iterações pequenas e verificáveis; cada correção é validada antes da próxima, sem misturar diffs |
Pegadinhas da prova
- Distrator típico: responder a resultados inconsistentes reescrevendo a prosa "com mais detalhes" — mais prosa ambígua; a resposta do exame é 2–3 exemplos concretos de input/output.
- Distrator típico: iterar com feedback vago ("ainda está errado, tente de novo") em vez de compartilhar a falha de teste literal com esperado vs obtido.
- Distrator típico: escrever os testes depois da implementação para "validar o que foi feito" — o valor do padrão está em os testes definirem o contrato antes.
- Distrator típico: em domínio desconhecido, gastar horas escrevendo uma spec upfront gigante em vez de usar o interview pattern para o Claude levantar o que você não anteciparia.
- Distrator típico: reportar problemas que interagem um por vez "para simplificar" — cada correção parcial invalida a anterior; interagentes vão juntos numa única mensagem.
Resumo em 5 linhas
- Prosa interpretada de forma inconsistente → 2–3 exemplos concretos de input/output (típico, variante, edge case com comportamento de erro).
- Test-driven iteration: suíte primeiro (comportamento, edge cases, performance), depois implementação, depois compartilhar falhas literais até verde.
- Edge case quebrado corrige-se com caso de teste específico (entrada + saída esperada), não com pedido genérico.
- Interview pattern: em domínio pouco familiar, peça perguntas antes do código — expõe considerações (invalidação de cache, failure modes) que você não anteciparia.
- Problemas que interagem → uma única mensagem detalhada; problemas independentes → correções sequenciais verificáveis.
Documentação oficial
- Claude Code best practices
- Use examples (multishot prompting)
- Claude Code: best practices for agentic coding
Questões de fixação
1. Você pediu "converta os logs para formato estruturado" e cada execução produz um JSON com chaves diferentes. Qual é a correção mais eficaz?
Gabarito: C. Interpretação inconsistente de prosa se resolve com exemplos concretos de input/output — eles definem o contrato sem ambiguidade. A adiciona mais prosa vaga. B não ataca a causa (ambiguidade permanece para qualquer modelo). D não muda a especificação; a inconsistência continuaria entre conversas.
2. Um script de migração gerado pelo Claude falha quando a coluna middle_name é nula. Qual mensagem de refinamento segue a prática do exame?
Gabarito: B. Caso específico com entrada, comportamento observado e saída esperada — feedback objetivo que orienta a correção exata. A é vago e força o Claude a adivinhar o edge case. C descarta trabalho válido por um problema pontual. D mascara erros em vez de tratar o caso nulo — "nunca falhar" silenciosamente corromperia a migração.
3. Você vai implementar uma camada de cache para um serviço que não conhece a fundo, e suspeita que existam requisitos (invalidação, consistência, falhas) que você não sabe enumerar. Qual técnica o exame recomenda como primeiro passo?
Gabarito: A. O interview pattern existe exatamente para expor considerações que o desenvolvedor não anteciparia em domínio pouco familiar — antes de o código existir. B descobre os requisitos da pior forma possível. C resolve ambiguidade de transformação, não levantamento de requisitos de design. D confunde mecanismos: plan mode explora e planeja, mas não substitui a entrevista de requisitos com o desenvolvedor.
4. A revisão da implementação de um parser revelou: (1) datas sem timezone tratadas errado e (2) o formato de saída de datas depende do mesmo trecho — mudar um afeta o outro. Também há (3) um typo num comentário. Como reportar?
Gabarito: D. A regra do task statement 3.5: problemas que interagem vão juntos numa única mensagem (corrigir timezone e formato isoladamente geraria soluções que se invalidam); independentes (o typo) podem ir sequencialmente. A trata interagentes como independentes — retrabalho garantido. B abandona contexto útil à toa. C junta tudo mas força serialização artificial da correção interagente.