Skip to main content

Ajax

Reinforcement-learning agents in JAX, compiled end to end with the environment,
including average-reward, expert-guided and world-model agents.

A whole training run, environment and every seed included, one compiled program.

Documentation CI Python License JAX

Ajax is a library of reinforcement-learning agents written in JAX. Compared with Stable-Baselines3 and its JAX version SBX, it differs in four ways:

  • End to end on the accelerator: the environment and the training loop compile into one JAX program, as in PureJaxRL, Rejax, Stoix and Brax's training agents, with no Python step between them, on a CPU or a GPU.
  • Average-reward agents: ASAC and APO maximise the reward per step, with no discount, for tasks that never end.
  • Expert-guided agents: learn from a controller you already have, or from recorded transitions, by cloning, imitation, residual policies, hand-over, prior data in the replay or offline training (methods below).
  • World models: DreamerV3 and TD-MPC2, following the code behind their papers' results.

Why Ajax shows each with an example and compares Ajax with SB3, SBX, PureJaxRL, Brax, Stoix and Rejax, including when to use them instead.

It has sixteen agents, from SAC and PPO to DreamerV3 and TD-MPC2, each implementing a published paper, with the places where it departs from that paper written down. Several seeds train side by side in one program, on a CPU or a GPU. Research features (learning from an expert, exploration rules, diagnostics) are extensions, passed as extensions=(...) rather than added as new arguments to the agents. An agent refuses, when built, an extension it cannot run; the compatibility table shows which agent runs which.


Installation

Ajax is on PyPI as ajax-rl, for Python 3.12 or newer, and imports as ajax:

pip install ajax-rl
pip install "ajax-rl[playground]"  # with Brax and MuJoCo Playground

JAX comes for the CPU; on a Linux machine with an NVIDIA GPU, add CUDA with ajax-rl[cuda]. Brax and MuJoCo Playground environments need an extra: ajax-rl[playground], which brings Brax, or ajax-rl[brax] alone (Installation). pip takes the newest versions that pyproject.toml allows; main installs with pip install "ajax-rl @ git+https://github.com/YannBerthelot/Ajax.git".

From source, uv installs the versions in uv.lock, which CI tests, with the development tools and the playground extra (uv sync --extra cuda adds CUDA):

git clone https://github.com/YannBerthelot/Ajax.git
cd Ajax
uv sync   # creates .venv with the locked dependencies

Installation covers the extras (cuda, compare, reproduction) and the dependency groups.

Quickstart

from ajax import PPO
from ajax.logging.wandb_logging import LoggingConfig

agent = PPO("CartPole-v1")  # 4 environments x 2048-step rollouts: one update per 8,192 steps
# Evaluate after every update; use_wandb=False keeps the results in memory only.
logging = LoggingConfig(config={}, log_frequency=8_192, use_wandb=False)
state, evaluations = agent.train(seed=[1, 2, 3], n_timesteps=40_960, logging_config=logging)

print(evaluations["timestep"][0])                # when each evaluation ran
print(evaluations["Eval/episodic mean reward"])  # one row per seed, one column per evaluation

The three seeds train together, and the run takes about fifteen seconds on a laptop CPU, compilation included. evaluations maps each logged name to an array of shape (seeds, evaluations); "Eval/episodic mean reward" is the mean return of 10 test episodes (num_episode_test). With use_wandb=True (the default) or use_tensorboard=True, the same records also go to Weights & Biases or TensorBoard. To train further, pass the state back: agent.train(seed=[1, 2, 3], n_timesteps=more, initial_state=state).

Features are arguments of the same agents:

from ajax import PPO, SAC
from ajax.extensions.instrumentation import ConditioningMetrics

# A recurrent actor and critic, for when one observation is not enough.
agent = SAC("Pendulum-v1", memory={"kind": "lstm", "hidden_size": 64})

# A research feature as an extension: the critic's health at each evaluation.
agent = PPO("CartPole-v1", expose_recent_rollout=True, extensions=(ConditioningMetrics(),))

# Brax and MuJoCo Playground environments by id (their extras), here 8 copies in parallel.
agent = PPO("ant", n_envs=8)

The quickstart guide goes on from here.


Agents

Agent Kind Paper Actions Memory
SAC off-policy Haarnoja et al., Soft Actor-Critic, 2018 (arXiv:1801.01290) continuous yes
ASAC off-policy, average reward Adamczyk et al., Average-Reward Soft Actor-Critic, 2025 (arXiv:2501.09080v2) continuous yes
REDQ off-policy Chen et al., Randomized Ensembled Double Q-Learning, 2021 (arXiv:2101.05982) continuous yes
TD3 off-policy Fujimoto et al., Addressing Function Approximation Error in Actor-Critic Methods, 2018 (arXiv:1802.09477) continuous yes
AVG incremental, no replay Vasan et al., Deep Policy Gradient Methods Without Batch Updates, Target Networks, or Replay Buffers, 2024 (arXiv:2411.15370) continuous no
IQL offline Kostrikov, Nair & Levine, Offline Reinforcement Learning with Implicit Q-Learning, ICLR 2022 (arXiv:2110.06169) continuous no
DQN off-policy, value-based Mnih et al., Human-level control through deep reinforcement learning, Nature 2015 discrete no
PQN on-policy, value-based Gallici et al., Simplifying Deep Temporal Difference Learning, 2024 discrete no
PPO on-policy Schulman et al., Proximal Policy Optimization Algorithms, 2017 (arXiv:1707.06347) both yes
APO on-policy, average reward Ma et al., Average-Reward Reinforcement Learning with Trust Region Methods, 2021 (arXiv:2106.03442) both no
UDRL supervised, command-conditioned Schmidhuber, Reinforcement Learning Upside Down, 2019 (arXiv:1912.02875) both no
DAgger imitation, supervised Ross, Gordon & Bagnell, A Reduction of Imitation Learning and Structured Prediction to No-Regret Online Learning, AISTATS 2011 (arXiv:1011.0686) both no
APG differentiable simulation Analytic policy gradient through the simulator; APG.contextual_controller is Busetto et al., One controller to rule them all, 2024 (arXiv:2411.06482) continuous yes
DreamerV3 world model Hafner et al., Mastering Diverse Domains through World Models, 2023, Nature 2025 (arXiv:2301.04104v2) both built in
TDMPC2 world model, planning Hansen, Su & Wang, TD-MPC2: Scalable, Robust World Models for Continuous Control, ICLR 2024 (arXiv:2310.16828) continuous no
TDMPC2MultiTask world model, offline The same paper's multi-task agent: one model trained offline on the data of several tasks continuous no

Memory says whether the agent accepts memory=; DreamerV3's world model is recurrent by design. Every agent is importable from ajax (from ajax import TD3). The algorithms overview helps choose one.


Learning from an expert or from data

Each method is an extension or an agent option. The last column lists the agents that accept it, as the compatibility table, generated from the code, does.

Method In Ajax Agents
Behaviour cloning before training CloningPretrain SAC, TD3, REDQ, ASAC, AVG, APO, DAgger
TD3+BC's actor term (Fujimoto and Gu, 2021); kickstarting (Schmitt et al., 2018) with anneal_frac ImitationLoss SAC, TD3, REDQ, ASAC, AVG, APO, DAgger; PPO, APG, UDRL with a stateless expert; continuous actions only
Q-filtered behaviour cloning (Nair et al., 2018) ImitationLoss(q_filter=True) SAC, TD3, REDQ, ASAC, AVG
IBRL targets (Hu et al., 2023) IBRL SAC, TD3, REDQ, AVG
Residual RL (Johannink et al., 2019) ResidualPolicy SAC
Jump-start RL hand-over (Uchendu et al., 2023) JSRLCurriculum SAC
Expert transitions in the replay before training expert_buffer_n_steps SAC
Prior data in the replay, as RLPD (Ball et al., 2023) without its symmetric sampling, then optional offline updates PriorData with a transition dataset (ajax.buffers.dataset) SAC, TD3, REDQ, ASAC, DQN
Offline training on a transition dataset, then online fine-tuning agent.train_offline(dataset, n_updates) SAC, TD3, REDQ, ASAC, DQN, IQL
Implicit Q-learning, offline then online (IQL, Kostrikov et al., 2022) IQL with train_offline its own agent
Conservative Q-learning, offline (CQL, Kumar et al., 2020); calibrated (Cal-QL, Nakamoto et al., 2023) ConservativeQ, CalQL on SAC, trained with train_offline CQL: SAC, REDQ, ASAC, IQL; Cal-QL: SAC, REDQ, IQL
ReBRAC, offline (Tarasov et al., 2023) TD3 with TD3+BC's term and TargetBC, trained with train_offline TD3
Adversarial imitation from demonstrations, with no reward (GAIL, Ho and Ermon, 2016) AdversarialReward with a transition dataset PPO, continuous actions
TD3+BC, offline (Fujimoto and Gu, 2021) TD3 with ImitationLoss(None, target="replay", alpha=2.5), trained with train_offline TD3; the term on SAC, REDQ, ASAC too
Offline multi-task training on pooled datasets (TD-MPC2, Hansen et al., 2024) TDMPC2MultiTask its own agent
Interactive imitation by dataset aggregation, with no reward (DAgger, Ross et al., 2011) DAgger its own agent
Features developed with Ajax, with no external reference: EDGE exploration, LCB-gated targets, a value-gated hand-over, an expert critic fitted to Monte-Carlo returns and the extensions that read it EDGEExploration, LCBGatedBootstrap, ValueBox, MCPretrain, ... SAC (LCB: SAC, TD3, REDQ)

Expert guidance explains the expert's conventions and how the pieces combine.


What else is in the box

  • Extensions: twenty-four of them, for expert guidance, exploration, critic-target changes, actor and critic pre-training, prior data, offline RL, adversarial imitation, ensemble diversity and critic diagnostics, passed as extensions=(...); the compatibility table says which agents run each one.
  • Expert guidance: the expert reads the environment's raw observations and answers in the environment's action units; an expert with a state, such as a PID's integral, gets it back at every step.
  • Recurrent memory: a GRU, LSTM, transformer or Mamba block for PPO, SAC, TD3, REDQ, ASAC and APG, with R2D2-style sequence replay (burn-in, stored state) for the replay agents.
  • Differentiable simulation: APG back-propagates the return through gymnax dynamics, across system classes (distributions over physical parameters), with Busetto et al.'s in-context controller and its staged curriculum.
  • World models: DreamerV3 and TD-MPC2 (single- and multi-task), following the paper-era official code, with specifications, deviations and parity tests against that code.
  • Networks and the PID policy: layers and initialisers named by strings, a CNN encoder for image observations (PPO, DQN, PQN, UDRL), and a PID controller as the actor of SAC, TD3, REDQ, ASAC, AVG, PPO or APO, with learned fixed gains that deploy as a plain PID, or gains scheduled on the observation. Where an agent starts from its reference code's initialisation and optimiser settings, its algorithm page says so and cites the code.
  • Environments: gymnax, Brax and MuJoCo Playground by id, n_envs copies in parallel, terminations kept apart from time limits (a truncated episode still bootstraps), episode_length and action_repeat on every agent, and wrappers for normalisation, observation noise, fixed initial states, model-reference tracking and PID error terms. Every continuous agent acts in [-1, 1], mapped onto the environment's action bounds.
  • Logging: train returns every evaluation as arrays, with training diagnostics (gradient norms, PPO's approximate KL, explained variance, ...) and each extension's own metrics, and a background worker sends them to Weights & Biases or TensorBoard.
  • Comparing agents: ajax.compare runs AdaStop (Mathieu et al., 2024), which trains more seeds only while the answer is unclear, and ajax.compare.estimate gives one agent's metrics confidence intervals that stay valid however many seeds are added.
  • Reproduction: Ajax agents trained beside a reference implementation (Stable-Baselines3, Brax, the authors' code) on the same JAX environment, run on demand from benchmarks/reference, under a written protocol; the results so far cover PPO and PQN.
  • Checkpoints and resuming: pass a state back to train further, or save it and resume in another process; the tests check that a split run matches the run left whole.
  • Tests: unit tests check one component against an exact contract with no learning, written once for every agent or extension that shares the contract. Probes are tiny generic environments with known answers: each agent trains on them briefly, and each probe checks one capability of the whole agent. A catalogue of planted bugs lists the probes that should catch each one; CI checks that every bug still applies to the code, and planting them to run the probes is done by hand. Conformance checks run one update of an agent and of its original implementation from the same state and compare them (PQN, TD3, TD3+BC, REDQ and AVG so far).
  • Performance: seeds vectorised with jax.vmap, a persistent compile cache, one per machine and JAX version, and a per-agent benchmark script, run by hand, that flags slowdowns over 10% against a recorded baseline.

Documentation

Getting started Installation and a guided quickstart
User guide Training, environments, networks, memory, logging, checkpoints, performance
Research features Extensions, compatibility, expert guidance, comparing agents, differentiable simulation, world models
Reproduction Ajax against reference implementations: protocol, specifications, results
Algorithms One page per agent: the paper, when to use it, an example, its parameters and deviations
API reference Generated from the docstrings
Developer guide Architecture, contributing, writing an extension, testing, performance
World model design notes DreamerV3 and TD-MPC2 specifications, deviations and validation

The site, with search and navigation, is at yannberthelot.github.io/Ajax. The links above point at the Markdown in this repository, which also reads on GitHub.


  • TargetGym: JAX environments for reaching and holding a setpoint, with tuned PID and MPC baselines. A scenario of Ajax's benchmarks/perf_bench.py trains on one of its aircraft tasks (uv sync --group plane).
  • ProbingEnvironments: small environments with known answers, used by Ajax's probing tests.
  • gymnax, Brax and MuJoCo Playground: the environment libraries Ajax trains on.
  • flashbax: the replay buffers of SAC, ASAC, REDQ, TD3, DQN, IQL and DAgger (UDRL and the world models keep their own).

Contributing

Bug reports, new agents and new extensions are welcome. After installing, run uv run pre-commit install once, so ruff and mypy check every commit. CONTRIBUTING.md explains where the code lives, how to add an agent or an extension, and how the tests check them. Every pull request runs pre-commit, the tests, the conformance checks and a strict build of the documentation site in CI; the slow tier, every test that trains, also runs daily on main, on a pull request labelled run-slow-tier, and before each release. make ci runs the checks locally (about an hour of CPU).

Citation

@misc{ajax2025,
  title        = {Ajax: Reinforcement Learning Agents in Jax},
  author       = {Yann Berthelot},
  year         = {2025},
  url          = {https://github.com/YannBerthelot/Ajax},
}

License

MIT, see LICENSE.

Metadata

Release files for ajax-rl 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ajax-rl 0.4.0
File Size Uploaded Provenance
ajax_rl-0.4.0.tar.gz 442.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ajax-rl 0.4.0
File Interpreter ABI Platform
ajax_rl-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 976.3 kB

Release files / ajax_rl-0.4.0.tar.gz

Download URL ajax_rl-0.4.0.tar.gz
Size 442.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f8fa023cc0c9aa84aa281ce3c8f12704cb7b300c64eeb002a27122d0132e9bfb
BLAKE2b-256 checksum
How to use checksums
a2d7c8a1a233604f8c0f3767856011c6be3c403e2f961f2171c5ce878178365c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ajax_rl-0.4.0-py3-none-any.whl

Download URL ajax_rl-0.4.0-py3-none-any.whl
Size 533.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0f8ffbde826764ce23b568a013de4939410bd5066d0b946d2e2c36dd8c31d4fa
BLAKE2b-256 checksum
How to use checksums
61e7abdbf25f388fa9a4cd9bd83745537d067c077668a4fc51d1fff27c746d6b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for ajax-rl 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page