BootstrapFewShot is a DSPy optimizer for choosing prompt demonstrations. It is useful when selecting examples by hand is difficult, especially when a program makes several language-model calls but the training data records only the original input and final answer. Rather than requiring labeled examples for every intermediate prompt, it can generate the missing demonstration fields from successful program runs. section 5.3 section 5.7
During bootstrapping, DSPy runs the program on training examples and checks the final response with a metric. When the metric accepts a run, DSPy can use the language-model inputs and outputs from that run as demonstrations. For a multistep program, this supplies examples to intermediate prompts too. Acceptance is based on the metric’s result for the full run; it does not separately establish that every generated intermediate field is correct. section 7.6.1 section 5.3.1
A typical setup configures the optimizer, then compiles an existing DSPy program:
- Pass a metric that judges predictions against training examples; its acceptance decision controls which generated demonstrations qualify. section 5.3.1
- Set max_bootstrapped_demos for generated demonstrations and max_labeled_demos for demonstrations taken directly from labeled examples. Set max_rounds when configuring the search. section 5.3
- Call compile(student=..., trainset=...) and use the resulting program for predictions. Inspect the language-model history to see which demonstrations reached its prompts. section 5.3 section 7.6.1
Listing 7.22 Optimizing a multihop module using BootstrapFewShot
from dspy import BootstrapFewShot
class PredictWithClearQuestion(dspy.Module): #1
def __init__(self, signature):
self.query1 = dspy.Predict("question -> clear_question")
self.query2 = dspy.Predict(signature)
def forward(self, **args):
q = args['message']
args['message'] = self.query1(question=q).clear_question
return self.query2(**args)
lm = dspy.LM(model='gpt-4o-mini')
dspy.configure(lm=lm)
prog = PredictWithClearQuestion(ClosedIntentSignature) #2
optimizer = BootstrapFewShot( #3
metric=validate_answer,
max_bootstrapped_demos=3,
max_labeled_demos=0,
max_rounds=1
)
prog_bootstrap_few_shot = optimizer.compile(student=prog,
trainset=train_set) #4
prediction = prog_bootstrap_few_shot(**dev_set[0].inputs()) #5
print(lm.inspect_history(n=2)) #6
The two-step implementation makes bootstrapping visible: one predictor clarifies a message, and a second classifies it. Compilation selects successful training runs to create demonstrations for both prompts. section 7.6.1
Generating an intermediate field
Suppose a flight-intent classifier first rewrites “list flights from tampa to cincinnati after 3 pm” as a clear question, then classifies it. Training examples need not supply that rewrite. If the final classification passes the metric, the generated clear question can become both an output demonstration for the first call and an input demonstration for the second. Similarly, with ChainOfThought, an accepted prediction can supply a reasoning field absent from the training example. section 7.6.1 section 5.3.1
BootstrapFewShot can also use labeled demonstrations without generating them; with only max_labeled_demos enabled, its behavior matches LabeledFewShot. Bootstrapping is distinct from bootstrap sampling: here it means creating missing demonstration content. Choose the metric carefully, because fields it does not check may still be admitted from an otherwise accepted run. section 5.3.1
