Efficient exploration for coding agents.
Save progress at every turn. Branch from any checkpoint instead of starting over.
Sprout lets a coding agent go back to any turn of a rollout and continue from there, instead of starting over. At each turn, Sprout saves a checkpoint: a disk snapshot of the agent's sandbox, paired with the agent's history up to that turn. When a rollout fails, SPROUT, the method of the paper, reviews it, picks the checkpoints before the mistake and branches from them. Benchmark evaluation and RL training run as the same jobs, which workers claim from the Run Store.
You need a Linux host with Python 3.12 and Go 1.25.
git clone https://github.com/dreamyang-liu/sprout.git sprout && cd sprout
ops/setup_podman.sh
source .venv/bin/activate
python -m sprout.worker doctorops/setup_podman.sh installs these items, and skips each one that is already there:
- rootless podman 6, under
~/.local/opt/podman - a btrfs store for the sandboxes, at
~/sprout-btrfs .venv, with themini,harboranddevextras- the runtime binary,
runtime/sprout-runtime
The script uses sudo only for the packages, the btrfs store and the cgroup and user id settings.
doctor prints one line for each check of the host. If a check fails, it exits 1.
export OPENAI_BASE_URL=<url> OPENAI_API_KEY=<key>
python -m sprout.worker run --model <model> --runtime-bin runtime/sprout-runtime \
--sandbox-image docker.io/library/python:3.11-slim --cwd /tmp --journal runs/first.jsonl \
"write fizzbuzz.py, run it, and check that 15 prints FizzBuzz"
python -m ops.report snapshots runs/first.jsonl
python -m ops.report export runs/first.jsonl -o runs/first.mdThe endpoint can be any OpenAI-compatible Chat Completions API. The run prints its outcome, and
the journal runs/first.jsonl records each turn. snapshots lists the snapshot of each turn,
and export writes the trajectory as Markdown. If your provider does not serve plain Chat
Completions, put it behind the bundled
LiteLLM proxy.
Evaluation and RL submit their rollouts, grades and reviews as jobs to the Run Store. A worker on the same host claims and runs them.
pip install -e ".[runstore]"
export SPROUT_MODEL_API_KEY=<key>
python -m sprout.services setup
python -m sprout.services up runstore-api runstore-worker
eval "$(python -m sprout.services env)"setup checks the host, and writes the configs and the secrets under ~/.config/sprout/. It
asks for the model endpoint and the variable of its key, and it asks before each change of a file
that exists (Guided setup). python -m sprout.services init
writes the same configs without questions. The worker passes the key variable to its jobs. The
last command exports the Run Store token into the shell.
The tasks are the Harbor task directories of these benchmarks. Clone them as the experiments guide says.
python -m sprout.eval.gate --tasks-dir ~/datasets/deep-swe/tasks --output runs/gate --workers 8
python -m sprout.eval.evaluate --task-dir ~/datasets/deep-swe/tasks/<task> \
--dataset-digest sha256:... --preparation-manifest runs/prep.json --output runs/<task>-sprout \
--method sprout --model <model> --model-endpoint <url> --model-key-env SPROUT_MODEL_API_KEY \
--rounds 2 --branches 4 3
python -m ops.report task runs/<task>-sproutThe commands do these steps:
- The gate checks that the oracle of each task scores 1 and that doing nothing scores 0.
- The evaluation runs the agent on the task. If the attempt fails, the review picks
checkpoints, and the agent branches from them.
--rounds 2 --branches 4 3gives two rounds, with up to 4 branches and then up to 3. ops.report taskprints the tree of the attempts and their rewards.
--dataset-digest and --preparation-manifest pin the task set. python -m examples.qwen.run
writes both, and runs a whole benchmark. The evaluation refuses a checkout with uncommitted
changes, because its summary records the commit. Evaluation gives every
option.
The RL driver serves Miles rollout
groups from the same jobs. Start it with python -m sprout.services up rl-driver, next to the
worker of step 3. The worker grades
SWE-rebench V2 tasks with a port of its official
harness.
| Guide | What it covers |
|---|---|
| Architecture | Checkpoints, SPROUT branching, the processes around the Run Store |
| Experiments | Datasets, task selection, smoke tests, resuming, the comparison export |
| Experiment protocol | The fixed settings, the rollout budget and the metrics |
| Evaluation | The options and the output of an evaluation and of the task gate |
| Model endpoints | What an endpoint must provide, and the LiteLLM proxy for other providers |
| Services | PostgreSQL, the LiteLLM proxy, the Run Store, its worker and the RL driver |
| Run Store | The job queue, the worker, the graders and the training export |
| RL driver | The Miles /rollout-groups adapter over the Run Store |
| Harbor plugin | Harbor's own trials on a Sprout sandbox, the reference for the Harbor grade |
| Runtime | The tools inside each sandbox |
| Gate | The checks that every commit must pass |
| Decisions | The architecture decisions that one revert cannot undo |
mini-swe-agent is the agent, run unmodified over Sprout's tool transport. Sprout reads tasks in the format of Harbor, and runs each task's verifier as Harbor 0.22 does. The microVMs run on our customized Firecracker, served by AgentENV; the container backend is stock rootless podman over btrfs snapshots.
@misc{liu2026sproutscalingagenticreinforcement,
title={SPROUT: Scaling Agentic Reinforcement Learning for Long-Horizon Software Engineering},
author={Mengyang Liu and Weiming Wang and Haixin Nan and Yu Wu and Peize Li and Shihong Huang and Xuning He and Xue Jiang and Yihong Dong},
year={2026},
eprint={2610.14405},
archivePrefix={arXiv},
primaryClass={cs.SE},
url={https://arxiv.org/abs/2610.14405},
}MIT, for everything in this repository including the runtime and the Python SDK.