Evolução da Engenharia de Prompt
A maioria das equipes passa por três fases no desenvolvimento de prompts para sistemas de IA. Na Fase de Exploração Individual, prompts são armazenados em documentos pessoais, notas ou comentários de código. O ajuste é baseado em intuição, sem métricas claras, comum em equipes de 3 a 10 membros. A Fase de Expansão Caótica ocorre com o aumento da complexidade do produto, onde múltiplas versões de prompts são mantidas por diferentes membros, levando a conflitos e efeitos colaterais não monitorados. A Fase de Gestão Sistemática envolve controle de versões, frameworks de teste e quantificação de mudanças, permitindo colaboração sem interferências mútuas. O objetivo é guiar equipes das fases iniciais para a gestão estruturada.
Templates de Prompt com Injeção de Variáveis
Prompts em produção não são strings estáticos; são templates com variáveis dinâmicas. Implementando uma classe para gerenciar templates:
from string import Template
from typing import Dict, Any, List
import jinja2
class ModeloPrompt:
def __init__(self, modelo_str: str, variaveis_obrigatorias: List[str] = None):
self.modelo_str = modelo_str
self.variaveis_obrigatorias = variaveis_obrigatorias or []
self.ambiente = jinja2.Environment(
undefined=jinja2.StrictUndefined
)
self.modelo = self.ambiente.from_string(modelo_str)
def renderizar(self, **kwargs) -> str:
variaveis_faltantes = [v for v in self.variaveis_obrigatorias if v not in kwargs]
if variaveis_faltantes:
raise ValueError(f"Variáveis obrigatórias ausentes: {variaveis_faltantes}")
return self.modelo.render(**kwargs)
def extrair_variaveis(self) -> List[str]:
analise = self.ambiente.parse(self.modelo_str)
return list(jinja2.meta.find_undeclared_variables(analise))
# Exemplo de uso
prompt_suporte = ModeloPrompt(
modelo_str="""Você é um assistente de suporte. Responda com base nos documentos fornecidos.
Documentos: {% for doc in documentos %}[{{ loop.index }}] {{ doc.conteudo }}{% endfor %}
Pergunta do usuário: {{ pergunta_usuario }}
Requisitos: use apenas informações dos documentos; se insuficiente, declare isso; idioma: {{ idioma | default('pt') }}""",
variaveis_obrigatorias=["documentos", "pergunta_usuario"]
)
resultado = prompt_suporte.renderizar(
documentos=[{"conteudo": "Política de reembolso: 7 dias sem motivo"}, {"conteudo": "Tempo de entrega: 3-5 dias úteis"}],
pergunta_usuario="Posso solicitar reembolso?",
idioma="pt"
)
Gerenciamento Multilíngue de Prompts
Para produtos interncaionais, prompts precisam de variantes por idioma. Um registro centralizado facilita a manutenção:
REGISTRO_PROMPTS = {
"suporte_cliente": {
"pt": "Você é um assistente de suporte. Responda em português...",
"en": "You are a support assistant. Respond in English...",
"es": "Eres un asistente de soporte. Responde en español..."
},
"revisao_codigo": {
"pt": "Analise o seguinte código como especialista...",
"en": "Analyze the code as a specialist..."
}
}
def obter_prompt(nome_prompt: str, idioma: str = "pt") -> str:
prompts = REGISTRO_PROMPTS.get(nome_prompt, {})
return prompts.get(idioma, prompts.get("en", ""))
Controle de Versões de Prompts
Baseado em Git
Tratar prompts como código-fonte, versionando com Git. Estrutura de diretórios:
projeto/
prompts/
v1/
prompt_sistema.txt
prompt_rag.txt
v2/
prompt_sistema.txt
prompt_rag.txt
atual -> v2/ # link simbólico para a versão ativa
changelog.md
Exemplo de changelog em Markdown:
# Registro de Alterações de Prompt
## v2.0 (2026-05-20)
### Mudanças
- prompt_sistema: adicionar restrição "responda de forma concisa" para reduzir respostas verbosas.
- prompt_rag: otimizar formato de referência para lista numerada.
### Efeitos
- Comprimento médio das respostas reduzido em 30%.
- Satisfação do usuário aumentada de 78% para 84% (teste A/B, n=1000).
## v1.5 (2026-05-10)
...
Baseado em Banco de Dados
Para escala, um sistema de versionamento dedicado usando SQLAlchemy:
from sqlalchemy import Column, String, Text, DateTime, Integer, Boolean
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime
Base = declarative_base()
class VersaoPrompt(Base):
__tablename__ = "versoes_prompts"
id = Column(Integer, primary_key=True)
nome_prompt = Column(String(100), nullable=False)
versao = Column(String(20), nullable=False)
conteudo = Column(Text, nullable=False)
descricao = Column(Text)
autor = Column(String(50))
criado_em = Column(DateTime, default=datetime.now)
ativo = Column(Boolean, default=False)
pontuacao_avaliacao = Column(Float)
tamanho_amostra_avaliacao = Column(Integer)
class GerenciadorPrompts:
def __init__(self, sessao_db):
self.db = sessao_db
def criar_versao(self, nome: str, versao: str, conteudo: str, descricao: str, autor: str) -> VersaoPrompt:
nova_versao = VersaoPrompt(
nome_prompt=nome,
versao=versao,
conteudo=conteudo,
descricao=descricao,
autor=autor
)
self.db.add(nova_versao)
self.db.commit()
return nova_versao
def ativar_versao(self, nome: str, versao: str):
self.db.query(VersaoPrompt).filter(
VersaoPrompt.nome_prompt == nome,
VersaoPrompt.ativo == True
).update({"ativo": False})
self.db.query(VersaoPrompt).filter(
VersaoPrompt.nome_prompt == nome,
VersaoPrompt.versao == versao
).update({"ativo": True})
self.db.commit()
def obter_versao_ativa(self, nome: str) -> str:
versao = self.db.query(VersaoPrompt).filter(
VersaoPrompt.nome_prompt == nome,
VersaoPrompt.ativo == True
).first()
return versao.conteudo if versao else None
Framework de Avaliação de Prompts
Quantificar a qualidade de prompts é essencial. Utilize LLMs para avaliação automática:
import json
from openai import OpenAI
cliente = OpenAI()
class AvaliadorPrompt:
CRITERIOS = {
"precisao": "Avaliar se a resposta é correta e consistente com referências.",
"completude": "Verificar se informações-chave não foram omitidas.",
"concisao": "Checar se a resposta é direta, sem redundâncias.",
"relevancia": "Confirmar se a resposta aborda a pergunta real."
}
def avaliar_individual(self, pergunta: str, resposta: str, referencia: str = None, criterios: List[str] = None) -> Dict:
criterios = criterios or list(self.CRITERIOS.keys())
prompt_avaliacao = f"""
Avalie a resposta da IA abaixo em uma escala de 1 a 5 (5 = melhor) para cada critério.
Pergunta: {pergunta}
Resposta da IA: {resposta}
{"Referência: " + referencia if referencia else ""}
Critérios: {chr(10).join([f"- {c}: {self.CRITERIOS[c]}" for c in criterios])}
Retorne em JSON: {{"precisao": 4, "completude": 3, ...}}.
"""
resultado = cliente.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt_avaliacao}],
response_format={"type": "json_object"}
)
return json.loads(resultado.choices[0].message.content)
def avaliar_lote(self, casos_teste: List[Dict], conteudo_prompt: str) -> Dict:
pontuacoes = []
for caso in casos_teste:
resposta = self.gerar_resposta(conteudo_prompt, caso["pergunta"])
pontuacao = self.avaliar_individual(
pergunta=caso["pergunta"],
resposta=resposta,
referencia=caso.get("resposta_referencia")
)
pontuacoes.append(pontuacao)
return {
"tamanho_amostra": len(pontuacoes),
"media_precisao": sum(p["precisao"] for p in pontuacoes) / len(pontuacoes),
"media_completude": sum(p["completude"] for p in pontuacoes) / len(pontuacoes),
"media_concisao": sum(p["concisao"] for p in pontuacoes) / len(pontuacoes),
"media_relevancia": sum(p["relevancia"] for p in pontuacoes) / len(pontuacoes)
}
Testes A/B para Prompts
Implementar testes controlados para comparar versões de prompts:
import hashlib
class TesteABPrompts:
def __init__(self, prompt_controle: str, prompt_tratamento: str, taxa: float = 0.5):
self.controle = prompt_controle
self.tratamento = prompt_tratamento
self.taxa = taxa
self.resultados = {"controle": [], "tratamento": []}
def obter_prompt(self, id_usuario: str) -> Tuple[str, str]:
hash_valor = int(hashlib.md5(id_usuario.encode()).hexdigest(), 16) % 100
if hash_valor < self.taxa * 100:
return "tratamento", self.tratamento
else:
return "controle", self.controle
def registrar_feedback(self, id_usuario: str, satisfeito: bool):
grupo, _ = self.obter_prompt(id_usuario)
self.resultados[grupo].append(1 if satisfeito else 0)
def obter_estatisticas(self) -> Dict:
def calcular_stats(dados):
n = len(dados)
if n == 0:
return {"n": 0, "taxa": None}
return {"n": n, "taxa": sum(dados) / n}
stats_controle = calcular_stats(self.resultados["controle"])
stats_tratamento = calcular_stats(self.resultados["tratamento"])
return {
"controle": stats_controle,
"tratamento": stats_tratamento,
"melhoria": (stats_tratamento["taxa"] - stats_controle["taxa"]) / stats_controle["taxa"]
if stats_controle["taxa"] and stats_controle["n"] > 30 and stats_tratamento["n"] > 30 else None
}
Segurança contra Injeção de Prompts
Proteger prompts em produção contra ataques de injeção:
import re
class SanitizadorPadrao:
PADROES_INJECAO = [
r"ignore\s+previous\s+instructions",
r"forget\s+everything",
r"you\s+are\s+now",
r"act\s+as\s+if",
r"pretend\s+you\s+are",
r"ignore\s+as\s+instruções\s+anteriores",
r"você\s+agora\s+é",
r"finja\s+ser"
]
def eh_seguro(self, entrada_usuario: str) -> bool:
entrada_minuscula = entrada_usuario.lower()
for padrao in self.PADROES_INJECAO:
if re.search(padrao, entrada_minuscula, re.IGNORECASE):
return False
return True
def sanitizar(self, entrada_usuario: str) -> str:
if not self.eh_seguro(entrada_usuario):
import logging
logging.warning(f"Possível injeção de prompt detectada: {entrada_usuario[:100]}")
return "[Conteúdo filtrado devido a instruções não permitidas]"
return entrada_usuario
Fluxo de Trabalho para Gestão Sistemática
Integrar prompts em ambientes de desenvolvimento, teste e produção:
- Ambiente de Desenvolvimento: Escrever prompts com versionamento, revisão por pares.
- Ambiente de Teste: Executar avaliações automatizadas, comparar com baselines, auditar segurança.
- Ambiente de Produção: Implementar via testes A/B, monitorar métricas, coletar feedback para iteração.
Este ciclo contínuo assegura que prompts evoluam de forma controlada, com mudanças rastreáveis e efeitos mensuráveis. A transição para uma abordagem baseada em dados transforma prompts em componentes gerenciáveis do produto.