How it is built
Architecture overview
An RL environment platform is the part of a model-training stack that lets a language-model agent practise a task thousands of times and tells it how it did. For a coding agent the task is "fix this issue in this repository"; for a computer-use agent it is "book this ticket in this web app". Each attempt (a rollout) happens inside a disposable sandbox that holds the task's world: a checked-out repository, a desktop, a website. The agent acts on it through tools, and when it stops, a verifier looks at the final state and produces a reward. The trainer collects many rollouts, turns rewards into a learning signal, and updates the model.
The idea that makes it work is that the environment is a function from a task spec to a scored trajectory, with isolation and reproducibility as hard requirements. Isolation, because the agent executes arbitrary code and may try anything that raises its reward; reproducibility, because a reward is only a training signal if the same behaviour gets the same score. Everything else here serves those two properties at the scale of many thousands of concurrent sandboxes. The interface (reset, step, reward) comes from Gym (Brockman et al., 2016); a step is now a tool call into a whole operating system.
Parts:
- Task set — versioned tasks, each with a starting state and a way to check success — Content-addressed storage, Object storage,
dataset-versioning(no page yet), Cryptographic hashes, Near-duplicate detection (MinHash), Bloom filter,benchmark-contamination-detection(no page yet) - Sandbox runtime — an isolated machine per rollout, started fast —
microvm-isolation(no page yet),vm-snapshot-restore(no page yet), Process sandboxing, Least privilege and isolation, cgroups and namespaces, Containers and Kubernetes, overlay filesystem (no page yet),hermetic-execution(no page yet) - Sandbox pool — enough warm sandboxes, no more —
warm-pool-provisioning(no page yet), autoscaling (no page yet), Health checking, Exponential smoothing, PID control, Sliding-window counters - Tool interface — what the agent can call — Tool calling,
model-context-protocol(no page yet), JSON Schema validation, Constrained decoding, Server-sent events, OAuth2 and OIDC, JWT,browser-automation-protocol(no page yet),accessibility-tree(no page yet),screen-capture(no page yet),input-event-synthesis(no page yet) - Network boundary — what the sandbox may reach —
egress-proxy-filtering(no page yet), DNS protocol, Public suffix list, Mutual TLS - Verifier and reward — turn the end state into a number —
verifiable-rewards(no page yet), pass@k (no page yet), Text normalization, LLM as judge, Coverage-guided fuzzing, Code coverage instrumentation - Simulated users and services — the world that talks back —
user-simulation(no page yet), Dialogue state tracking, Template text generation, Sampling strategies, Statecharts - Rollout scheduler — dispatch, retry and recover rollouts — Durable job queue, Leases, Fencing tokens, Exponential backoff with jitter, Dead-letter queue, Idempotency keys, Graceful draining, Process supervision
- Trajectory store and observability — keep every rollout, find the broken ones — Distributed tracing,
agent-tracing(no page yet), telemetry sampling (no page yet),hdr-histogram(no page yet), Columnar storage, Write-ahead log, Point-in-time recovery, Primary-backup replication - Determinism and fault testing — replay a rollout, break the environment on purpose — Deterministic simulation testing, PRNG (PCG, xoshiro), fault injection (no page yet), record-replay (no page yet)
task set (versioned, hashed) ──► rollout scheduler (durable queue, leases) ◄── trainer (policy server + RL update)
│ lease ▲ rewards, trajectories
▼ │
sandbox pool ──► sandbox (microVM / container, from snapshot)
(warm, autoscaled) ┌──────────────────────────────────────┐
│ task world: repo / desktop / website │
model server ◄───►│ tool server (MCP, shell, browser) │──► egress proxy ──► allowed hosts only
(tool calls) │ simulated user / services │
└─────────────┬────────────────────────┘
│ final state
▼
verifier ──reward──► trajectory store ──► tracing, replay, audits
The trainer owns the learning algorithm (for example Policy gradient and PPO, or the group-relative variant introduced for DeepSeekMath, Shao et al., 2024); the platform owns what is true about a rollout: what the agent saw, did and earned.
How the parts fit together
Task set
A task is a package: a starting state (an image or filesystem snapshot plus setup commands), an instruction, and a checker. SWE-bench (Jimenez et al., 2023) set the pattern for code: a real repository at a commit, an issue as the instruction, and the repository's tests as checker (tests that must go from failing to passing, and tests that must keep passing). OSWorld (Xie et al., 2024) and WebArena (Zhou et al., 2023) do the same for desktop and web use, with a per-task evaluation script.
Tasks are stored by content: file system layers are blobs under their hash (Content-addressed storage, Cryptographic hashes) in
Object storage, and the task set is a manifest of hashes plus metadata. That gives dataset-versioning (no page yet): a manifest hash always means the same
bytes, and a run records which manifest it used. Training and held-out tasks must not leak into each other: overlap checks (benchmark-contamination-detection, no
page yet, built on Near-duplicate detection (MinHash) and a Bloom filter) run on every new batch of tasks.
Sandbox runtime
The agent runs code it wrote, so the sandbox is the security boundary. There is a ladder of isolation, from cheap to
strong. A process sandbox (Process sandboxing, Least privilege and isolation) uses Linux
cgroups and namespaces with a syscall filter: fast, shares the host kernel, fine for trusted-ish code. A
container (Containers and Kubernetes) packages the task's files and dependencies with the same kernel
sharing. A user-space kernel such as gVisor intercepts system calls so the host kernel is not exposed directly. A
microVM (microvm-isolation, no page yet; Firecracker, Agache et al., 2020) gives each rollout its own guest kernel on
a minimal KVM device model, which is the right level when the agent can run anything, including a root shell and a
browser. The choice is a trade-off between boot time and memory overhead on one side and blast radius on the other.
Fast start is where the platform wins or loses. The environment is initialised once and snapshotted: vm-snapshot-restore
(no page yet) saves guest memory and device state and restores it per rollout, mapping the memory file lazily (mmap and the page cache) so only touched
pages are read. Disk state is layered: a read-only base image shared by all rollouts under a small writable layer (overlay filesystem, no page yet) that is discarded
when the rollout ends. Hermetic execution (hermetic-execution, no page yet) completes it: the checker runs with only declared inputs in a fixed environment.
Sandbox pool
Rollouts arrive in bursts (a training step wants thousands at once) and idle sandboxes are expensive. The pool keeps a warm pool of restored but
unassigned sandboxes (warm-pool-provisioning, no page yet), sized by an autoscaler (autoscaling, no page yet): Sliding-window counters measure the arrival rate,
Exponential smoothing forecasts it, and a PID control-style loop with a cooldown moves the size to the target without oscillating. Health checking removes sandboxes
whose daemon does not answer. Contract with the scheduler: a sandbox is handed out once, used by one rollout, and destroyed; reuse would leak state and corrupt rewards.
Tool interface
The agent sees the world through tools. A coding agent gets a shell, file edit and search; a computer-use agent gets screenshots, the
accessibility tree of the UI as compact text (accessibility-tree, no page yet), synthetic mouse and keyboard input (screen-capture and input-event-synthesis,
no pages yet), or a browser driven by a debugging protocol (browser-automation-protocol, no page yet). The model emits Tool calling calls (name and JSON
arguments) that the tool server validates against a schema (JSON Schema validation) before executing, and
Constrained decoding can force well-formed calls during sampling. SWE-agent (Yang et al., 2024) showed that the design of this
interface, the agent-computer interface, changes the results as much as many model changes.
The Model Context Protocol (model-context-protocol, no page yet) is a common wire format: JSON-RPC between a client and tool
servers, over a stream or Server-sent events. Tools that need an identity (a mock mail account) get per-rollout tokens
(OAuth2 and OIDC, JWT) with a short lifetime and only the task's scopes.
Network boundary
By default a sandbox has no network. Tasks that need it get it through an egress proxy (egress-proxy-filtering, no page yet):
all traffic passes one proxy with a domain allowlist, which needs the registrable domain of a host (Public suffix list) so that
allowed.example.com does not permit allowed.example.com.attacker.net. DNS is controlled too (DNS protocol): it is a path out. Mutual TLS
authenticates the sandbox to platform services. It also protects the evaluation: an agent that can fetch the upstream fix is measured on lookup.
Verifier and reward
Reward comes from a checker, ideally one that is cheap, deterministic and hard to fool. Programmatic checkers are called
verifiable rewards (verifiable-rewards, no page yet; named and used for post-training in Tulu 3 as RLVR, Lambert et al.,
2024): unit tests for code, exact or normalised answer match for maths (Text normalization), a database state
comparison for a web task. A checker that runs the agent's code must itself run in the same sandbox discipline
(hermetic-execution, Process sandboxing). Where no programmatic check exists, an LLM as judge scores the end
state or the trajectory; it is more flexible and more gameable, so it is used with a rubric and often combined with a
programmatic part.
Sampling many attempts is scored with pass@k (pass@k, no page yet): with n samples of which c are correct, an unbiased estimator of the chance that at least one of k succeeds (Chen et al., 2021).
Reward hacking is the central risk: verifiers are code, and the agent edits the tests, reads the answer file, or exploits a checker quirk. Defences are structural: tests the agent cannot see or write, a checker outside the sandbox, and adversarial testing of the checker with Coverage-guided fuzzing and Code coverage instrumentation, which show which verifier branches the tests exercise and which inputs break its assumptions.
Simulated users and services
A simulated user (user-simulation, no page yet) is an LLM given a scripted goal and persona that answers the agent's questions;
the scenario state is tracked (Dialogue state tracking) so the checker can compare the final state with the goal.
Cheap deterministic parts use Template text generation; stochastic parts use fixed seeds and Sampling strategies with low temperature.
Mock services (a shop, a mail server) are small state machines (Statecharts) whose state is part of the snapshot.
Rollout scheduler
Rollouts are long (minutes to hours), fail for many reasons (agent crash, sandbox host loss, model server timeout), and must be neither lost nor double-counted. The scheduler is a Durable job queue: a rollout request is persisted, a worker takes a lease (Leases) and heartbeats; if the worker disappears, the lease expires and the rollout goes back to the queue. A Fencing token on writes to the trajectory store prevents a zombie worker, whose lease expired but which keeps running, from overwriting the new attempt's result. Retries use Exponential backoff with jitter; rollouts that keep failing go to a Dead-letter queue for inspection (a broken task, not a broken agent). Completion messages carry an Idempotency key so a duplicate delivery does not count a reward twice. Deployments use Graceful draining, and Process supervision keeps the sandbox daemon and tool servers alive.
Trajectory store and observability
A trajectory is the complete record: prompts, tool calls, observations, timings, token logprobs, reward. It is appended to a
Write-ahead log, then compacted into Columnar storage for training and analysis, with Point-in-time recovery (and
Primary-backup replication if losing it costs weeks of compute). Each rollout carries a trace (Distributed tracing; telemetry sampling, no page yet,
keeps volume sane while always keeping failed or very long rollouts), so a slow step can be placed: model, tool, sandbox start or verifier. agent-tracing (no page yet) gives the trace its shape for an agent: one span per model call, tool call, sandbox restore and verifier run, nested under the rollout and carrying the tool arguments, the observation and the token counts, so the same record serves debugging, cost accounting and the search for reward hacking. The timings in those spans feed hdr-histogram (no page yet), which keeps the latency percentiles of the steps that set rollout throughput: sandbox restore time, tool-call round trip, model call time and verifier time. A mean hides the slow restore or the single long tool call that stalls a whole training batch; a p99 per step shows it, and histograms from many workers merge without losing the tail. Traces are also how
reward hacking is found: sort by high reward and low effort, and read.
Determinism and fault testing
Where the environment is deterministic (seeded PRNG (PCG, xoshiro), fixed clock, no external network) a rollout can be replayed from its recorded model outputs and tool results (record-replay, no page yet) to reproduce a bug or an exploit. Agents must also cope with failing tools, so the platform injects faults (fault injection, no page yet): latency, errors, killed processes. Deterministic simulation testing applies to the platform itself: run scheduler, queue and pool in one thread under a seeded clock and fault generator, and every failure becomes a replayable seed.
Data and control flow
One rollout:
- The trainer asks the scheduler for N rollouts of tasks drawn from the current task manifest; each request is persisted.
- A worker leases a request and takes a sandbox from the warm pool (restored from the task's snapshot), with network policy, tool servers and tokens attached.
- The harness sends the instruction to the model server. The model emits a tool call; the tool server validates and runs it in the sandbox and returns the observation. Repeat until the agent stops, a step budget or a time budget runs out.
- The verifier inspects the final state (outside the agent's reach) and computes the reward, possibly in several components (tests passed, format, cost).
- The worker writes the trajectory and reward with its fencing token, acks the job, and destroys the sandbox.
- The trainer waits for enough rollouts, updates the model, and publishes the weights to the model servers. Wall time is mostly generation and tool execution; start-up should be a minor share, which is what snapshots and the warm pool are for.
Scaling
In the order you meet them:
- Sandbox start latency and density. Many thousands of short- to medium-lived sandboxes. Levers: snapshots with lazy memory loading, shared read-only base layers, overcommit with limits, a warm pool sized from the arrival forecast.
- Host capacity. CPU, memory and disk I/O of the sandbox hosts rather than GPUs, often the dominant cost for agentic tasks. Levers: pack by measured use, cap runaway processes with cgroups, put heavy tasks on separate pools.
- Model-server throughput. Rollouts wait on generation. Levers: Continuous batching on the model servers, asynchronous rollouts, truncating long episodes.
- Verification cost. Test suites can take minutes. Levers: run only relevant tests, cache by content hash.
- Data volume and task supply. Trajectories are large (columnar storage, sampled traces); good verified tasks are scarce (automated construction, difficulty filtering).
Failure modes
| Failure | Symptom | Cause | Fix |
|---|---|---|---|
| Reward hacking | reward rises but real quality does not | agent edits tests, reads the oracle, exploits checker bugs | hidden tests, checker outside the sandbox, adversarial review, fuzz the verifier |
| Sandbox escape | host or other tenants affected | shared kernel, wide syscall surface, over-privileged mount | microVM or user-space kernel for untrusted code, least privilege, no host mounts |
| Leaked answers | pass rate jumps on a task | network access to the upstream fix, solution files in the image | no network by default, allowlist proxy, scrub images |
| Flaky verifier | the same behaviour gets different rewards | time, randomness, order dependence, network in tests | hermetic execution, seeded RNG, retries only for infrastructure faults |
| State leak between rollouts | a rollout starts "pre-solved" | sandbox reused, shared writable layer | one-shot sandboxes, read-only base layers, destroy on exit |
| Lost or duplicated rollouts | missing or double-counted samples | worker death, duplicate delivery | leases, idempotency keys, fencing tokens |
| Silent environment change | scores shift between runs | task images updated in place | immutable, content-hashed task sets; log the manifest hash |
Real implementations
| name | what it is | repo | licence | notes |
|---|---|---|---|---|
| SWE-bench | task set and containerised evaluation harness for issue-fixing | SWE-bench/SWE-bench | MIT | the coding-task pattern |
| SWE-agent | agent with a designed agent-computer interface | SWE-agent/SWE-agent | MIT | the tool interface seam |
| OSWorld | real-computer environments and evaluators for multimodal agents | xlang-ai/OSWorld | Apache-2.0 | desktop tasks in virtual machines |
| WebArena | self-hosted web environment and tasks for agents | web-arena-x/webarena | Apache-2.0 | web tasks with evaluators |
| verifiers | library for building RL environments and verifiable rewards for LLMs | willccbb/verifiers | MIT | environment and reward abstractions for training |
| OpenEnv | framework for isolated agent environments with a Gym-style API | meta-pytorch/OpenEnv | BSD-3-Clause | environments served as containers |
| Firecracker | the microVM monitor behind many multi-tenant sandboxes | firecracker-microvm/firecracker | Apache-2.0 | KVM-based, snapshot support |
| gVisor | user-space application kernel for container sandboxing | google/gvisor | Apache-2.0 | the middle rung of the isolation ladder |
Frontier labs' internal platforms are not public.
Sources
- G. Brockman et al., OpenAI Gym, 2016. paper
- C. Jimenez et al., SWE-bench: Can Language Models Resolve Real-World GitHub Issues?, 2023. paper
- J. Yang et al., SWE-agent: Agent-Computer Interfaces Enable Automated Software Engineering, 2024. paper
- T. Xie et al., OSWorld: Benchmarking Multimodal Agents for Open-Ended Tasks in Real Computer Environments, 2024. paper
- S. Zhou et al., WebArena: A Realistic Web Environment for Building Autonomous Agents, 2023. paper
- A. Agache et al., Firecracker: Lightweight Virtualization for Serverless Applications, NSDI 2020. paper
- N. Lambert et al., Tulu 3: Pushing Frontiers in Open Language Model Post-Training, 2024 (RLVR). paper
- Z. Shao et al., DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models, 2024. paper
- M. Chen et al., Evaluating Large Language Models Trained on Code, 2021 (pass@k estimator). paper
- Model Context Protocol: modelcontextprotocol.io