Call agents & RL
RL environments & decision engines
An RL rollout needs many identical environments, each one isolated, each one cheap to copy. A Sandbox is that environment: start one, run the episode to a decision point, snapshot its memory, restore as many copies as you have actions to try, and score the trajectories in parallel with .map().
CPU sandboxes for environments, gVisor-isolated with network rules; a GPU function for the policy or the scorer.
How it works
- 1Sandbox(...).create() starts an environment; process.run_code drives it step by step and returns what the agent observed.
- 2At a branching point, snapshot_memory() freezes the whole process; Sandbox.create_from_memory_snapshot(id) brings back an identical copy in seconds, one per candidate action.
- 3Each copy continues its own episode; the trajectories go to a scoring function, fanned out with .map() so hundreds are judged at once.
- 4Scores feed the decision engine or the trainer; the sandboxes are terminated, and the next rollout starts from the same snapshot.
The code
from levers9 import Sandbox, job env = Sandbox(cpu=1, memory="1Gi", block_network=True, keep_warm_seconds=1800).create() env.process.run_code(open("play_to_decision_point.py").read()) snap = env.snapshot_memory() # freeze the episode here @job(cpu=1, memory="1Gi") def rollout(action: str) -> dict: copy = Sandbox.create_from_memory_snapshot(snap) # an identical environment per action out = copy.process.run_code(f"step({action!r}); print(score())") copy.terminate() return {"action": action, "score": float(out.result)} results = list(rollout.map(["book_viewing", "ask_budget", "offer_callback"]))
python rollout.py levers9 container list # every environment copy while it runs
Where to go next
Related
Sandboxed code execution
Run LLM-generated code in gVisor-isolated containers with CPU, memory and network limits per call.
Teach a call agent with human feedback
Play the seven missions: calls in, hot spots, duels for 10 XP a pick, level up, boss fight, crown the champion, connect it to real customers.
Process ten thousand inputs with .map()
One container per item, sub-second warm starts, scale back to zero when the queue drains.