omidzamani/dspy-better-together
Use for BetterTogether, prompt plus weight optimization, fine-tuning sequences, and strategy chains like p -> w -> p.
npx skills add https://github.com/OmidZamani/dspy-skills --skill dspy-better-together
Sequence prompt and weight optimizers, evaluate intermediate programs, and return the best candidate.
3.2.1 or later in the stable 3.2.x series.student.set_lm(lm).BetterTogether to hold out part of the trainset.BootstrapFinetune.import dspy
lm = dspy.LM("openai/gpt-4o-mini")
dspy.configure(lm=lm)
student = dspy.ChainOfThought("question -> answer")
student.set_lm(lm)
def metric(example, pred, trace=None):
return float(example.answer.lower() == pred.answer.lower())
optimizer = dspy.BetterTogether(
metric=metric,
p=dspy.GEPA(
metric=lambda gold, pred, trace=None, pred_name=None, pred_trace=None:
dspy.Prediction(score=metric(gold, pred), feedback="Check answer correctness."),
reflection_lm=dspy.LM("openai/gpt-4o"),
auto="light",
),
w=dspy.BootstrapFinetune(metric=metric),
)
compiled = optimizer.compile(
student,
trainset=trainset,
valset=valset,
strategy="p -> w -> p",
)
| Strategy | Use it when |
|----------|-------------|
| "p -> w" | Start with a simple prompt-then-weight pass |
| "p -> w -> p" | Re-optimize prompts after fine-tuning |
| "w -> p" | Fine-tuning data is already strong |
| Custom chains | Comparing prompt optimizers or conducting controlled experiments |
Optimizer names come from constructor keyword arguments. For example, mipro=... and gepa=... make "mipro -> gepa" valid.
Pass optimizer-specific arguments through optimizer_compile_args:
compiled = optimizer.compile(
student,
trainset=trainset,
valset=valset,
strategy="p -> w",
optimizer_compile_args={
"p": {"max_metric_calls": 150},
},
)
Do not pass student inside optimizer_compile_args; BetterTogether manages the current program.
The returned program exposes:
candidate_programs: evaluated candidates with score and strategyflag_compilation_error_occurred: whether a step failed before completionTake omidzamani/dspy-better-together from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.