0Pricing
AI Prompt Engineering · Lezione

Compilazione e ottimizzazione dei prompt

BootstrapFewShot, MIPRO e altri ottimizzatori DSPy nella pratica

Compilazione e ottimizzazione dei prompt è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Prompt Engineering, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Prompt Engineering include 4 lezioni in totale.

Che cosa significa ottimizzazione in DSPy

L'ottimizzazione DSPy (chiamata compilazione) trova la configurazione di prompt migliore per il programma, dato un set di addestramento e una metrica. L'ottimizzatore ricerca tra possibili esempi few-shot, istruzioni e dimostrazioni di ragionamento.

Si esegue la compilazione una volta, si salva il risultato e si distribuisce il programma ottimizzato. Durante l'inferenza si effettuano soltanto chiamate LLM rapide, senza ulteriore sovraccarico di ottimizzazione.

Definire una funzione metrica

Ogni ottimizzatore DSPy necessita di una funzione metrica che assegni un punteggio a una previsione in base all'output atteso. Restituisce un numero (o un booleano): più alto è, meglio è.

La metrica è il segnale che l'ottimizzatore usa per decidere se una configurazione di prompt è valida.

# 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)

Preparare un set di addestramento

DSPy necessita di un set di addestramento composto da oggetti dspy.Example. Ogni esempio specifica gli input e l'output atteso. Anche 20-50 esempi sono spesso sufficienti per 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)

Ottimizzatore BootstrapFewShot

BootstrapFewShot è l'ottimizzatore DSPy più usato. Esegue il programma sul set di addestramento, raccoglie le tracce riuscite (coppie input-output per cui la metrica viene superata) e usa tali tracce come dimostrazioni few-shot nel prompt compilato.

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')

Ottimizzatore MIPRO

MIPRO (Multi-prompt Instruction Proposal and Optimization) è un ottimizzatore più potente. Non si limita a selezionare esempi few-shot, ma ricerca anche un testo di istruzioni migliore da includere nel prompt.

MIPRO richiede più chiamate LLM durante la compilazione, ma spesso raggiunge un'accuratezza significativamente maggiore.

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')

Com'è fatto un prompt compilato

Dopo la compilazione, DSPy incorpora nel prompt dimostrazioni few-shot ottimizzate. È possibile esaminarlo analizzando i predictor del programma compilato.

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')

L'interfaccia teleprompter.compile()

Tutti gli ottimizzatori DSPy condividono la stessa interfaccia compile(). Questa uniformità consente di sostituire gli ottimizzatori senza modificare il codice del programma.

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 estende BootstrapFewShot generando numerosi set di dimostrazioni candidati e selezionando quello con le migliori prestazioni su un set di validazione.

È un buon compromesso tra la semplicità di BootstrapFewShot e la potenza di 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')

Considerazioni sui costi della compilazione

La compilazione effettua chiamate LLM aggiuntive per generare e valutare i prompt candidati. Occorre quindi pianificare il budget:

  • BootstrapFewShot: circa 1-2 volte la dimensione del set di addestramento in chiamate LLM
  • RandomSearch con 8 candidati: circa 8-10 volte
  • MIPRO medium: circa 30-50 volte

Si esegua la compilazione offline, si salvi il risultato e si distribuisca il programma salvato. Il costo dell'inferenza in produzione non cambia.

Convalidare il programma compilato

Dopo la compilazione, si valuti sempre il programma su un set di test separato per verificare che quello ottimizzato si generalizzi realmente. Non si controllino soltanto le prestazioni sul set di addestramento.

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%}')

Unire tutti gli elementi

Un flusso di lavoro completo per l'ottimizzazione con DSPy: definire la signature → creare il modulo → preparare i dati di addestramento → scegliere l'ottimizzatore → compilare → valutare → salvare. Questo è il ciclo completo dall'idea a una pipeline di prompt ottimizzata e pronta per la produzione.

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 delle conoscenze: BootstrapFewShot

Che cosa usa BootstrapFewShot dal set di addestramento per migliorare il prompt compilato?

Riepilogo: compilazione e ottimizzazione

L'ottimizzazione DSPy ricerca la configurazione di prompt migliore usando una funzione metrica e un set di addestramento. BootstrapFewShot trova buone dimostrazioni few-shot a partire dalle tracce riuscite. MIPROv2 ricerca inoltre un testo di istruzioni migliore. Tutti gli ottimizzatori condividono un'interfaccia compile(program, trainset=...). La compilazione è un costo offline una tantum: si salvi il risultato con program.save() e si distribuisca il programma ottimizzato, senza ulteriori costi di ottimizzazione durante l'inferenza.

Domande Frequenti

La lezione «Compilazione e ottimizzazione dei prompt» è gratuita?

Sì — il testo completo di «Compilazione e ottimizzazione dei prompt» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Prompt Engineering, passa a CoddyKit PRO. Il corso AI Prompt Engineering include 4 lezioni in totale.

Cosa imparerò in «Compilazione e ottimizzazione dei prompt»?

BootstrapFewShot, MIPRO e altri ottimizzatori DSPy nella pratica Eserciti AI Prompt Engineering con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Prompt Engineering?

Non è richiesta alcuna esperienza precedente. AI Prompt Engineering su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Compilazione e ottimizzazione dei prompt»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Prompt Engineering?

Sì. Ogni lezione AI Prompt Engineering include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Introduzione al framework DSPy
  2. Definizione di signature e moduli
  3. Compilazione e ottimizzazione dei prompt
  4. Valutazione delle pipeline DSPy
← Torna a AI Prompt Engineering