Prompt engineering para desenvolvedores: técnicas que mudam a qualidade do output
1. Fundamentos do Prompt Engineering: O que Todo Dev Precisa Saber
Prompt engineering é a prática de projetar e refinar entradas textuais para modelos de linguagem (LLMs) com o objetivo de obter saídas previsíveis, precisas e úteis. Para desenvolvedores, dominar essa habilidade é tão essencial quanto saber escrever código limpo — um prompt mal construído pode gerar respostas genéricas, incorretas ou inseguras.
A diferença entre prompts simples e prompts estruturados é dramática. Um prompt como "explique herança em Python" pode retornar uma explicação genérica de 3 parágrafos. Já um prompt estruturado retorna exatamente o que o desenvolvedor precisa:
Prompt simples:
"Explique herança em Python"
Prompt estruturado:
Role: você é um instrutor de Python para desenvolvedores júnior.
Task: explique o conceito de herança em Python.
Context: o aluno já conhece classes e objetos básicos.
Format: use markdown com:
- Definição (máximo 3 linhas)
- Exemplo de código com 2 classes
- Explicação linha a linha do exemplo
- 1 exercício prático
O papel do contexto aqui é crítico: fornecer informações suficientes sem poluir o prompt evita que o modelo "invente" suposições erradas sobre o nível de conhecimento do usuário.
2. Estruturação de Prompts: Template e Padrões que Funcionam
O padrão mais robusto para prompts técnicos é Role + Task + Context + Format. Cada elemento tem uma função específica:
- Role: define a persona do modelo (ex: "você é um engenheiro de software sênior")
- Task: descreve claramente o que deve ser feito
- Context: fornece informações de fundo, restrições ou dados relevantes
- Format: especifica exatamente como a saída deve ser estruturada
Exemplo prático de um prompt mal estruturado:
Prompt ruim:
"Crie uma API REST para gerenciar usuários"
Esse prompt é vago e pode gerar desde um microserviço completo até um snippet de 5 linhas. Agora veja a versão estruturada:
Prompt bem estruturado:
Role: você é um desenvolvedor backend sênior especializado em FastAPI.
Task: gere o código de uma API REST para gerenciamento de usuários.
Context:
- Framework: FastAPI com SQLAlchemy
- Banco: PostgreSQL
- Autenticação: JWT
- Operações: CRUD básico (criar, listar, atualizar, deletar)
Format:
- Retorne APENAS o código em Python, sem explicações
- Use type hints em todas as funções
- Inclua validação de dados com Pydantic
- Comente apenas trechos críticos de segurança
Use delimitadores como "---" ou "###" para separar seções do prompt, facilitando a leitura pelo modelo.
3. Técnicas de Refinamento: Chain-of-Thought e Few-Shot Prompting
Chain-of-Thought (CoT) é uma técnica onde você pede ao modelo para raciocinar passo a passo antes de dar a resposta final. Isso é particularmente útil para tarefas de lógica, debugging ou análise de código.
Prompt com Chain-of-Thought:
"Analise o código abaixo e encontre o bug. Explique seu raciocínio passo a passo antes de dar a resposta final.
def calcular_media(lista):
soma = 0
for i in range(len(lista)):
soma += lista[i]
return soma / len(lista)
Passo 1: [modelo preenche]
Passo 2: [modelo preenche]
Resposta final: [modelo preenche]"
Few-shot prompting consiste em fornecer exemplos dentro do prompt para guiar o comportamento do modelo. É útil quando você precisa de um formato específico de saída:
Few-shot para geração de testes:
Gere testes unitários no formato abaixo:
Exemplo 1:
Função: def somar(a, b): return a + b
Teste:
def test_somar():
assert somar(2, 3) == 5
assert somar(-1, 1) == 0
Exemplo 2:
Função: def multiplicar(a, b): return a * b
Teste:
def test_multiplicar():
assert multiplicar(3, 4) == 12
assert multiplicar(0, 5) == 0
Agora gere testes para:
Função: def dividir(a, b): return a / b
Zero-shot vs few-shot: use zero-shot para tarefas simples e genéricas. Use few-shot quando precisar de consistência em formato, tom ou estilo. Para tarefas complexas como geração de queries SQL, sempre prefira few-shot.
4. Controle de Saída: Especificando Formato, Tom e Restrições
O controle de saída é uma das habilidades mais valiosas para desenvolvedores. Você pode especificar formatos precisos:
Prompt para saída em JSON:
"Liste 3 frameworks web Python populares. Retorne APENAS um JSON array válido com a estrutura:
[
{
"nome": "string",
"ano_lancamento": number,
"criador": "string"
}
]"
Controle de tom e estilo:
Tom técnico e direto:
"Explique o padrão Singleton em Python. Use linguagem técnica, sem analogias. Máximo 10 linhas."
Tom didático para iniciantes:
"Explique o padrão Singleton em Python como se estivesse ensinando um estagiário. Use analogias do mundo real."
Restrições de conteúdo são essenciais para segurança:
Prompt com restrições:
"Gere uma função Python para autenticar usuários.
Restrições:
- NÃO use bibliotecas externas não seguras
- NÃO inclua senhas em texto puro
- Use hash SHA-256 para armazenamento
- Retorne apenas o código, sem comentários de segurança explícitos"
5. Técnicas de Iteração e Depuração de Prompts
A depuração de prompts segue um ciclo: gerar output → analisar falhas → ajustar prompt → regenerar. Para testar variações, ajuste parâmetros como temperatura:
- Temperatura baixa (0.0 - 0.3): saídas determinísticas, boas para código
- Temperatura alta (0.7 - 1.0): saídas criativas, boas para brainstorming
Exemplo de iteração:
Versão 1: "Crie uma função para validar email"
Output: função genérica que só verifica "@"
Versão 2: "Crie uma função Python que valide email usando regex.
Restrição: a regex deve verificar domínio e formato padrão."
Output: função com regex, mas sem tratamento de erros
Versão 3: "Crie uma função Python que valide email com regex.
Inclua: validação de formato, tratamento de exceções,
retorne booleano. Comente cada parte da regex."
Output: função completa e documentada
Para versionamento de prompts em times, mantenha um arquivo YAML ou JSON com histórico:
# prompts_versoes.yaml
v1:
prompt: "Gere função para validar email"
temperatura: 0.7
output_qualidade: baixa
v2:
prompt: "Crie função Python que valide email usando regex"
temperatura: 0.3
output_qualidade: media
v3:
prompt: "Crie função Python que valide email com regex, tratamento de erros e comentários"
temperatura: 0.2
output_qualidade: alta
6. Prompt Engineering para Geração de Código e Documentação
Para geração de código, prompts restritivos são seus melhores amigos. Exemplo para gerar uma API endpoint:
Prompt para código:
Role: especialista em FastAPI
Task: crie um endpoint POST /usuarios
Context:
- Modelo SQLAlchemy: Usuario(id, nome, email, senha_hash)
- Use Pydantic para validação
- Hash de senha com bcrypt
Format:
- Código completo do endpoint
- Inclua tratamento de erro 400 para email duplicado
- Type hints obrigatórios
- NÃO inclua imports desnecessários
Para documentação técnica:
Prompt para documentação:
"Documente a função abaixo seguindo o padrão Google Style Docstring.
Inclua: descrição, parâmetros, retorno, exceções e exemplo de uso.
def calcular_frete(cep_origem, cep_destino, peso, servico='sedex'):
# lógica aqui
pass"
Para evitar alucinações e código inseguro, sempre inclua:
- Restrições explícitas ("NÃO use eval()", "NÃO permita SQL injection")
- Solicitação de verificação ("Antes de responder, verifique se o código não tem vulnerabilidades conhecidas")
7. Integração com Ferramentas do Desenvolvedor: Copilot, Ollama e RAG
Prompts para GitHub Copilot são diferentes de prompts para LLMs locais como Ollama. Copilot funciona melhor com prompts implícitos (comentários de código), enquanto Ollama exige prompts explícitos:
Prompt para Copilot (implícito):
# Função que valida CPF brasileiro
# Retorna True se válido, False caso contrário
# Algoritmo: cálculo dos dígitos verificadores
Prompt para Ollama (explícito):
Role: desenvolvedor Python
Task: crie uma função que valide CPF brasileiro
Context: o CPF tem 11 dígitos, os dois últimos são verificadores
Format: retorne apenas o código com type hints
Em sistemas RAG (Retrieval-Augmented Generation), o prompt deve incluir o contexto recuperado:
Prompt para RAG:
"Use o contexto abaixo para responder. Se o contexto não contiver a informação, diga 'não encontrado'.
Contexto: [documentação recuperada aqui]
Pergunta: Qual a sintaxe para criar uma migration no Django?"
Para pipelines de CI/CD, use prompts com temperatura 0.0 para garantir consistência:
# No arquivo .github/workflows/gerar_docs.yml
- name: Gerar documentação
run: |
echo 'Gere documentação para o código em ./src.
Use markdown. Temperatura: 0.0.' | ollama run codellama
8. Métricas e Avaliação de Qualidade do Output
Critérios objetivos para avaliar outputs:
- Precisão técnica: o código compila? A lógica está correta?
- Relevância: responde exatamente ao que foi perguntado?
- Formato: segue a estrutura solicitada?
- Segurança: contém vulnerabilidades conhecidas?
- Completude: cobre todos os casos especificados?
Para benchmarking entre versões de prompt, use uma planilha ou script:
# benchmark_prompts.py
prompts = {
"v1": "Gere função para validar email",
"v2": "Gere função Python que valide email com regex e tratamento de erros"
}
metricas = {
"compila": [False, True],
"cobre_casos_limite": [0, 3],
"seguro": [True, True]
}
Quando o prompt engineering não resolve? Em casos de:
- Modelo com conhecimento desatualizado (prefira RAG)
- Tarefas que exigem raciocínio matemático complexo (use CoT + few-shot)
- Geração de código muito longo (divida em prompts menores)
Lembre-se: prompt engineering é uma habilidade iterativa. Nenhum prompt sai perfeito na primeira tentativa.
Referências
- OpenAI Prompt Engineering Guide — Guia oficial da OpenAI com estratégias, exemplos e boas práticas para engenharia de prompts.
- Anthropic Prompt Engineering Resources — Documentação da Anthropic sobre técnicas avançadas de prompting para modelos Claude.
- LangChain Prompt Templates Documentation — Tutorial oficial do LangChain sobre criação e versionamento de templates de prompts para aplicações LLM.
- GitHub Copilot Prompt Engineering Best Practices — Guia da Microsoft/GitHub para otimizar prompts no Copilot, com exemplos específicos para geração de código.
- Ollama Prompt Engineering Tips — Repositório oficial do Ollama com dicas de formatação de prompts para modelos locais e otimização de parâmetros.