Noções Básicas de Engenharia de Prompt e Contexto
9 exemplos para você começar com Engenharia de Prompt e Contexto - 6 básicos e 3 intermediários.
Pré-requisitos
- Instale o SDK oficial:
pip install anthropic. - Defina sua chave de API como uma variável de ambiente:
export ANTHROPIC_API_KEY=sk-ant-.... - Todos os exemplos usam
client.messages.create(...)do pacote Pythonanthropic.
Exemplos Básicos
1. O Prompt Ingênuo e Inchado
O ponto de partida que a maioria das equipes envia acidentalmente: colar um arquivo inteiro quando apenas algumas linhas importam.
import anthropic
client = anthropic.Anthropic()
with open("user_service.py") as f:
entire_file = f.read() # pode ter mais de 2.000 linhas
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=300,
messages=[{
"role": "user",
"content": f"Esta função valida o formato do e-mail?\n\n{entire_file}",
}],
)- O arquivo inteiro é enviado, mesmo que a pergunta seja sobre uma única função.
- Cada linha extra em
entire_fileé cobrada como um token de entrada em cada chamada. - Este padrão é o modo de falha padrão, não um caso extremo, pois requer zero pensamento extra para escrever.
- Nada aqui está errado sintaticamente, é por isso que é fácil de perder na revisão.
2. Cortando para o Trecho Relevante
A mesma pergunta, respondida enviando apenas a função em questão.
import anthropic
client = anthropic.Anthropic()
relevant_function = '''
def validate_email(address: str) -> bool:
return "@" in address and "." in address.split("@")[-1]
'''
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=300,
messages=[{
"role": "user",
"content": f"Esta função valida o formato do e-mail?\n\n{relevant_function}",
}],
)- O prompt agora contém exatamente o código sobre o qual a pergunta é, nada mais.
- Menos tokens de entrada significam um custo menor para exatamente a mesma pergunta.
- Extrair o trecho relevante é a única etapa manual que esta abordagem exige.
- Este é o prompting de contexto mínimo: envie apenas o que a tarefa precisa.
3. Medindo a Diferença de Tokens
Antes de confiar que o corte realmente ajudou, meça-o.
import anthropic
client = anthropic.Anthropic()
def count_tokens(text: str, model: str = "claude-sonnet-5") -> int:
result = client.messages.count_tokens(
model=model,
messages=[{"role": "user", "content": text}],
)
return result.input_tokens
full_file_tokens = count_tokens(open("user_service.py").read())
snippet_tokens = count_tokens(relevant_function)
print(f"Arquivo completo: {full_file_tokens} tokens")
print(f"Trecho: {snippet_tokens} tokens")count_tokensrelata tokens de entrada sem gerar uma conclusão, portanto, a medição é quase gratuita.- Comparar antes e depois transforma "isso parece menor" em um número real que você pode colocar em um relatório de custos.
- Execute isso uma vez por modelo de prompt durante o desenvolvimento, não em cada chamada de produção.
- Se o trecho não for significativamente menor que o arquivo completo, a etapa de corte não está fazendo seu trabalho.
4. Um Modelo de Prompt Reutilizável
Instruções repetidas em cada chamada desperdiçam tokens tanto quanto um documento superdimensionado.
SYSTEM_PROMPT = "Você é um revisor de código. Responda em um parágrafo curto."
def review(snippet: str, question: str) -> str:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=200,
system=SYSTEM_PROMPT,
messages=[{"role": "user", "content": f"{question}\n\n{snippet}"}],
)
return response.content[0].text- Corrigir o prompt do sistema em um local mantém as instruções de cada chamada curtas e consistentes.
- A parte variável do prompt (
snippet,question) é a única coisa que muda a cada chamada. - Essa separação também torna óbvio, de relance, qual é o custo fixo versus o custo por chamada.
- Um modelo organizado é um pré-requisito para as técnicas de sumarização e segmentação abordadas mais adiante nesta seção.
5. Descartando Histórico de Conversa Obsoleto
Em um chat com várias voltas, as voltas antigas que não importam mais custam tokens se você continuar reenviando-as.
def trimmed_history(messages: list[dict], keep_last: int = 4) -> list[dict]:
# Mantenha apenas as voltas mais recentes; descarte tudo o que for mais antigo.
return messages[-keep_last:]
full_history = [
{"role": "user", "content": "O que este repositório faz?"},
{"role": "assistant", "content": "É um serviço de faturamento..."},
{"role": "user", "content": "Adicione uma nova tentativa ao manipulador de webhook."},
{"role": "assistant", "content": "Aqui está a função atualizada..."},
{"role": "user", "content": "Agora adicione um teste unitário para isso."},
]
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=400,
messages=trimmed_history(full_history, keep_last=4),
)- Cada volta anterior em
messagesé reenviada como tokens de entrada na próxima chamada, portanto, o histórico fica mais caro quanto mais longa uma conversa dura. trimmed_historyé uma ferramenta bruta: mantém a recência, não a relevância, portanto, use-a quando voltas mais antigas genuinamente deixarem de importar.- Para conversas onde uma volta inicial permanece relevante durante todo o processo, cortar apenas pela recência pode descartar algo que você ainda precisa.
- Esta é a mesma ideia de contexto mínimo aplicada ao estado da conversa em vez de um único documento.
6. Excluindo Campos Irrelevantes de Dados Estruturados
A mesma disciplina se aplica a JSON ou linhas de banco de dados, não apenas a arquivos de origem.
raw_record = {
"id": "usr_9f2",
"email": "a@example.com",
"created_at": "2024-01-02T00:00:00Z",
"internal_flags": {"beta": True, "region_shard": "us-east-2"},
"last_login_ip": "10.0.4.12",
"support_notes": "..." * 500, # campo longo de texto livre
}
def trim_for_prompt(record: dict) -> dict:
return {k: record[k] for k in ("id", "email", "created_at")}
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=100,
messages=[{
"role": "user",
"content": f"Resuma esta conta: {trim_for_prompt(raw_record)}",
}],
)- Dados estruturados têm o mesmo problema que arquivos de origem: é fácil passar o objeto inteiro em vez dos campos que a tarefa precisa.
trim_for_prompté uma lista de permissões explícita, que é mais segura do que uma lista de negação ad hoc que mantém silenciosamente novos campos adicionados posteriormente.- Campos longos de texto livre como
support_notessão exatamente o tipo de coisa que infla silenciosamente as contagens de tokens. - Este padrão se generaliza para qualquer resposta de API ou linha de banco de dados que um pipeline alimenta em um prompt.
Exemplos Intermediários
7. Um Seletor de Trechos de Contexto Mínimo
Em vez de escolher manualmente um trecho, classifique os candidatos por relevância e mantenha apenas os poucos principais.
import anthropic
client = anthropic.Anthropic()
def select_relevant_snippets(question: str, candidates: list[str], keep: int = 2) -> list[str]:
# Uma passagem de relevância barata: peça a um modelo rápido para pontuar cada candidato.
scored = []
for snippet in candidates:
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=5,
messages=[{
"role": "user",
"content": f"Pergunta: {question}\nTrecho:\n{snippet}\n\nRelevância 0-10, apenas número:",
}],
)
score = int(response.content[0].text.strip() or 0)
scored.append((score, snippet))
scored.sort(reverse=True, key=lambda pair: pair[0])
return [snippet for _, snippet in scored[:keep]]
top_snippets = select_relevant_snippets(
"Como uma falha de pagamento é retentada?",
candidates=[billing_module_src, auth_module_src, retry_queue_src],
keep=2,
)- Um modelo barato como o Haiku 4.5 pontua a relevância muito mais barato do que pagar para enviar todos os candidatos ao modelo caro.
- Apenas os trechos com maior pontuação vão para o prompt real enviado ao modelo mais forte que realiza a tarefa real.
- Esta é a segmentação de modelos aplicada à própria etapa de seleção, não apenas à resposta final.
- Para uma base de código, um grafo de dependências é uma versão mais rápida e precisa dessa mesma ideia; veja a página dedicada a essa técnica.
8. Combinando Corte com Orçamento de Tokens
Um orçamento de janela de contexto limita o quanto pode ser enviado, e o corte é como você fica dentro dele.
MAX_CONTEXT_TOKENS = 4000
def build_prompt_within_budget(question: str, snippets: list[str]) -> str:
prompt = question
used = count_tokens(prompt)
for snippet in snippets:
snippet_tokens = count_tokens(snippet)
if used + snippet_tokens > MAX_CONTEXT_TOKENS:
break # pare de adicionar trechos assim que o orçamento for atingido
prompt += f"\n\n{snippet}"
used += snippet_tokens
return prompt
final_prompt = build_prompt_within_budget(
"Resuma as alterações recentes na lógica de retentativa.",
snippets=[retry_queue_diff, billing_module_diff, changelog_excerpt],
)- Definir um
MAX_CONTEXT_TOKENSexplícito transforma "mantenha o prompt pequeno" em uma regra que o código impõe, não um hábito que os engenheiros precisam lembrar. - Os trechos são adicionados em ordem de prioridade, então o material mais relevante sobrevive se o orçamento forçar um corte.
- Essa mesma ideia de orçamento, aplicada a um agente de longa duração em vez de uma única chamada, é o que um ADR de orçamento de janela de contexto documenta formalmente.
- Um orçamento muito apertado omite silenciosamente material relevante, portanto, escolha-o com base nas necessidades medidas, não em um número redondo.
9. Medindo Economias em um Pipeline Completo
Junte as peças anteriores e relate o impacto real do custo do corte.
def compare_strategies(question: str, full_document: str, trimmed_snippet: str) -> dict:
return {
"full_document_tokens": count_tokens(f"{question}\n\n{full_document}"),
"trimmed_tokens": count_tokens(f"{question}\n\n{trimmed_snippet}"),
}
result = compare_strategies(
"Este arquivo lida corretamente com retentativas?",
full_document=open("billing_service.py").read(),
trimmed_snippet=relevant_function,
)
savings_pct = 100 * (1 - result["trimmed_tokens"] / result["full_document_tokens"])
print(f"Redução de tokens: {savings_pct:.0f}%")- Esta é a mesma chamada
count_tokensdo exemplo 3, aplicada no nível do pipeline em vez de um prompt de cada vez. - Relatar uma porcentagem de redução, em vez de uma contagem bruta de tokens, torna as economias significativas para partes interessadas não técnicas.
- Execute essa comparação sempre que alterar como o contexto é montado, para que uma regressão no tamanho do prompt seja detectada da mesma forma que uma regressão de desempenho seria.
- As economias de tokens se acumulam em cada chamada que uma carga de trabalho faz, portanto, uma redução modesta por chamada pode somar uma grande diferença mensal.
Versões da Stack: Escrito contra a linha de modelos Claude atualizada em aproximadamente junho de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (o padrão) e Claude Haiku 4.5 - e o SDK oficial
anthropicpara Python (última versão 0.x). Nomes de modelos, preços e versões de SDK mudam rapidamente - verifique os detalhes atuais em platform.claude.com/docs antes de confiar neles.