Pular para o conteúdo
Categoria: Desenvolvendo com IA14 min de leitura

Prompt engineering para código: como pedir o que você precisa

Por Schematize Blog ·

Aprenda técnicas de prompt para gerar código melhor: contexto, exemplos few-shot, restrições, chain-of-thought, anatomia de um bom prompt e iteração estruturada com o modelo.

Pedir código a um modelo de linguagem parece simples, mas a diferença entre uma resposta inútil e uma solução pronta para produção quase sempre está no prompt. O modelo não lê sua mente: ele responde ao que você escreveu, com todo o contexto e todas as ambiguidades que você deixou. Neste guia você vai aprender técnicas concretas de prompt engineering voltadas para geração de código — do básico de dar contexto até padrões avançados como few-shot e chain-of-thought — além de um modelo mental para montar prompts e os erros que sabotam os seus resultados.

Por que o prompt muda tudo

Modelos de linguagem grandes funcionam por probabilidade condicionada ao contexto: cada token que eles geram depende de tudo o que veio antes, incluindo o seu prompt. Quando você escreve "faça uma função de login", o modelo precisa adivinhar a linguagem, o framework, o formato de retorno e mil outros detalhes. Cada adivinhação é uma chance de errar.

A boa notícia é que esses modelos aprenderam a generalizar a partir de pouquíssimos exemplos no próprio prompt, sem precisar de retreinamento — capacidade descrita como aprendizado few-shot (Brown et al., 2020). Isso significa que você consegue "ensinar" o comportamento desejado ali na hora, só ajustando o texto. Dominar essa habilidade é o que separa quem briga com a IA de quem a usa como alavanca.

Há um corolário importante: o modelo não tem estado entre conversas e não "lembra" do seu projeto a menos que você diga. Tudo o que ele sabe sobre o seu caso está no que você fornece naquele momento. Prompt engineering, no fundo, é a engenharia de decidir o que entra nessa janela de contexto e como organizá-lo para maximizar a chance de uma resposta correta.

A anatomia de um bom prompt de código

Antes dos princípios isolados, vale ter um esqueleto mental. Um prompt de código robusto costuma ter quatro blocos, nesta ordem:

    [Papel]      Você é um engenheiro Python sênior.
    [Contexto]   Projeto em Python 3.12 com FastAPI 0.110 e Pydantic v2.
                 Convenção: snake_case, erros via exceções.
    [Tarefa]     Escreva um endpoint POST /usuarios que valida o corpo
                 com um modelo Pydantic e persiste via repositório injetado.
                 Trate e-mail duplicado retornando 409.
    [Formato]    Retorne apenas o código do endpoint e o modelo, com type
                 hints. Sem explicações fora do código.

    Esse esqueleto não precisa ser preenchido sempre por inteiro, mas tê-lo na cabeça evita que você esqueça o bloco que mais causa erro: o contexto técnico.

    Princípio 1: dê contexto explícito

    O erro número um é assumir que o modelo conhece seu projeto. Sempre informe:

      Compare os dois prompts:

      Ruim:  faça uma função que busca usuários
      
      Bom:   Em Python 3.12 com SQLAlchemy 2.0, escreva uma função
             buscar_usuarios_ativos(session) que retorna uma lista de
             objetos User com status='ativo', ordenados por data_cadastro
             decrescente. Use type hints e trate o caso de lista vazia.

      O segundo prompt elimina dezenas de ambiguidades e quase sempre produz código aproveitável de primeira.

      Princípio 2: defina restrições e formato de saída

      Diga ao modelo o que você NÃO quer e como quer receber a resposta. Restrições reduzem o espaço de respostas possíveis e aumentam a precisão:

        Definir o formato é especialmente útil quando você vai integrar a saída a um fluxo automatizado. Se você quer só uma função, peça só a função. Se quer um arquivo completo com imports, peça isso explicitamente.

        Um detalhe subestimado: pedir saída estruturada quando você vai processar a resposta por código. Se um agente vai consumir o resultado, peça JSON com um esquema definido e diga "responda apenas com o JSON, sem cercas de markdown". Quanto mais determinístico o formato, menos parsing frágil você escreve depois.

        Princípio 3: forneça exemplos (few-shot)

        A técnica few-shot consiste em mostrar ao modelo um ou mais exemplos do par entrada→saída desejado, antes de pedir o caso real. Isso ancora o estilo, o formato e as convenções. É uma das aplicações mais poderosas da capacidade de aprendizado em contexto descrita por Brown et al. (2020).

        Aqui está como escrevemos validadores neste projeto:
        
        # exemplo
        def validar_email(valor: str) -> bool:
            """Retorna True se valor for um e-mail válido."""
            return bool(re.match(r"[^@]+@[^@]+\.[^@]+", valor))
        
        Agora, no mesmo estilo, escreva validar_cpf(valor: str) -> bool.

        Com o exemplo, o modelo replica a assinatura, a docstring e o padrão de retorno sem você precisar descrevê-los em palavras.

        Quando usar zero-shot, one-shot ou few-shot

        Nem todo prompt precisa de exemplos. Vale calibrar:

          Mais exemplos custam tokens e nem sempre ajudam. Use o mínimo que comunica o padrão.

          Princípio 4: peça raciocínio passo a passo (chain-of-thought)

          Para problemas que exigem várias etapas — algoritmos, lógica de negócio complexa, depuração — vale pedir ao modelo que raciocine antes de codar. Essa técnica, chamada chain-of-thought, melhora significativamente o desempenho em tarefas de raciocínio ao fazer o modelo explicitar os passos intermediários (Wei et al., 2022).

          Na prática:

          Preciso de uma função que detecte ciclos em um grafo dirigido.
          Primeiro, explique a abordagem e os casos de borda.
          Depois, escreva o código em Python.

          Ao forçar a explicação antes da implementação, você reduz erros de lógica e ainda ganha uma documentação do raciocínio. Quem quiser entender o mecanismo por trás disso pode ler Chain-of-Thought: fazendo a IA pensar passo a passo.

          Um cuidado: para tarefas triviais, pedir raciocínio só infla a resposta e gasta tokens. Reserve o chain-of-thought para problemas onde a lógica é o gargalo, não a digitação.

          Princípio 5: itere com feedback preciso

          Raramente o primeiro prompt entrega a versão final, e tudo bem. O segredo é iterar com precisão em vez de repetir "não funcionou":

            A função quebra quando a lista está vazia: retorna None
            em vez de []. Corrija para retornar uma lista vazia e
            adicione um teste para esse caso.

            Feedback específico transforma o modelo num parceiro de depuração eficaz. Feedback vago só gera novas adivinhações.

            Uma tática que economiza tempo: quando uma conversa acumula muitas idas e vindas, o contexto fica poluído com tentativas erradas. Em vez de continuar empurrando correções, recomece um prompt limpo já incorporando tudo o que você aprendeu. Conversas longas e bagunçadas degradam a qualidade tanto quanto prompts vagos.

            Princípio 6: decomponha tarefas grandes

            Não peça "construa um sistema de e-commerce" de uma vez. Modelos têm uma janela de contexto limitada e perdem qualidade quando o pedido é gigante. Quebre em partes:

              Cada etapa vira um prompt focado, com a saída anterior servindo de contexto para a próxima. Essa decomposição também facilita a revisão humana, que continua indispensável.

              Padrões de prompt que funcionam

              Reúna estes "moldes" no seu repertório:

                Dois padrões avançados: testes primeiro e refatoração guiada

                Além dos moldes básicos, dois padrões rendem muito em código de produção.

                O primeiro é pedir os testes antes da implementação. Você descreve o comportamento, pede ao modelo que escreva os casos de teste e só depois implemente o código que os satisfaz. Isso força uma especificação concreta e revela ambiguidades cedo:

                Escreva primeiro os testes (pytest) para uma função
                parse_intervalo(texto) que aceita "1-5" e devolve [1,2,3,4,5],
                cobrindo entrada inválida e intervalo invertido.
                Depois implemente a função que passa em todos os testes.

                O segundo é a refatoração guiada por restrição: cole o código atual e dê uma direção clara de melhoria, sem deixar o modelo "melhorar à vontade":

                Refatore esta função para reduzir a complexidade ciclomática,
                mantendo a assinatura pública e o comportamento idênticos.
                Não introduza dependências novas. Explique cada mudança em uma linha.

                Restringir o escopo da refatoração evita que o modelo reescreva tudo e introduza regressões silenciosas.

                Erros comuns ao escrever prompts

                Evite estas armadilhas frequentes:

                  Prompt engineering para código não é mágica nem adivinhação: é comunicação técnica clara. Quanto melhor você descreve o problema, melhor é a resposta.

                  Estudo de caso: do prompt ruim ao prompt afiado

                  Acompanhe a evolução de um pedido real, para ver os princípios atuando juntos. Suponha que você precise de uma função que faça retry de uma chamada HTTP.

                  Versão 0 — ingênua:

                  faça uma função de retry

                  O modelo adivinha linguagem, biblioteca, número de tentativas, política de espera. Provavelmente entrega algo genérico que não encaixa no seu projeto.

                  Versão 1 — com contexto:

                  Em Python 3.12, escreva uma função que repete uma chamada HTTP
                  com a biblioteca httpx em caso de falha.

                  Melhor, mas ainda ambíguo: quantas tentativas? Espera fixa ou exponencial? Quais erros justificam retry?

                  Versão 2 — específica e restrita:

                  Em Python 3.12 com httpx (cliente síncrono), escreva
                  fetch_com_retry(url, tentativas=3). Faça backoff exponencial
                  (0.5s, 1s, 2s). Repita apenas em erros de conexão e em status 5xx;
                  não repita em 4xx. Use type hints, levante a última exceção se
                  todas as tentativas falharem. Retorne apenas a função.

                  Essa terceira versão elimina quase toda ambiguidade e quase sempre produz código que entra direto no projeto. Note que não ficou mais "bonita" — ficou mais precisa. É esse salto de precisão, não de tamanho, que define um bom prompt.

                  Controlando a aleatoriedade da resposta

                  Um aspecto frequentemente ignorado do prompt engineering é que parte da variação nas respostas não vem do seu texto, e sim da configuração de geração. Modelos têm um parâmetro de temperatura que controla o quanto a saída é "criativa" versus determinística.

                  Para código, a regra prática é simples: temperatura baixa. Você não quer criatividade na hora de gerar uma função de parsing — quer a resposta mais provável e consistente. Temperatura alta faz sentido para brainstorming de abordagens ("liste cinco maneiras diferentes de resolver isto"), mas para a implementação final, o determinismo é seu aliado, inclusive porque torna os resultados mais reproduzíveis quando você ajusta o prompt.

                  Da mesma forma, se a sua tarefa exige saída estruturada estrita (JSON conforme um esquema), prefira recursos de saída estruturada da API quando disponíveis, em vez de só pedir no texto. Eles reduzem a chance de o modelo "escorregar" para um formato livre.

                  Prompts dentro do editor

                  Boa parte do prompt engineering moderno acontece dentro do próprio editor, onde o modelo já tem acesso ao seu código. Ferramentas como o GitHub Copilot: guia completo para programar com IA usam comentários e código ao redor como contexto implícito, enquanto o Cursor: o editor de código com IA que está dominando 2026 permite conversas com referência direta a arquivos. Nesses ambientes, escrever um bom comentário descritivo antes de uma função é, na prática, escrever um prompt.

                  A grande vantagem do editor é que o contexto vem de graça: o modelo já enxerga os tipos, os imports e as funções vizinhas. Isso muda a técnica — em vez de descrever as convenções do projeto em palavras, você as deixa visíveis no arquivo aberto e mantém um comentário-âncora curto descrevendo a intenção. Ainda assim, os mesmos princípios valem: seja específico sobre o comportamento e os casos de borda, mesmo quando o framework já está implícito.

                  Quando você combina prompts bem construídos com um fluxo iterativo, chega perto de conseguir construir software apenas conversando — a base do Vibe coding: o que é e como construir apps só com prompts. A diferença é que, com prompt engineering sólido, você mantém o controle sobre a qualidade.

                  Um fluxo de trabalho completo, do zero ao código revisado

                  Reunindo tudo, um fluxo eficiente de gerar código com IA costuma seguir estes passos:

                    Esse ciclo transforma a IA de "gerador imprevisível" em uma etapa controlada do seu processo de engenharia. O ganho de produtividade vem menos de cada prompt isolado e mais de ter um fluxo repetível em que você confia.

                    Perguntas frequentes

                    Preciso de prompts longos para ter respostas boas? Não. Precisa de prompts específicos. Um prompt curto e preciso ("em Go 1.22, escreva X com type Y, tratando o caso Z") supera um parágrafo genérico. Comprimento não é qualidade.

                    Vale a pena montar uma biblioteca de prompts? Sim. Os moldes que funcionam para o seu stack — formato de testes, estilo de erro, estrutura de endpoint — economizam tempo quando reutilizados. Trate-os como snippets versionados.

                    O modelo erra mesmo com um prompt perfeito? Sim, e por isso execução e revisão são inegociáveis. O prompt aumenta a probabilidade de acerto; não a garante. Trate toda saída como código de um colega que ainda precisa passar pelo seu code review.

                    Devo dizer ao modelo para "pensar passo a passo" sempre? Não. Isso ajuda em tarefas de raciocínio (algoritmos, lógica complexa, depuração) e atrapalha em tarefas triviais, onde só infla a resposta. Use com critério.

                    Conclusão

                    A qualidade do código gerado por IA é, em grande medida, um reflexo da qualidade do seu prompt. Dar contexto explícito, definir restrições, usar exemplos few-shot na dose certa, pedir raciocínio passo a passo quando a lógica é o gargalo e iterar com feedback preciso são técnicas que transformam o modelo de um gerador caótico em um colaborador confiável. Tenha na cabeça a anatomia de um bom prompt — papel, contexto, tarefa e formato — e construa um repertório de moldes para o seu stack. Trate o prompt como um artefato de engenharia: refine, versione mentalmente os que funcionam e revise sempre a saída. O modelo é poderoso, mas é você quem o direciona.

                    Referências

                      Leituras relacionadas

                      Nenhum comentário ainda

                      Seja o primeiro a comentar.

                      Deixe seu comentário

                      Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

                      Entrar com Canverly