Sweeps: rerun a scenario, changing only what you choose
A sweep reruns one scenario many times. You list what should change, for example the model, the quorum or the shock size. Verdi runs every combination and gives you one spreadsheet and one comparison page. The baseline scenario file is never edited.
The 3 commands you need
# 1. See the plan and the cost, and test each model with one tiny call. Runs no simulation.
verdi-agents sweep examples/sweeps/model_comparison.yaml --dry-run
# 2. Run it. It shows the plan again and asks before starting.
verdi-agents sweep examples/sweeps/model_comparison.yaml
# 3. Open the results.
open runs/sweeps/model_comparison/comparison.html
Before anything runs, every model in the sweep gets one tiny test call. A
wrong model name, a key without access (HTTP 401) or an unreachable server
stops the sweep right there, naming the model, so no time or budget is spent
on runs that would fail. Skip it with --skip-check.
If the sweep stops (laptop closed, Ctrl-C, endpoint down), run command 2 again. Finished runs are kept and only the missing or failed ones run.
Writing a sweep file
Copy examples/sweeps/model_comparison.yaml and edit it:
name: model_comparison # also the output folder name
scenario: examples/full.yaml # the baseline
vary: # every combination is run
model.name: [default, Borealis2-preview]
parallel_runs: 2 # simulations at the same time
agent_concurrency: 4 # model calls at the same time, per simulation
# ticks: 10 # shorten every run for a cheap pilot
# output: runs/sweeps/my_folder # default: runs/sweeps/<name>
Naming what to change
Use the field's path in the scenario, with dots between levels:
| You want to change | Write |
|---|---|
| The model name | model.name |
| Quorum | constitution.quorum |
| Fixed vs revisable institutions | institutional_condition |
| The first shock's size | shocks.0.delta (0 is the first item in a list) |
| Food in the commons at the start | world_resources.food |
| The first agent's food | agents.0.resources.food |
A misspelled field stops the sweep before anything runs, with a suggestion
such as Did you mean 'constitution.quorum'?. A field that the engine fills
by default (for example constitution.quorum in starter.yaml) can be varied
too.
Giving options names
A list makes names from the values. To choose the names yourself, or when an
option is more than one value, write name: value:
vary:
shocks.0.delta:
mild: -9.0
severe: -18.0
model: # a different endpoint and key per model
qwen: {name: Qwen3.8-27B}
deepseek: {name: deepseek-v4, base_url: https://api.deepseek.com/v1,
api_key_env: DEEPSEEK_API_KEY}
A model: option only needs the parts that differ from the baseline. The
rest is kept. Put each key in .env (DEEPSEEK_API_KEY=...), never in the YAML.
Several things at once
Every combination is run. This runs 2 x 2 x 2 = 8 conditions:
vary:
institutional_condition: [fixed, revisable]
constitution.quorum: [0.5, 0.75]
shocks.0.delta: {mild: -9.0, severe: -18.0}
See examples/sweeps/governance_grid.yaml.
Quick sweeps without a file
verdi-agents sweep --scenario examples/full.yaml \
--vary model.name=default,Borealis2-preview \
--vary constitution.quorum=0.5,0.75 \
--parallel-runs 2 --dry-run
The other settings work as flags too: --ticks, --agent-concurrency,
--output, --name, and --yes (start without asking).
What you get
runs/sweeps/model_comparison/
comparison.html <- open this: mean ± spread per condition, links to every run
summary.csv <- one row per run, opens in Excel / Google Sheets
sweep_manifest.json <- what ran, status, timings, code commit
default/
seed-42/
scenario.yaml <- the exact input of this run (frozen)
report.html <- the single-run report
run.log <- everything the run printed (look here if it failed)
metrics.json, events.jsonl, ...
summary.csv also records model_served, the model name the endpoint
reported for each run, next to model_requested. If they differ, the server
was not serving what you asked for. It also has token counts, so you can see
the cost per condition.
To rebuild summary.csv and comparison.html without running anything:
verdi-agents sweep <file> --results.
Good practice
- Pilot first. Run with
ticks: 5and one seed, check the comparison page, then removeticksfor the real sweep. - Repeat with seeds when you need it. Without
seeds:every condition runs once, on the scenario's ownrun_seed. Addseeds: [42, 43, 44](or a count,seeds: 3) to repeat every condition on each seed; all conditions get the same seeds. - Compare across seeds, not single runs. The same seed does not give the same model output, especially with remote APIs. The comparison page shows the mean and standard deviation over seeds for this reason.
- Watch the cost line. It is a lower bound: probes, meetings and interviews add calls on top.
- Two kinds of parallelism.
parallel_runsis how many simulations run at once.agent_concurrencyis how many model calls each simulation makes at once. Your endpoint sees up toparallel_runs x agent_concurrencycalls at once.