Voltar para todos os artigos
Engenharia de Prompts para Desenvolvedores

Engenharia de Prompts para Desenvolvedores

Um guia prático de engenharia de prompts para desenvolvedores: fornecer contexto rico com código e logs, usar delimitadores e estruturar a saída esperada.

Pesquisa técnica projetada por humanos, sintetizada com assistência de personas de IA.
7 min de leitura

TL;DR / Sumário Executivo

Um guia prático de engenharia de prompts para desenvolvedores: fornecer contexto rico com código e logs, usar delimitadores e estruturar a saída esperada.

💡 TL;DR (Resumo)

A engenharia de prompts é a arte de criar entradas eficazes para modelos de linguagem (LLMs). Para desenvolvedores, as técnicas mais importantes são: fornecer contexto rico (código, logs de erro), usar delimitadores (como ``` ou <xml>), definir um papel claro para a IA (ex: "atue como um dev sênior especialista em Python"), e usar a técnica Chain-of-Thought (CoT), pedindo para a IA "pensar passo a passo" antes de dar a resposta final.


O que é Engenharia de Prompts (e por que devs deveriam se importar)?

Engenharia de Prompts é o processo de estruturar o texto que você fornece a um modelo de linguagem (LLM) para obter a resposta mais precisa, relevante e útil possível. Para um desenvolvedor, isso não é apenas uma "conversa com um chatbot"; é uma nova forma de interagir com uma ferramenta de produtividade poderosa.

Dominar essa habilidade significa:

  • Respostas de código mais precisas: Gerar código que funciona de primeira.
  • Depuração mais rápida: Obter análises de causa raiz em vez de sugestões genéricas.
  • Automação de tarefas: Criar scripts, documentação e testes com mais eficiência.

Técnicas Essenciais para Desenvolvedores

1. Forneça Contexto Rico e Específico

LLMs não têm acesso ao seu ambiente local. Você precisa fornecer todo o contexto necessário.

  • Ruim: "Meu código não funciona, me ajude."
  • Bom: "Estou recebendo um erro TypeError: cannot read property 'map' of undefined em um componente React. Aqui está o código do componente, o erro completo do console e um exemplo do objeto props que ele recebe."

Exemplo Prático:

markdown
typescript // Componente MyComponent.tsx function MyComponent({ items }) { return ( <ul> {items.map(item => <li key={item.id}>{item.name}</li>)} </ul> ); } ``` **Erro do Console:** `TypeError: cannot read property 'map' of undefined` **Objeto `props` recebido:** `{}` (vazio) **Pergunta:** "Atue como um desenvolvedor React sênior. Analise o erro, o componente e o objeto props, e me diga a causa raiz e como posso corrigir o componente para ser mais robusto contra esse erro."

2. Use Delimitadores Claros

Delimitadores dizem à IA exatamente onde começa e termina uma seção de texto (como um trecho de código, um log de erro ou um exemplo). Isso evita que o modelo confunda instruções com dados.

Delimitadores comuns:

  • Aspas triplas: """
  • Crases triplas para blocos de código: ```
  • Tags XML: <codigo>...</codigo>, <erro>...</erro>

Exemplo:

Analise o seguinte código Go delimitado por ```go e sugira melhorias de performance.

```go
func Soma(nums []int) int {
  total := 0
  for _, num := range nums {
    total += num
  }
  return total
}

### 3. Atribua um Papel (Persona)

Instruir a IA a "atuar como" uma persona específica ativa o conhecimento do modelo relacionado àquele domínio, resultando em respostas mais especializadas.

- **Para código:** "Atue como um Engenheiro de Software Principal com 20 anos de experiência em C++ e sistemas de baixa latência."
- **Para segurança:** "Atue como um especialista em segurança de aplicações (AppSec)."
- **Para arquitetura:** "Atue como um Arquiteto de Soluções AWS."

### 4. Chain-of-Thought (CoT) - A "Técnica de Ouro"

Esta é talvez a técnica mais poderosa. Em vez de pedir a resposta final diretamente, peça para a IA "pensar passo a passo". Isso força o modelo a externalizar seu processo de raciocínio, o que geralmente leva a conclusões mais lógicas e corretas.

**Exemplo de depuração:**

**Prompt Simples (ruim):**
> "Corrija este código Python:"
> ```python
> def get_user(id):
>   return users[id]
> ```

**Prompt com CoT (excelente):**
> "Analise o seguinte código Python. Pense passo a passo sobre os potenciais problemas, especialmente em relação a edge cases e erros de runtime. Depois de listar seu raciocínio, sugira uma versão mais robusta do código."
> ```python
> def get_user(id):
>   return users[id]
> ```

**Resposta Esperada da IA:**
> **Raciocínio Passo a Passo:**
> 1. A função assume que a variável `users` existe no escopo, mas ela não é definida.
> 2. A função assume que `users` é um dicionário ou um objeto similar.
> 3. O principal problema é que não há tratamento para o caso em que o `id` não existe em `users`. Isso causaria um `KeyError`.
> 4. O tipo do `id` não é verificado. Se for um tipo inválido, pode causar um erro.
>
> **Código Robusto Sugerido:**
> ```python
> def get_user(users_dict: dict, user_id: int) -> dict | None:
>   """Busca um usuário em um dicionário de forma segura."""
>   return users_dict.get(user_id)
> ```

### 5. "Few-Shot" Prompting (Aprendizado por Exemplo)

Se você quer que a IA gere algo em um formato específico, dê a ela alguns exemplos.

**Exemplo para gerar testes:**

Gere um teste de unidade para a seguinte função JavaScript usando o padrão que eu fornecer.

Função para testar:

javascript
function soma(a, b) { return a + b; }

Exemplo de teste no formato desejado:

javascript
test('deve somar 1 + 2 para ser igual a 3', () => { expect(soma(1, 2)).toBe(3); });

Sua vez: Gere um teste para o caso em que a função soma números negativos.


## Anti-Padrões a Evitar

- **Ambiguidade:** "Faça este código melhor." (Melhor em quê? Performance? Legibilidade? Segurança?)
- **Falta de Contexto:** "Por que estou recebendo um erro?" (Qual erro? Qual código?)
- **Conversas Contínuas Longas:** LLMs têm uma "janela de contexto" limitada. Em conversas muito longas, eles começam a "esquecer" o início. É melhor iniciar uma nova conversa com um prompt completo para uma nova tarefa.

## Prompt Final: Um Template para Desenvolvedores

Use este template como ponto de partida para suas próprias tarefas de desenvolvimento:

```markdown
**# CONTEXTO**
Estou trabalhando em uma aplicação [linguagem/framework] e preciso [objetivo].

**# PERSONA**
Atue como um [papel especialista, ex: expert em segurança de APIs REST].

**# TAREFA**
[Descreva a tarefa de forma clara e específica, ex: "Revise a seguinte função de controller em Node.js e identifique potenciais vulnerabilidades de segurança."]

**# CÓDIGO / DADOS**
` ``[linguagem]
// Cole seu código, log de erro, ou dados aqui
` ``

**# REGRAS DE SAÍDA**
1. Forneça sua resposta em formato de lista (Markdown).
2. Para cada vulnerabilidade, explique o risco e forneça um exemplo de código corrigido.
3. Use a técnica Chain-of-Thought: primeiro explique seu raciocínio, depois apresente a solução.

## Onde os Placeholders "{X}" e "{Y}" Estavam

O erro foi causado por placeholders como `{'{X}'}` e `{'{Y}'}` que estavam no documento. A sintaxe correta para exibir chaves literais dentro de um arquivo `.mdx` é usar uma expressão de string, como `{'{}'}`. A correção foi aplicada.

O `next-mdx-remote`, ao encontrar `{X}` ou `{Y}`, tentava interpretá-los como variáveis JavaScript, o que falhava porque `X` e `Y` não estavam definidos. Isso acionava o erro do parser `acorn`. Ao mudar para `{'{}'}`, instruímos o MDX a simplesmente renderizar a string literal "{}" (ou, no caso, "{X}" e "{Y}"), resolvendo o erro de compilação.