Campaign — keep evolving, carrying the artifact forward¶
One evolve() run is a session. A campaign runs several sessions on the same
spec, each starting from the artifact the previous session produced, and stops
when a session fails to improve. That is the smallest honest "keep improving"
loop for a spec: there is no second engine and no hidden state — the next
session's target is the previous session's output.
The campaign works on a copy of the target in a temporary workspace, so the
user's file/directory is never touched. The report returns the workspace and
final_target; apply that deliberately with agentdescent apply --to ... or by
copying it yourself.
- An improving session's artifact is written back to the workspace copy.
- A non-improving session is discarded and, after
--patiencesuch sessions (default 1), the campaign stops; the workspace keeps the best artifact, not the last one. - The split's seed stays the spec's seed across sessions. With
shuffle: truethe held-out split is derived from that seed, so changing it per session would make the rewards incomparable; sessions differ because the artifact they start from does. - Session 0 establishes the campaign's baseline (
baseline_reward); it is not reported as an improvement over the user's file, which the campaign never measured. --dry-runcomposes one session and printscalls/session x sessions.policy_slotis refused: its target is a slot name, not a file, so there is nothing to carry forward. An inlinekind: textinstruction is refused too: put the prompt in a file so there is a target to copy and carry.--workdirmust be empty; campaign does not resume a previous workspace yet.final_rewardis the last session's measured reward;best_rewardis the best session, which is the artifact left in the workspace.
from agentdescent import run_campaign
from agentdescent.evolvespec import load_spec
report = run_campaign(load_spec("spec.json"), sessions=3, rounds=2)
print(report.best_reward, report.final_target, report.stopped_reason)
A campaign is a loop over ordinary runs, not a claim that more sessions are
always better. It reports stopped_reason="patience" when the measured reward
stops moving; if that happens on session one, the second session bought nothing
and the report says so.