Evaluate agents, train them with RL, and collect rollout data across any agent and any sandbox — one Python call, no bespoke microservice per pairing and no changes to the agent.
Docs · Quickstart · Cookbook · Roadmap
Agentix is the universal bridge between agents and environments — the single path connecting any agent, any sandbox, and any model for evaluation, RL training, rollout-data collection, and observability. It stays small on purpose: two ideas (a bundle and a remote call) plus one model-call bridge (abridge), with no heavy stack of disconnected sandbox runners, rollout services, and agent frameworks to hold together. Five core capabilities:
- Drive a sandbox with a Python function — call any importable callable inside the box and get its typed value back; extend the loop by writing another function.
- Eval/run any agent, in any sandbox, with any model — abridge tunnels the agent's LLM calls to the host and translates Anthropic → OpenAI-compatible at the wire (more directions on the roadmap), so an off-the-shelf agent runs against whatever provider you have, with no agent changes.
- Train any agent as an RL rollout — no code change — the agent is an opaque trajectory producer; Agentix makes no assumption about how it is built.
- Every model call stamped and traced — abridge tags each call with session/request ids at the transport layer and records prompt, completion, and token usage as trace spans; trainer-ready token-in/token-out capture is being built on top of this.
- Observability for free — every model call becomes an OTel span, exportable to LangSmith / LangFuse / Docent / any OTLP backend with zero agent instrumentation.
|
Claude Code · mini-SWE-agent · Qwen Code · your own |
SWE-bench images · custom Docker/Podman · Apptainer · your own backend |
|
⇣ bridged by ⇣ await sandbox.remote(fn, *args, **kwargs) |
|
Agentix is small on purpose. The whole framework is two operations:
| You write | You get | |
|---|---|---|
| Bundle | agentix build [path] |
A deploy-ready image with your code and its dependencies |
| Remote call | await sandbox.remote(fn, ...) |
The return value of fn, executed inside the sandbox |
fn is any importable Python callable — an agent, a shell helper, a
scorer, or a whole multi-step rollout. Args travel in, the typed return
value comes back out. There is no fixed RPC surface to conform to and no
base class for your code to inherit.
from app import run
result = await sandbox.remote(run, input="hello")Side traffic rides along automatically: stdlib logging from inside the
sandbox replays into your host logs, and OTel-shaped /trace spans
capture every step — ready for eval dashboards and RL buffers.
git clone https://github.com/Agentix-Project/Agentix && cd AgentixBuild a bundle once (takes a few minutes), then every remote call is
seconds. From examples/hello-world:
cd examples/hello-world
uv sync
uv run agentix build . --output dist/hello-world.bundle.tar
BUNDLE=$(uv run agentix deploy docker dist/hello-world.bundle.tar --format json | jq -r .bundle)
uv run python main.py --bundle "$BUNDLE"The host code is just provider → session → remote call:
from agentix.bash import run
from agentix.provider.base import SandboxConfig
from agentix.provider.docker import DockerProvider
config = SandboxConfig(image="python:3.13-slim", bundle=BUNDLE)
async with DockerProvider().session(config) as sandbox:
result = await sandbox.remote(run, command="echo hello from $(uname -a)")Build a cross-arch bundle by passing --platform linux/amd64 to both
agentix build and agentix deploy. Full walkthrough:
quickstart.
The point of one call surface is that an eval or RL loop wires together out of the same primitive — the agent, the environment setup, and the scorer are all just functions you remote-call:
| You have | You expose | You call |
|---|---|---|
| An agent (Claude Code, Qwen Code, …) | async def run(...) -> RunResult |
await sandbox.remote(run, ...) |
| Shell, files, repo setup | async def run(command: str) -> BashResult |
await sandbox.remote(bash_run, ...) |
| A benchmark or reward model | async def score(...) -> Score |
await sandbox.remote(score, ...) |
examples/run-swe-rollouts is the
full loop end to end: sandbox agent run → patch extraction → SWE-bench
harness score → one rollout log per instance.
vs. sandbox runners (swe-rex,
E2B, Daytona, Harbor). A runner hands you a box and a fixed way to reach
into it — a predefined RPC surface, or "run a shell / docker exec
command" plus a vendor SDK. Anything richer means squeezing your logic
through that narrow hole. Agentix inverts it: the bundle installs your
real Python, and sandbox.remote(fn, ...) calls any importable
function and returns its typed value. A backend decides where the box
runs; Agentix decides what you can call inside it — so you layer it on
top of Docker/Podman or Apptainer today, with managed backends on the
roadmap.
| swe-rex · E2B · Daytona · Harbor | Agentix | |
|---|---|---|
| Reach into the sandbox | Fixed RPC surface, or shell / docker exec + vendor SDK |
await sandbox.remote(fn, ...) — any importable function |
| Sandbox logs & stdout | Scrape command output | stdlib logging and captured stdout/stderr auto-bridged to the host over /log, plus a durable in-sandbox sandbox-<id>.log |
| Observability | Bring your own | /trace spans (OTel-shaped) for every step |
| Model under test | Whatever the agent's SDK speaks | abridge translates Anthropic → OpenAI-compatible at the wire — Claude-speaking agents on OpenAI, OpenRouter, vLLM, your gateway |
vs. rollout-as-a-service (ProRL-Agent-Server). ProRL popularized an HTTP server with task-specific handlers and token trajectories for RL trainers. Agentix shares the decoupling — training stays separate from rollout execution — with a lighter surface.
| ProRL-Agent-Server | Agentix | |
|---|---|---|
| Add a new task | Implement a handler, register it | Write a function, install it |
| Call a rollout | HTTP request to the service | await sandbox.remote(fn, ...) |
| Trajectories | Token-in / token-out over the service API | abridge stamps session/request ids + per-call trace spans; token-in/token-out capture in development |
| Sweet spot | HPC-scale multi-turn RL fleets | Teams wiring eval + RL data without a platform team |
Both designs are powerful at HPC scale. Agentix targets the much larger
set of research and product teams that want await remote(fn) with fewer
moving parts.
Five capabilities, one primitive underneath each:
await sandbox.remote(fn, ...) runs any importable Python callable
inside the sandbox and returns its typed value. No fixed RPC surface to
conform to, no base class to inherit — extend the loop by writing another
function. The agent, the repo setup, the scorer are all just functions
you remote-call. Captured stdout/stderr (print, subprocess output),
stdlib logging, and OTel-shaped /trace spans from inside the sandbox
replay on the host automatically over /log; the same output is also
kept in a durable $AGENTIX_LOG_DIR/sandbox-<id>.log for post-mortem.
Bring an off-the-shelf agent (Claude Code, mini-SWE-agent, Qwen Code, or
your own), drop it in a backend (Docker/Podman, Apptainer, or your own
SandboxProvider; managed backends like Daytona and E2B are stubbed on
the roadmap), and point it at your model.
abridge tunnels the agent's LLM calls back
to the host and translates Anthropic → OpenAI-compatible at the wire —
so a Claude-speaking agent runs against whatever you've got: OpenAI,
OpenRouter, a private vLLM/SGLang, your own gateway. More translation
directions (OpenAI → Anthropic, Gemini) are on the
abridge roadmap. The tunnel carries JSON
request/response bodies and buffers responses (no incremental streaming
yet) — see the abridge README for the exact
contract.
Agentix treats the agent as an opaque trajectory producer and makes no assumption about how it's built: single-shot or multi-turn, deep-thinking loops, hierarchical multi-agent — all opaque internal logic. Because every completion request crosses the bridge, the exact context presented to the model at each call is observable on the per-call trace span, with zero instrumentation in the agent. The same run you evaluate is the run you train on.
abridge stamps every model call with a
session id (per rollout) and request id (per call) at the transport
layer — the agent never sees it — and records prompt, completion, and
token usage on the call's trace span. That gives an upstream gateway
everything it needs to group a rollout's calls; trainer-ready
token-in / token-out capture is being built on top of this (see the
abridge roadmap). Nothing to wire into the
agent: the same run you evaluate is the run you train on.
Every model call abridge tunnels also becomes an OTel-shaped span — tagged
with GenAI semantic conventions (model, token usage, prompt/completion
content, tool calls) — and fed into the core /trace system. Register one
Processor (agentix-trace-otel) and the
full agent trajectory exports to LangSmith, LangFuse, Docent, Phoenix,
or any OTLP backend. The agent stays pristine — Agentix derives the
spans from the traffic it already bridges, so there is nothing to
instrument.
One monorepo, separate packages (agentixx and agentix-runtime-basic
are on PyPI today; the rest install from source while publishing catches
up). The core is agentixx; everything else is an optional plugin under
plugins/.
| Package | Role |
|---|---|
agentix-runtime-basic |
agentix.bash, file ops, sandbox primitives |
agentix-provider-docker · -apptainer · -uv |
Sandbox backends — Docker/podman, Apptainer, and a local uv-materialized runtime (no container) (-daytona · -e2b are placeholders pending integration) |
agentix-runner |
run_rollouts(...) — batch eval/rollout orchestration |
agentix-dataset-swe |
SWE-bench task images + official-harness scoring |
agentix-agent-claude-code · -mini-swe-agent · -qwen-code |
Agent adapters |
agentix-bridge |
Model translation + tunnel-traffic recording (abridge) |
agentix-tito |
Token-in / token-out session-recording gateway |
agentix-trace-otel |
Export /trace spans to any OTLP backend |
Drop a directory under plugins/ and it becomes a workspace member;
uv sync --all-packages installs it editable.
git clone https://github.com/Agentix-Project/Agentix
cd Agentix
uv sync --all-packages --all-extras
uv run pytest
uv run ruff check agentix/ tests/This repo is a uv workspace — core, plugins, and examples share one lockfile, so editing any member is live in the shared venv with no publish cycle. See ARCHITECTURE.md for how bundles and remote calls work under the hood.