MÓDULO 4.2

🎯 Prompt Engineering Avançado

Chain-of-Thought, pseudocódigo primeiro, prompting agêntico e as técnicas de decomposição que transformam tarefas complexas em resultados precisos.

7
Tópicos
40
Minutos
Avançado
Nível
Prático
Tipo
1

🔗 Chain-of-Thought para código

Chain-of-Thought (CoT) é a técnica de forçar o modelo a raciocinar explicitamente antes de gerar código. Estudos da Anthropic e Google (2024) mostram que CoT melhora a precisão em 40-60% em problemas de programação complexos. O modelo não é mais rápido — é mais cuidadoso.

📝 Comparativo: Sem CoT vs. Com CoT

Sem CoT (resultado medíocre):

"Implemente uma função que
verifica se um número é primo."

Com CoT (resultado preciso):

"Antes de implementar, analise:
1. Quais casos extremos existem?
   (0, 1, negativos, números grandes)
2. Qual a complexidade ideal para
   o contexto de uso (números até 10^6)?
3. Precisa ser thread-safe?

Depois implemente com TypeScript
e inclua os testes unitários."
1

Frases ativadoras de CoT

"Antes de implementar, analise...", "Pense passo a passo sobre...", "Liste os casos extremos antes de começar...", "Explique sua abordagem antes de escrever código."

2

Quando usar CoT

Algoritmos não triviais, lógica de negócio complexa, refatorações de grande escala, qualquer tarefa onde o erro seja custoso. Não é necessário para CRUD simples ou boilerplate.

3

Revisando o raciocínio

Antes de implementar, peça ao modelo para listar sua abordagem. Você pode corrigir o raciocínio antes do código ser gerado — muito mais barato do que corrigir a implementação depois.

2

📝 Pseudocódigo primeiro — estratégia para alta complexidade

Para tarefas de alta complexidade, separar planejamento de implementação é a técnica mais eficaz. Pedir pseudocódigo primeiro cria um checkpoint natural onde você revisa a lógica antes que qualquer linha de código seja gerada.

🔄 Fluxo em Dois Estágios

1

Estágio 1: Planejamento

"Preciso implementar um sistema de
rate limiting por usuário e por IP.
Antes de implementar, descreva em
pseudocódigo ou texto estruturado:
- A estrutura de dados
- O algoritmo de verificação
- Os casos de borda
- Onde vai residir (middleware, Redis)"
2

Estágio 2: Implementação (após aprovação)

"O plano está bom, com uma mudança:
use sliding window em vez de fixed window
para o rate limiting.

Agora implemente com TypeScript + Redis,
incluindo testes unitários com mock do Redis."

💡 O ROI da Abordagem em Dois Estágios

Corrigir lógica em pseudocódigo: 2 minutos. Corrigir uma implementação errada que já está integrada a outros módulos: 2 horas. Para features críticas de negócio, sempre separe planejamento de execução.

3

🎯 Focar em comportamento, não implementação

Este é o princípio central que diferencia prompts mediocres de prompts profissionais. Especificar implementação limita o agente a soluções que talvez não sejam as melhores para o contexto. Especificar comportamento observável libera o agente para escolher a implementação mais adequada.

✗ Orientado a implementação

"Use o método Array.filter() para
filtrar usuários ativos e depois
use Array.sort() com localeCompare
para ordenar por nome."

Problema: força implementação específica, pode ser subótima para o contexto real.

✓ Orientado a comportamento

"O usuário deve ver apenas membros
ativos da equipe, ordenados
alfabeticamente por nome.
A lista atualiza em tempo real
quando um membro muda de status."

Resultado: agente escolhe a melhor implementação para o stack existente.

📊 Quando orientar a implementação é OK

  • Restrições técnicas reais: "Deve usar nossa lib interna de cache" — aí faz sentido especificar.
  • Integração com sistema existente: "Deve seguir o padrão do módulo X" — contexto legítimo.
  • Migração de código: "Converta este código de callbacks para async/await" — transformação específica.
4

🤖 Prompting agêntico — objetivos de alto nível com Definition of Done

Prompting agêntico é fundamentalmente diferente do prompting conversacional. O agente vai executar múltiplas etapas sem intervenção humana. Sem uma Definition of Done (DoD) clara, ele continua trabalhando além do necessário ou para antes de terminar.

📋 Template de Prompt Agêntico

## Objetivo
Implemente o módulo de autenticação JWT para a API de pagamentos.

## Contexto relevante
@src/app.ts
@src/routes/index.ts
@src/middleware/

## Permissões
- Pode criar novos arquivos em src/auth/ e src/middleware/
- Pode modificar src/routes/index.ts para adicionar rotas de auth
- NÃO deve modificar src/app.ts ou arquivos de migration existentes
- NÃO deve fazer deploy ou commit

## Restrições técnicas
- Use jsonwebtoken e bcrypt (já estão no package.json)
- Siga o padrão de erros existente em @src/utils/errors.ts
- Tokens expiram em 24h (access) e 7d (refresh)

## Definition of Done
A tarefa está completa quando:
1. POST /auth/register cria usuário com senha hasheada
2. POST /auth/login retorna access e refresh token
3. POST /auth/refresh troca refresh token por novo access token
4. Middleware de autenticação protege rotas marcadas
5. Todos os endpoints têm testes unitários passando
6. npm run test passa sem erros

Pause e aguarde aprovação antes de qualquer ação destrutiva.

💡 O Elemento Mais Importante: Permissões

Definir o que o agente pode e não pode fazer é mais crítico do que o objetivo em si. Um agente sem restrições claras pode sobrescrever arquivos errados, fazer chamadas de API não autorizadas ou modificar infraestrutura de produção. Sempre liste permissões explicitamente.

5

🧩 Técnicas de decomposição — dividir sistemas complexos

A regra prática mais eficaz: se a tarefa vai gerar mais de 300 linhas de código, decomponha. Tarefas grandes criam contexto longo que degrada a qualidade do modelo e dificulta a revisão humana. Decomposição é uma habilidade de engenharia, não de prompt.

🔍 Exemplo: Sistema de Pagamentos Decomposto

Tarefa monolítica (falha):

"Implemente o sistema de pagamentos completo com Stripe, planos de assinatura, webhooks e portal do cliente."

Decomposição correta:

  • 1. Schema de banco: tabelas plans, subscriptions, payments, invoices
  • 2. Integração Stripe: criar customer, sincronizar produtos/preços
  • 3. Endpoint de checkout: criar sessão e processar pagamento
  • 4. Webhook handler: processar eventos do Stripe com idempotência
  • 5. Portal do cliente: listar faturas, trocar plano, cancelar

Critérios de uma boa subtarefa

  • Tem objetivo único e claro
  • Produz <300 linhas de código
  • Pode ser testada independentemente
  • Tem critérios de conclusão verificáveis

Ordem de implementação

  • 1.Schema e modelos de dados primeiro
  • 2.Autenticação antes de features
  • 3.Lógica de negócio antes de UI
  • 4.Integrações externas por último
6

♻️ Refactoring por prompt — melhorias sem perder funcionalidade

Refactoring com IA é uma das aplicações mais poderosas — e mais perigosas. Sem invariantes claros definidos, o agente pode mudar a interface pública de uma função, quebrar contratos implícitos ou introduzir mudanças sutis de comportamento. A chave é especificar o que não pode mudar.

📋 Template de Prompt para Refactoring

## Contexto
@src/services/UserService.ts (arquivo a refatorar)
@src/services/UserService.test.ts (testes existentes)

## Objetivo
Refatorar UserService para melhorar testabilidade:
reduzir dependências acopladas e extrair lógica de
validação para funções puras.

## Invariantes (o que NÃO pode mudar)
- Interface pública: assinatura de todos os métodos públicos
- Comportamento: todos os testes existentes devem continuar passando
- Compatibilidade: não modificar como é injetado no sistema (DI)
- Não adicionar dependências externas novas

## Objetivo de melhoria
- Reduzir complexidade ciclomática de createUser() de 12 para <5
- Extrair validateUserData() como função pura testável
- Remover chamada direta ao banco (usar repositório injetado)

## Definition of Done
npm run test passa sem modificar nenhum teste existente

💡 Refactoring Incremental vs. Big-Bang

Prefira sempre refactoring incremental — um módulo por vez, com testes passando a cada etapa. Big-bang refactoring (refatorar tudo de uma vez) com IA gera código que funciona isoladamente mas quebra na integração. Commits pequenos, revisão frequente.

7

🐛 Debug por prompt — contexto correto para resolução rápida

A diferença entre um debug que resolve em uma mensagem e um que leva 10 trocas de mensagem é o contexto fornecido. O agente resolve o que consegue ver. Enviar apenas a mensagem de erro é como pedir diagnóstico médico descrevendo apenas a dor sem dizer onde.

🐛 Template de Debug Eficaz

## Erro
TypeError: Cannot read properties of undefined (reading 'id')
at UserService.createOrder (UserService.ts:47)
at OrderController.post (OrderController.ts:23)

## Stack trace completo
[cole o stack trace completo aqui]

## Código relevante
@src/services/UserService.ts (linhas 40-55)
@src/controllers/OrderController.ts (linhas 18-30)

## Ambiente
- Node.js 22.5.0
- TypeScript 5.4
- Prisma 5.10

## O que já tentei
- Adicionei console.log em UserService.ts:46 — user está undefined
- Verifiquei que userId está chegando corretamente na controller

## Comportamento esperado vs. observado
- Esperado: usuário autenticado sempre tem user populado antes desta chamada
- Observado: user é undefined apenas quando a requisição vem do webhook, não da UI

📊 Taxa de Resolução por Qualidade do Contexto

Apenas mensagem de erro 15%
Erro + código relevante 55%
Template completo (template acima) 92%

Estimativa baseada em análise de sessões de debug com Claude Code (projetos reais, 2025)

💡 Isolamento Antes do Debug

Antes de enviar para o agente, tente isolar o problema: reproduza com o mínimo de código possível. Um bug que reproduz em 20 linhas de código é muito mais fácil de resolver do que um bug em um sistema complexo. O agente (e você) agradece.

Resumo do Módulo 4.2

Chain-of-Thought melhora precisão em 40-60% em problemas complexos — use frases ativadoras explícitas
Pseudocódigo primeiro separa planejamento de execução — corrija lógica em minutos, não horas
Comportamento, não implementação — descreva o que o sistema deve fazer, deixe o agente escolher o como
Prompting agêntico — Objetivo + Contexto + Permissões + Definition of Done. DoD é o mais crítico.
Decomposição — se vai gerar +300 linhas, decomponha. Subtarefas têm critérios verificáveis.
Debug com contexto completo — erro + stack trace + código + ambiente + tentativas = 92% de resolução na primeira

Próximo Módulo:

4.3 — 🏗️ Arquitetura e Design Patterns com IA: MVC, DDD, modelagem de banco e documentação arquitetural