Agent Arena

Running evaluations

Preflight, trials, concurrency, timeouts.

Always validate first

arena validate --project projects/my_project

Checks config, test files and credentials, and exits non-zero on a problem. It takes a second and catches the mistakes that would otherwise surface after a partial spend.

Then plan

arena evaluate --project projects/my_project --dry-run

Prints the full matrix and a cost estimate, and calls nothing. Do this before any first paid run — models × cases × trials grows faster than people expect. Four models, 50 cases and 3 trials is 600 calls.

Preflight and skipping

Before spending, the runner asks each model whether it can run. A model whose credential is missing is skipped, not failed:

  skipping opus_5: ANTHROPIC_API_KEY is not set

The run continues without it, and the model appears in the leaderboard with status no_data and the skip reason. Silently omitting it would make a four-model comparison look like a three-model one.

If every model would be skipped, the run raises instead — an empty leaderboard is not an answer:

every model would be skipped, so there is nothing to run: opus_5 (ANTHROPIC_API_KEY is not set).
Export the missing API key(s), or add a `mock:` model to compare against.

This is the failure mode to watch in CI. A misconfigured secret produces a green build that evaluated only your mock models. arena validate fails on missing credentials; put it before evaluate.

Trials versus cases

Add To measure
More cases Whether the model handles your task — improves generalisation
More trials How consistently it does — improves variance estimates

Cases are usually the better investment. Ten cases run three times tells you about consistency on ten situations; thirty cases run once tells you about thirty situations. When the leaderboard says two models are too close to call, it almost always means add cases.

Set temperature: 0 and trials still vary, because providers are not fully deterministic. That variance is real and worth knowing.

Concurrency

run:
  concurrency: 8

Default 4. The right value is the largest your provider tolerates without rate limiting — raising it past that makes a run slower, because every rejected call becomes a retry with backoff. See performance.md.

Local models are usually limited by your hardware. High concurrency against a single GPU queues rather than parallelising.

Timeouts and retries

run:
  timeout_s: 120.0
  retries: 2
  retry_backoff_s: 2.0

Retries are classified: a 401, 403, 400, 404 or 422 fails immediately rather than sleeping through attempts it cannot fix. 429s and 5xx retry with full jitter, and a Retry-After header is honoured when the provider sends one.

Raise timeout_s for large local models or long generations; the default assumes a hosted model answering promptly.

Filtering a run

arena evaluate --project p --tags hard              # only hard cases
arena evaluate --project p --exclude-tags slow
arena evaluate --project p --ids case_1 case_2      # specific cases
arena evaluate --project p --limit 20               # cap the count
arena evaluate --project p --models sim_small       # one model

Iterating on a scorer? Run one mock model over a handful of cases. It is free and instant.

Reading progress

··x······xx···x···xxxxxx···xxxxx······x··xx· 144/144
Mark Means
· Passed
x Ran, scored as incorrect
! Errored
? Other status

A wall of x early usually means a scorer misconfiguration, not a bad model — stop and check with --limit 5 before spending the rest.

Interruption

Ctrl-C exits 130. The run is closed out as aborted with its partial results attached, so the database never holds a row stuck at running.

There is no resume yet: an interrupted run starts over. See ../roadmap/status.md.

After the run

arena report  --project p                 # re-show the latest
arena report  --project p --run-id <id>   # a specific run
arena history --project p                 # runs over time
arena history --project p --flaky         # unstable cases