How it works
COPRO runs a generate-and-evaluate loop:- Generate candidates: Create
breadthcandidate instructions per predictor - Evaluate: Test each candidate on your training data
- Refine: Use the best candidate as the seed for the next round
- Repeat: Continue for
depthrounds
Configuration
prompt_model (separate LM for generating candidate instructions), eval_concurrency (concurrent LM calls during evaluation, default 16), track_stats, and init_temperature (currently unused, reserved for candidate diversity control). The full field table is in the optimizers reference.
Usage example
(QAInput, QAOutput) tuples, the zero-boilerplate row form. Any row type that implements ToInput<QAInput> works, including #[derive(Example)] structs carrying gold labels and metric-only fields; see Data. The predictors! line names the module’s optimizable leaves — without it the module does not satisfy the Predictors bound compile_module requires.
Typed data loading
Use the shared data ingress reference:DataLoader.
When to use COPRO
Best for:- Quick iteration cycles
- Simple tasks
- Limited compute budget
- Short turnaround requirements
- You need best possible quality (use MIPROv2 or GEPA)
- Task has complex failure modes (use GEPA)
- You want to leverage prompting best practices (use MIPROv2)
Comparison with other optimizers
GEPA is the only optimizer that requires textual feedback from the metric (
Eval::with_feedback). The others use numerical scores alone. Full configuration tables for all six live in the optimizers reference.
Configuration details
Breadth
Number of candidate instructions generated at each round, per predictor. Higher breadth means more exploration but proportionally more LM calls. Must be greater than 1;compile errors otherwise.
Recommended: 5-15
Depth
Number of refinement rounds. Each round builds on the best candidate from the previous one, with diminishing returns beyond about 5. Recommended: 2-5Prompt model
An optional separate LM used to generate candidate instructions. Falls back to the global LM set withconfigure when unset.
Track stats
A per-round statistics flag. COPRO’scompile_module returns (), so nothing is returned either way; leave it at the default.
Implementation notes
COPRO is a thin strategy over the shared evaluation engine: each candidate instruction is a name-keyedCandidate injected ambiently per rollout through a cached, bounded-concurrency fan-out — the module is never mutated during evaluation — and the final winner is installed once through OptimizeTarget::install. Repeated candidates are deduplicated by content hash and served from the rollout cache, so re-evaluating an instruction it has already seen costs nothing. See the optimizer engine reference for the machinery.
Cost is approximately breadth × depth × num_predictors × trainset_size LM calls, minus cache hits.
Examples
COPRO Examples
See examples 02-module-iteration-and-updation.rs and 04-optimize-hotpotqa.rs
