qlaw/optimize.py, qlaw/evaluate.py, qlaw/datasets.py, and qlaw/metrics.py provide compilation, measurement, and bounded GEPA instruction optimization.
Strategy: measure each lens first, optimize its instruction text with held-out evidence, then cascade into whole-engine compilation. Per-lens trainsets are built from the existing GRAPH_TEMPLATES plus hand-authored examples. The engine trains on full-session trajectories.
Datasets
qlaw/datasets.py builds per-lens and engine trainsets and devsets. Every example calls .with_inputs(...) — otherwise program(**example.inputs()) crashes at evaluation time.
Metrics
qlaw/metrics.py provides six metrics. dspy.Evaluate calls a metric as metric(example, prediction) — exactly two positional args. Optimizers may pass trace, pred_name, and pred_trace too, so declare defaults.
Return values from a metric may be
bool, float, or dspy.Prediction(score, feedback). Feedback is read only by GEPA. dspy.Evaluate reports EvaluationResult.score as a 0–100 percentage, not 0–1.
Compile pipeline
qlaw/optimize.py:
- The metric goes on the optimizer constructor —
dspy.MIPROv2(metric=...),dspy.BootstrapFewShot(metric=...). trainset=is keyword-only atcompile()—train_set=fails withTypeError.MIPROv2(auto="light"|"medium"|"heavy")cannot be combined with explicitnum_candidatesornum_trials— that raisesValueError.compile()returns a new copy; the student is not mutated.
Command-line entrypoints
scripts/evaluate.py writes eval_results.json alongside artifacts/.
Bounded GEPA instruction optimization
For bounded GEPA prompt optimization of the core lenses, use the wrapper:--strategy omni — explore all engines on a small slice, continue from the validation winner. The wrapper installs the unreleased gepa OA API at run time (DSPy pins gepa 0.1.1).
By default, both the gepa engine’s proposals and evaluation use the .env model. Pass --codex-model to switch to the native Codex agent proposer.
GEPA “omni” meta-optimizer
qlaw/omni.py composes GEPA into an “omni” meta-optimizer at the DSPy layer, distinct from — but conceptually similar to — the GEPA Omni plugin. optimize_omni and optimize_parallel orchestrate GEPA across lenses.
Caching and rollout ids
DSPy caches LM calls on by default. ForRefine sampling to actually sample fresh, pass a unique rollout_id and a non-zero temperature. Otherwise the same cached response is returned across attempts.
Save and load
program.save(path)— state only.program.save(dir, save_program=True)+dspy.load(dir)— full program.allow_pickledefaults toFalse. API keys are never serialized.