Compilando e otimizando prompts
BootstrapFewShot, MIPRO e outros otimizadores do DSPy na prática.
Compilando e otimizando prompts é uma aula grátis de AI Prompt Engineering no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Prompt Engineering, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Prompt Engineering inclui 4 aulas no total.
O que significa otimização no DSPy
A otimização do DSPy (chamada de compilação) encontra a melhor configuração de instruções para o seu programa, considerando um conjunto de treinamento e uma métrica. O otimizador pesquisa entre possíveis exemplos de poucos exemplos, instruções e demonstrações de raciocínio.
Você executa a compilação uma vez, salva o resultado e implanta o programa otimizado. Durante a inferência, são apenas chamadas rápidas ao LLM — sem a sobrecarga de otimização.
Definindo uma função de métrica
Todo otimizador do DSPy precisa de uma função de métrica que atribua uma pontuação a uma predição considerando a saída esperada. Ela retorna um número (ou um booleano) — quanto maior, melhor.
A métrica é o sinal que o otimizador usa para decidir se uma configuração de instruções é boa.
# Metric: exact match on answer field
def exact_match_metric(example, prediction, trace=None):
"""
example: a training example with .answer
prediction: the module's output with .answer
Returns 1.0 if correct, 0.0 otherwise
"""
expected = example.answer.strip().lower()
predicted = prediction.answer.strip().lower()
return float(expected == predicted)
# Metric: F1 score for token overlap (common in QA)
def token_f1_metric(example, prediction, trace=None):
gold_tokens = set(example.answer.lower().split())
pred_tokens = set(prediction.answer.lower().split())
if not pred_tokens:
return 0.0
precision = len(gold_tokens & pred_tokens) / len(pred_tokens)
recall = len(gold_tokens & pred_tokens) / len(gold_tokens)
if precision + recall == 0:
return 0.0
return 2 * precision * recall / (precision + recall)Preparando um conjunto de treinamento
O DSPy precisa de um conjunto de treinamento formado por objetos dspy.Example. Cada exemplo especifica as entradas e a saída esperada. Até mesmo 20 a 50 exemplos costumam ser suficientes para o BootstrapFewShot.
import dspy
# Build training examples
trainset = [
dspy.Example(
question='What is the capital of Germany?',
answer='Berlin'
).with_inputs('question'),
dspy.Example(
question='Who wrote Romeo and Juliet?',
answer='William Shakespeare'
).with_inputs('question'),
dspy.Example(
question='What year did World War II end?',
answer='1945'
).with_inputs('question'),
# ... add more examples
]
print(f'Training set size: {len(trainset)} examples')
print(trainset[0].question, '->', trainset[0].answer)Otimizador BootstrapFewShot
BootstrapFewShot é o otimizador mais comum do DSPy. Ele executa seu programa no conjunto de treinamento, coleta rastreamentos bem-sucedidos (pares de entrada e saída nos quais a métrica é aprovada) e usa esses rastreamentos como demonstrações de poucos exemplos na instrução compilada.
import dspy
from dspy.teleprompt import BootstrapFewShot
# Define your program
class QA(dspy.Signature):
"""Answer factual questions."""
question: str = dspy.InputField()
answer: str = dspy.OutputField()
program = dspy.ChainOfThought(QA)
# Set up the optimizer
optimizer = BootstrapFewShot(
metric=exact_match_metric,
max_bootstrapped_demos=4, # Up to 4 few-shot examples per predictor
max_labeled_demos=4, # Use labeled examples directly if available
)
# Compile!
compiled_program = optimizer.compile(program, trainset=trainset)
print('Compilation complete')Otimizador MIPRO
MIPRO (proposta e otimização de múltiplas instruções) é um otimizador mais poderoso. Ele não apenas seleciona exemplos de poucos exemplos, mas também pesquisa um texto de instrução melhor para incluir na instrução.
O MIPRO exige mais chamadas ao LLM durante a compilação, mas frequentemente alcança uma precisão significativamente maior.
import dspy
from dspy.teleprompt import MIPROv2
class QA(dspy.Signature):
"""Answer factual questions."""
question: str = dspy.InputField()
answer: str = dspy.OutputField()
program = dspy.ChainOfThought(QA)
# MIPRO: optimizes both instructions AND few-shot examples
optimizer = MIPROv2(
metric=exact_match_metric,
auto='medium', # 'light' / 'medium' / 'heavy' for optimization budget
num_threads=4, # Parallel evaluation threads
)
compiled_program = optimizer.compile(
program,
trainset=trainset,
num_trials=20, # Number of candidate prompts to evaluate
)
print('MIPRO compilation complete')Como é uma instrução compilada
Depois da compilação, o DSPy incorpora demonstrações otimizadas de poucos exemplos à instrução. Você pode inspecioná-las examinando os preditores do programa compilado.
import dspy
# After compiling, inspect the optimized state
compiled_program = dspy.ChainOfThought('question -> answer')
# (Assume this was returned by optimizer.compile(...))
# Inspect the demos that were found
for demo in compiled_program.demos:
print('Input:', demo.question)
print('Reasoning:', demo.get('reasoning', 'N/A'))
print('Answer:', demo.answer)
print('---')
# Save the compiled state
compiled_program.save('compiled_qa_program.json')
print('Saved compiled program')A interface teleprompter.compile()
Todos os otimizadores do DSPy compartilham a mesma interface compile(). Essa consistência significa que você pode trocar de otimizador sem alterar o código do programa.
from dspy.teleprompt import BootstrapFewShot, MIPROv2, COPRO
# All optimizers use the same interface:
# compiled = optimizer.compile(program, trainset=trainset)
# BootstrapFewShot: fast, uses successful traces as demos
opt1 = BootstrapFewShot(metric=exact_match_metric)
# MIPRO: slower, optimizes instructions too
opt2 = MIPROv2(metric=exact_match_metric, auto='light')
# COPRO: coordinate descent over instruction proposals
opt3 = COPRO(metric=exact_match_metric, depth=3)
# Swap between them with one line change:
compiled = opt1.compile(program, trainset=trainset)
# or: compiled = opt2.compile(program, trainset=trainset)BootstrapFewShotWithRandomSearch
BootstrapFewShotWithRandomSearch amplia o BootstrapFewShot ao gerar vários conjuntos candidatos de demonstrações e selecionar o que apresenta o melhor desempenho em um conjunto de validação.
É um bom meio-termo entre a simplicidade do BootstrapFewShot e o poder do MIPRO.
from dspy.teleprompt import BootstrapFewShotWithRandomSearch
# Split data into train and validation
trainset = examples[:40]
devset = examples[40:60]
optimizer = BootstrapFewShotWithRandomSearch(
metric=exact_match_metric,
max_bootstrapped_demos=4,
num_candidate_programs=8, # Try 8 different demo sets
num_threads=4,
)
compiled_program = optimizer.compile(
program,
trainset=trainset,
valset=devset, # Picks the best program based on validation
)
print('Best program selected from 8 candidates')Considerações sobre o custo da compilação
A compilação faz chamadas adicionais ao LLM para gerar e avaliar instruções candidatas. Planeje o orçamento de acordo:
- BootstrapFewShot: aproximadamente 1 a 2 vezes o tamanho do conjunto de treinamento em chamadas ao LLM
- RandomSearch com 8 candidatos: aproximadamente 8 a 10 vezes
- MIPRO médio: aproximadamente 30 a 50 vezes
Execute a compilação off-line, salve o resultado e implante o programa salvo. O custo da inferência em produção não muda.
Validando o programa compilado
Depois da compilação, sempre avalie o programa em um conjunto de teste separado para confirmar que o programa otimizado realmente se generaliza. Não verifique apenas o desempenho no conjunto de treinamento.
import dspy
# Evaluate on test set
evaluate = dspy.Evaluate(
devset=testset,
metric=exact_match_metric,
num_threads=4,
display_progress=True,
)
# Compare uncompiled vs compiled
uncompiled_score = evaluate(uncompiled_program)
compiled_score = evaluate(compiled_program)
print(f'Uncompiled accuracy: {uncompiled_score:.1%}')
print(f'Compiled accuracy: {compiled_score:.1%}')
print(f'Improvement: +{compiled_score - uncompiled_score:.1%}')Unindo tudo
Um fluxo completo de otimização no DSPy: definir a signature → criar o módulo → preparar os dados de treinamento → escolher o otimizador → compilar → avaliar → salvar. Esse é o ciclo completo, da ideia a um fluxo de instruções otimizado e pronto para produção.
import dspy
from dspy.teleprompt import BootstrapFewShot
# 1. Configure LM
dspy.configure(lm=dspy.LM('openai/gpt-4o-mini', api_key='sk-...'))
# 2. Define signature and module
class QA(dspy.Signature):
"""Answer questions accurately."""
question: str = dspy.InputField()
answer: str = dspy.OutputField()
program = dspy.ChainOfThought(QA)
# 3. Compile
optimizer = BootstrapFewShot(metric=exact_match_metric)
compiled = optimizer.compile(program, trainset=trainset)
# 4. Save
compiled.save('production_qa.json')
print('Production program ready')Verificação de conhecimento: BootstrapFewShot
O que o BootstrapFewShot utiliza do seu conjunto de treinamento para melhorar a instrução compilada?
Recapitulação: compilação e otimização
A otimização do DSPy pesquisa a melhor configuração de instruções usando uma função de métrica e um conjunto de treinamento. BootstrapFewShot encontra boas demonstrações de poucos exemplos a partir de rastreamentos bem-sucedidos. MIPROv2 também pesquisa um texto de instrução melhor. Todos os otimizadores compartilham uma interface compile(program, trainset=...). A compilação é um custo único e off-line — salve o resultado com program.save() e implante o programa otimizado sem custo adicional durante a inferência.
Perguntas Frequentes
A aula “Compilando e otimizando prompts” é grátis?
Sim — o texto completo de “Compilando e otimizando prompts” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Prompt Engineering, atualize para CoddyKit PRO. O curso de AI Prompt Engineering inclui 4 aulas no total.
O que vou aprender em “Compilando e otimizando prompts”?
BootstrapFewShot, MIPRO e outros otimizadores do DSPy na prática. Você pratica AI Prompt Engineering com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar AI Prompt Engineering?
Nenhuma experiência prévia é necessária. AI Prompt Engineering no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Compilando e otimizando prompts”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de AI Prompt Engineering?
Sim. Cada aula de AI Prompt Engineering inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Introdução ao framework DSPy
- Definindo assinaturas e módulos
- Compilando e otimizando prompts
- Avaliando pipelines do DSPy