Skip to content

Commit 90a9dd8

Browse files
authored
fix: pass metric_threshold to BootstrapFewShot in unshuffled (seed=-1) case (#9317)
Fixes #9308. The metric_threshold parameter was not being passed to BootstrapFewShot for the unshuffled few-shot case (seed=-1) in create_n_fewshot_demo_sets, causing examples below the threshold to be incorrectly included as bootstrapped demos.
1 parent 26bfd24 commit 90a9dd8

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

‎dspy/teleprompt/utils.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ def create_n_fewshot_demo_sets(
383383
program = BootstrapFewShot(
384384
metric=metric,
385385
max_errors=max_errors,
386+
metric_threshold=metric_threshold,
386387
max_bootstrapped_demos=max_bootstrapped_demos,
387388
max_labeled_demos=max_labeled_demos,
388389
teacher_settings=teacher_settings,

‎tests/teleprompt/test_utils.py‎

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
from unittest.mock import Mock
1+
from unittest.mock import Mock, patch
22

33
import dspy
4-
from dspy.teleprompt.utils import eval_candidate_program
4+
from dspy.teleprompt.utils import create_n_fewshot_demo_sets, eval_candidate_program
5+
from dspy.utils.dummies import DummyLM
56

67

78
class DummyModule(dspy.Module):
@@ -50,3 +51,47 @@ def test_eval_candidate_program_failure():
5051
result = eval_candidate_program(batch_size, trainset, candidate_program, evaluate)
5152

5253
assert result.score == 0.0
54+
55+
56+
def test_create_n_fewshot_demo_sets_passes_metric_threshold_for_unshuffled():
57+
"""Verify that metric_threshold is passed to BootstrapFewShot for the unshuffled (seed=-1) case.
58+
59+
Regression test for https://github.com/stanfordnlp/dspy/issues/9308
60+
"""
61+
student = DummyModule()
62+
student.predictor = dspy.Predict("input -> output")
63+
trainset = [dspy.Example(input="test", output="test").with_inputs("input")]
64+
65+
lm = DummyLM([{"output": "test"}])
66+
dspy.configure(lm=lm)
67+
68+
with patch("dspy.teleprompt.utils.BootstrapFewShot") as MockBootstrap:
69+
mock_instance = Mock()
70+
mock_instance.compile.return_value = student
71+
MockBootstrap.return_value = mock_instance
72+
73+
create_n_fewshot_demo_sets(
74+
student=student,
75+
num_candidate_sets=4, # -3, -2, -1, 0 → hits seed=-1
76+
trainset=trainset,
77+
max_labeled_demos=1,
78+
max_bootstrapped_demos=1,
79+
metric=lambda ex, pred, trace=None: 1.0,
80+
teacher_settings={},
81+
metric_threshold=0.9,
82+
)
83+
84+
# Find the call where seed == -1 (unshuffled few-shot)
85+
# BootstrapFewShot should be called at least twice: once for seed=-1, once for seed>=0
86+
calls = MockBootstrap.call_args_list
87+
assert len(calls) >= 1, "BootstrapFewShot was never called"
88+
89+
# Every BootstrapFewShot call should include metric_threshold
90+
for call in calls:
91+
_, kwargs = call
92+
assert "metric_threshold" in kwargs, (
93+
f"metric_threshold missing from BootstrapFewShot call: {kwargs}"
94+
)
95+
assert kwargs["metric_threshold"] == 0.9, (
96+
f"metric_threshold={kwargs['metric_threshold']}, expected 0.9"
97+
)

0 commit comments

Comments
 (0)