Marginal-gain stopping — stop when calls stop paying¶
evolve already stops on a target, patience, rounds, wall clock, calls, tokens
and diminishing returns. A campaign or long RSI run often wants a different
question: is the next call still buying reward? MarginalGainStop turns the
recent reward/call curve into a stop_when callable.
from agentdescent import MarginalGainStop
policy = MarginalGainStop(min_gain_per_call=1e-4, patience=3, window=3)
evolve(..., stop_when=policy)
- The policy keeps the last
window + 1(calls, held_out_reward)points from theRoundInfothe engine already passes. - A measurement is low when the gain per additional call is below
min_gain_per_call.min_gainis an optional absolute-gain floor combined by OR: if the recent gain is at mostmin_gain, the measurement is also low. With the defaultmin_gain=0, the per-call bar is what decides — including the case this policy exists for, a run that is still improving but too slowly to pay for its calls. patienceconsecutive low measurements stop the run with the engine'sstop_reason="stop_when";reasonnames the gain, call delta and streak for the caller's report.- A round that spent no additional calls does not establish a slope and never counts as low.
held_out_rewardis this round's measurement, not the best so far, so a noisy dip reads as a negative gain.- The policy is stateful. Call
reset()before reusing one instance for a new run (a campaign or a meta loop should not carry the previous run's points).
This is an economic stop, not a safety one: it says the search has stopped paying for itself, not that the artifact is good. Pair it with a target or a round budget when both matter.