ax experiment
Create, run, and analyze experiments.
| Command | Use |
|---|---|
experiment create | Scaffold a new experiment YAML. |
experiment validate | Check a YAML against the schema. |
experiment run | Run on the platform, or locally with --local. |
experiment query | Summarize results with filters and grouping, or raw SQL. |
experiment list | List experiments in the active org. |
experiment view | Inspect one registered experiment. |
experiment resource add | Attach titled links to an experiment. |
experiment resource edit | Change a resource's title or URL. |
experiment resource delete | Remove a resource. |
experiment push | Register a YAML without running it. |
experiment pull | Download registered YAML. |
experiment fork | Copy a registered experiment onto the current data pipeline. |
experiment versions | List stored versions. |
experiment variants | Resolve the variant matrix without running. |
experiment schema | Print the schema document. |
Platform-backed commands also accept --org <org-id> (target another org for
one command), and all but experiment push and experiment run accept
--json (machine-readable output); neither flag is repeated in the tables
below. Arguments marked required must be supplied; everything
else is optional, and flags combine freely unless a row says otherwise.
experiment create
Scaffold a new experiment YAML.
ax experiment create <NAME>| Argument / flag | What it does |
|---|---|
<NAME> | Required. Experiment name; writes <NAME>.yaml. |
--dir <dir> | Directory to write into (default .). |
--schema-version <n> | Schema version to scaffold (default: latest). |
--template cli-install | Scaffold the CLI-install starter experiment. |
--cli <name> | Target CLI or product name. Required with the template. |
--target-description <text> | What the target is, for the shared install task. Required with the template. |
--install-docs <url> | Install docs URL for the documented variant. Required with the template. |
--install-command <cmd> | Exact install command for the explicit variant. Required with the template. |
--smoke-command <cmd> | Hidden smoke command the harness reruns after the agent finishes. Required with the template. |
--smoke-output-contains <text> | Text the smoke command's output must contain (template only). |
--force | Overwrite an existing <NAME>.yaml (template only). |
Examples:
# Blank scaffold
ax experiment create my-experiment
# Starter experiment: can agents install your CLI?
ax experiment create my-first-experiment --template cli-install \
--cli mycli_name \
--target-description 'a CLI for managing OLAP databases' \
--install-docs https://example.com/install \
--install-command 'npm install mycli_name' \
--smoke-command 'mycli_name --version' \
--smoke-output-contains 'mycli_name version'experiment validate
Check an experiment YAML against the schema; exits non-zero on schema errors.
ax experiment validate <EXPERIMENT.yaml>| Argument / flag | What it does |
|---|---|
<EXPERIMENT.yaml> | Required. Path to the experiment file. |
--no-ai | Skip the AI review; run only the static schema checks and lints. |
Schema errors are fatal. Advisory lints print warning[<rule>] on stderr and still exit zero. warning[grading-details-in-prompt] means a prompt names a test or echoes its description; keep scoring in tests and describe a realistic job in the prompt. See Experiment design.
When signed in, validation also prints an advisory AI review of the
experiment design to stderr, including checking whether the experiment is
designed in a way that lets the agent know it is being evaluated. It never
changes the exit code, so a suggestion is not a failure. Skip it with --no-ai
or AX_NO_AI_LINT=1; pick a different review model with AX_AI_LINT_MODEL.
experiment run
Run an experiment: submit to the platform (default) or run locally in Docker
with --local.
ax experiment run <EXPERIMENT.yaml | EXPERIMENT_ID>| Argument / flag | What it does |
|---|---|
<EXPERIMENT.yaml | EXPERIMENT_ID> | Required. A local YAML path, or a registered experiment id for platform runs. |
--repeat <n>, -n | Run each variant N times (default 1). |
--detach | Submit and exit instead of polling. Platform runs only (not with --local). |
--version <fingerprint> | Run a specific registered version. Only with an experiment-id target; not with --local. |
--flag <name> | Enable a named run-request flag (repeatable). |
--file <spec>, --file-sha256 <spec> | Bind or add staged files. With a registered id, explicit values override stored dependencies for this run only. |
--mock | Deterministic mock driver; no model spend. |
Target a subset of variants with selectors, all repeatable or comma-separated:
--variant, --prompt, --agent, --model, --product, --environment.
Same flag ORs; different flags AND (--agent cursor --model X runs only
variants using agent cursor and model X). Exact --variant ids are
additive on top. Each selected variant is included once.
Local-only flags:
| Argument / flag | What it does |
|---|---|
--local | Run in Docker on this machine instead of the platform. |
--watch / --watch-raw | Live-tail agent events (pretty / raw JSONL). |
--jobs <n>, -j | Concurrency across the local matrix (default 1). |
--resolve-variants | Print the resolved matrix and exit. |
--env <NAME[=VALUE]> / --env-file <path> | Extra local secret sources (repeatable). |
--output-root <dir> | Where to put .axp/runs/<id>/ (default .). |
--local-model-keys | Use host provider keys instead of managed model access (default local runs are managed; sign-in / AX_API_KEY required). |
--api-base-url <url> | Platform URL for managed model access (default local or remote). |
Examples:
# Platform run, polling until done
ax experiment run my-experiment.yaml
# Local run with live agent events
ax experiment run my-experiment.yaml --local --watch
# Two prompts only, three repeats each
ax experiment run my-experiment.yaml --prompt baseline,explicit --repeat 3
# A specific registered version
ax experiment run my-experiment --version <fingerprint>On an attached platform run, if any run contains evidence that the agent is
aware that it is being tested, it is classified as "test aware" and a warning
prints on stderr. It does not change the exit code. Inspect the run with
run view, or list them with
run list --agent-test-aware. See
runs where the agent noticed it was being tested.
experiment query
Query an experiment's results: flag-based modeled summaries, or SQL via the
sql subcommand. Save SQL as insights with --save.
ax experiment query <EXPERIMENT_ID>
ax experiment query <EXPERIMENT_ID> sql --tables| Argument / flag | What it does |
|---|---|
<EXPERIMENT_ID> | Required. Experiment id, as shown on the platform Results page. |
sql <SQL|@file|-> | ClickHouse SQL in experiment scope: inline text, @file.sql, or - for stdin. |
--tables [<NAME>] | List queryable tables, or describe one table. --table is an alias. |
--format json|table | Force NDJSON or an ASCII table. Defaults to table on a TTY and json when piped. |
--experiment-version <v> | latest (default) or a version fingerprint. Modeled queries only. |
--limit <n> | Max rows (default 100). |
--dry-run | Validate and print the compiled SQL without executing. |
--include-test-aware | Count runs classified as "test aware" (the agent noticed it was being tested), which both query modes leave out by default. Those runs may not mimic real-world agent behavior. See runs where the agent noticed it was being tested. |
--save <heading> | Save the query as an insight. --slug, --description, --label, and --force only apply together with it. |
Experimental flag-based modeled queries (metrics with filters and grouping, no SQL) also work; the surface may change:
| Flag (experimental) | What it does |
|---|---|
--metric <name> | Metrics per group (repeatable): testPassRate, testsPassed, testsFailed, cost, wallClockTime, tokens, toolCalls, toolFailures. Default: testPassRate, cost, wallClockTime, tokens, toolFailures. |
--group-by <dimension> | Group by variant, agent, model, product, environment, prompt, or test. List the observed values of each with --dimensions. |
--stat <stat> | Aggregate statistic per group. Only mean is supported today (the default). |
--filter <dimension=value> | Filter on agent, product, environment, or prompt, e.g. --filter agent=claude or --filter prompt=baseline. |
--agent / --product / --environment / --prompt | Shorthand dimension filters (repeatable). |
--dimensions [<dimension>] | Discover dimension values and metric names. |
Both modes leave out runs classified as "test aware" (the agent noticed it was
being tested) by default. Only the modeled query reports the count, as a note on
stderr (N test-aware runs excluded · pass --include-test-aware to include them); SQL
applies the same exclusion silently. Passing --include-test-aware counts them;
those runs may not mimic real-world agent behavior. For SQL scoped to one composite run id, use
run query; run scope is never filtered that way.
Examples:
# What is queryable
ax experiment query my-experiment sql --tables
# Ad-hoc SQL in experiment scope
ax experiment query my-experiment sql @query.sql --format table
# Save the query as an insight
ax experiment query my-experiment sql @query.sql --save "Failing tests"
# Experimental: pass rate by variant, no SQL
ax experiment query my-experiment --metric testPassRate --group-by variant
# Experimental: cost and tokens per prompt, claude runs only
ax experiment query my-experiment --metric cost,tokens --group-by prompt \
--filter agent=claude
# Experimental: which test fails most?
ax experiment query my-experiment --metric testPassRate --group-by test
# Experimental: what dimensions and metrics exist?
ax experiment query my-experiment --dimensionsexperiment list
List experiments in the active org, most recently updated first.
ax experiment list| Argument / flag | What it does |
|---|---|
--search <text> | Case-insensitive match on experiment name or id. |
--owner <email-or-id> | Only experiments created by this owner. |
--agent / --model / --product / --environment | Dimension filters (repeatable). Same flag ORs; different dimensions AND. |
--since <when> | Updated at or after this time (RFC 3339 or YYYY-MM-DD). |
--limit <n> | Max experiments (default 50, platform cap 500). |
experiment view
Show a metadata summary of one registered experiment: ownership, timestamps, run tally, resolved axes, latest version, and resources.
ax experiment view <EXPERIMENT_ID>| Argument / flag | What it does |
|---|---|
<EXPERIMENT_ID> | Required. Experiment id (the YAML's id field). |
Human output lists each resource as title, resource UUID, and URL after
Description: (same place as the experiment page). An empty list is a dash.
--json adds a resources array (id, title, url, created_at,
updated_at). Resources are not in the YAML; push and pull ignore them.
get is an alias of view.
experiment resource add
Attach one titled link, or several in one invocation. --title and --url
are repeatable and zip in order; counts must match.
ax experiment resource add <EXPERIMENT_ID> --title <TITLE> --url <URL>| Argument / flag | What it does |
|---|---|
<EXPERIMENT_ID> | Required. Experiment id (the YAML's id field). |
--title <text> | Required. Display title, 1 to 200 characters after trim. Repeatable. |
--url <url> | Required. http:// or https:// URL, max 2048 characters. Repeatable. Pair with --title in order. |
Same title or same URL twice is allowed. A non-http URL, or unpaired
--title / --url, is an error.
Examples:
# One plan doc
ax experiment resource add <EXPERIMENT_ID> \
--title "Experiment plan" --url https://docs.google.com/document/d/<DOC_ID>
# Plan and report together
ax experiment resource add <EXPERIMENT_ID> \
--title "Experiment plan" --url https://docs.google.com/document/d/<DOC_ID> \
--title "Mongo report" --url https://docs.google.com/presentation/d/<SLIDES_ID>experiment resource edit
Change a resource's title, URL, or both. Copy <RESOURCE_ID> (a UUID) from
ax experiment view. At least one of --title or --url is required.
ax experiment resource edit <EXPERIMENT_ID> <RESOURCE_ID> --title <TITLE>| Argument / flag | What it does |
|---|---|
<EXPERIMENT_ID> | Required. Experiment id (the YAML's id field). |
<RESOURCE_ID> | Required. Resource UUID from experiment view. |
--title <text> | New title. |
--url <url> | New URL. Same http(s) rules as add. |
A missing resource id is an error.
experiment resource delete
Remove a resource. rm is an alias. No confirmation prompt.
ax experiment resource delete <EXPERIMENT_ID> <RESOURCE_ID>| Argument / flag | What it does |
|---|---|
<EXPERIMENT_ID> | Required. Experiment id (the YAML's id field). |
<RESOURCE_ID> | Required. Resource UUID from experiment view. |
A missing resource id is an error, not a silent success.
experiment push
Register an experiment and its declared file dependencies on the platform without running it. Pushing unchanged YAML keeps the same version id and replaces its stored file manifest.
ax experiment push <EXPERIMENT.yaml>| Argument / flag | What it does |
|---|---|
<EXPERIMENT.yaml> | Required. YAML whose dependencies are resolved relative to its directory. |
--file <spec>, --file-sha256 <spec> | Bind a named dependency for this push. The uploaded value becomes part of the stored manifest. |
experiment pull
Download a registered experiment's YAML and stored dependencies as a runnable local package (latest version by default).
ax experiment pull <EXPERIMENT_ID>| Argument / flag | What it does |
|---|---|
<EXPERIMENT_ID> | Required. Experiment id (the YAML's id field). |
--output <path>, -o | Write here (default <experiment-id>.yaml). |
--version <fingerprint> | Pull a specific stored version instead of the latest. |
--force | Overwrite the destination YAML and restored dependencies if they exist. |
--stdout | Write only the YAML to standard output instead of restoring a package. Cannot be combined with --output, --force, or --json. |
--json | Print the receipt, including restored dependency paths, as JSON; the package still goes to disk. |
Output streams
By default the YAML goes only to the file, never to standard output. The receipt prints to standard output on a terminal and to standard error when output is redirected, so a piped default pull writes nothing to standard output and cannot overwrite the file it just created.
To capture the definition from a script or an agent, ask for it explicitly:
ax experiment pull <EXPERIMENT_ID> --stdout > experiment.yamlexperiment fork
Copy a registered experiment onto the current data pipeline as a new experiment, without creating runs.
ax experiment fork <EXPERIMENT_ID>| Argument / flag | What it does |
|---|---|
<EXPERIMENT_ID> | Required. Experiment to copy (the YAML's id field). |
--new-id <id> | Id for the new experiment (default <EXPERIMENT_ID>-v2, with a counter appended when that id is taken). Fails if the id already exists. |
--name <name> | Display name for the new experiment (default: the source name followed by (V2)). |
--long-ids | Show the full 64-char version fingerprint instead of the 7-char prefix. |
The fork registers the source's latest stored definition and dependencies again
under the new id, with only id and name rewritten in the YAML, and claims
the copy on the current results pipeline. The source experiment is only read:
its runs, versions, and results are unchanged. Use it when an experiment's
results are held in the retired data pipeline and you want to run the same
definition again; ax experiment run <NEW_ID> picks up from there.
Examples:
# Fork with derived id and name, then run the copy
ax experiment fork my-first-experiment
ax experiment run my-first-experiment-v2
# Choose the new identity
ax experiment fork my-first-experiment --new-id my-first-experiment-2026 --name "My first experiment (2026)"experiment versions
List stored versions of a registered experiment, newest push first.
ax experiment versions <EXPERIMENT_ID>The VERSION column is the friendly first-created ordinal (v1, v2, ...);
re-pushing an older definition can move it to the top without changing its
ordinal.
The AGENT TEST AWARENESS column reads - until a run classified as "test
aware" (the agent noticed it was being tested) traces back to the experiment
content itself, and needs iteration · <n> runs from then on, where n counts those
runs. Runs a platform artifact caused leave the column at -, since the
definition is not what needs changing. With --json, each row carries the same
signal as needs_iteration and test_aware_run_count.
experiment variants
Preview what a YAML resolves to before running it: how many variants the cross
product yields, which incompatible agent and model pairs were pruned, and the
exact variant ids to use with ax experiment run --variant.
ax experiment variants <EXPERIMENT.yaml>| Argument / flag | What it does |
|---|---|
<EXPERIMENT.yaml> | Required. Path to the experiment file. |
--json | Emit the resolve-response JSON the platform client parses. |
--runtime | Tolerant re-resolution of an already-submitted run (accepts the legacy nested agents[].model shape). |
experiment schema
Print the experiment schema document.
ax experiment schema [--schema-version <n>]