Skip to main content

ageval

agent eval — lock a dataset, bind environment and agent, run the same task.

English · 中文    Release Python

[!IMPORTANT] Most agent evaluation still sits at the model: same prompts, same tool contract, different weights or APIs. That split is failing. A shippable agent is a Model plus a Harness: the same weights on a different coding-agent runtime, tool policy, or isolation change behavior and cost. Harness has to be a first-class eval axis, locked with the Model and the environment.

ageval decouples the runtime of a bench run. Environment and Agent combine through plugins, so one run.py runs under each binding.

N environments × M harnesses: each combination would need its own scaffold; ageval composes environment and harness through plugins, so one eval runs anywhere.

Contents

What it is

ageval treats Harness as a first-class evaluation axis.

  • The unit of delivery is a dataset. A dataset holds tasks; each task owns the loop (run.py), the score (evaluator.py), and gold. Environment and Agent bind on the job, not in the task.
  • An Attempt is visible. Order is environment → run → evaluate → record; cleanup always runs.
  • Environment is injected by name. The environment winner exports the service name environment. An agent backend injects that name and requires the capabilities it needs (attach_stdio or exec). Missing capability fails at lock. Calls stay on the Protocol. Default is the host and local docker; cloud sandboxes e2b and daytona are optional.
  • Coding agents enter through plugins. Default is ACP (pi, Codex, Claude Code, OpenCode); heterogeneous harnesses such as nooa, dsh, and miniswe join the same way. Open slots extend the harness set and run on the same Attempt path and leaderboard.

How it works

            you ── lock / run ──►  ┌─────────────────┐
                                   │     Attempt     │  lock dataset · digest
                                   │   ageval core   │  environment → run
                                   │                 │  evaluate → record
                                   │                 │  finally cleanup
                                   └────────┬────────┘
                                            │ opens one environment
              ┌─────────────────────────────┼─────────────────────────────┐
              ▼                             ▼                             ▼
        ┌───────────┐                 ┌───────────┐                 ┌───────────┐
        │   local   │                 │  docker   │                 │ e2b/ssh/daytona │
        └─────┬─────┘                 └─────┬─────┘                 └─────┬─────┘
              └──────── Protocol: upload · exec · attach_stdio ───────────┘
                                            │
                                            ▼
                                   ┌─────────────────┐
                                   │     run.py      │  task loop · Agent invoke
                                   │  ACP / plugin   │  plugin inlet
                                   └────────┬────────┘
                                            ▼
                                   ┌─────────────────┐
                                   │  evaluator.py   │  only source of PASS
                                   └─────────────────┘
  1. Lock the experiment. Dataset, Environment, and Agent are composed into a digest. Secrets remain locators; they are not stored as plaintext in the lock.
  2. Open an environment. Host, docker, a cloud sandbox, or a remote. Insufficient capability or missing credentials fail before the environment opens.
  3. Execute the task. run.py owns the loop, tools, and Agent invocation. Changing the environment or the Agent does not require rewriting the task.
  4. Score independently. Gold enters the environment at this point. evaluator.py binds PASS / FAIL / ERROR. Cleanup always runs.

Features

Evaluation

  • Lock one experiment. Dataset, Harness, and environment lock together into a reproducible digest.
  • One task, a suite, a matrix, or repeats. Run a single task, a full dataset, a parameter matrix on one task, or multiple independent Attempts of the same job (pass@k).
  • Scoring is separate from the Agent. Gold does not enter the Agent view. PASS comes only from evaluator.py (deterministic script by default; optional Agent.session as LLM-as-judge). Trajectories are for inspection.
  • Limits are enforced before invocation. Wall time, memory, processes, and invocation ceilings are set by the runtime before invoke.

Composition

  • One run.py under each binding. Environment and Agent combine through plugins. Default is ACP; heterogeneous harnesses such as nooa, dsh, and miniswe join through the same plugin path. Open slots extend or replace a harness and participate in the same Attempt path and leaderboard.
  • Agent packages. A harness (ageval.agent/1: executor, entry, overlays). Shipped mechanism cards bind with --agent pi (no install). Custom overlay packs still ageval agent install then --agent org/name@version. binding.model is the default; --model overrides this run.
  • Multiple roles and sessions. The task owns dialog, tools, and handoff; the runtime supplies the environment and the Agent inlet.
  • Validate before invoke. Capabilities and credentials are checked before the Agent is called; absence fails and invoke does not start.

Environment

  • Host, container, cloud sandbox, remote — one Protocol. local, docker, e2b, ssh, daytona: upload / exec / attach_stdio.
  • Visibility is isolated. The Agent sees only the projected workspace; gold and host credentials do not enter the task default environment.
  • Official Attempt image. Docker installs ACP entries at build time; they are not installed at invoke.

Results

  • Local Viewer. Inspect trajectory, environment, and score along Jobs → Tasks → Attempt.
  • Sealed trajectory. Export a copy without modifying the score.
  • Hub. Publish datasets, plugins, and Agent packages; upload suites. Organizations manage members, visibility, and versions. The public Leaderboard lists complete, release-bound suites only. Operators can docker compose -f services/registry/docker-compose.yml up -d (Postgres, object store, Registry, Hub) and pull ghcr.io/zju-real/ageval-hub / ageval-registry from a release tag.

Authoring

  • The task owns only that task. Loop, tools, scoring, and gold; orchestration does not belong in the task.
  • SDK is optional. Sessions, tools, terminals. It does not decide PASS and does not hold host credentials.

Getting started

Requires uv and CPython 3.12+. A live coding-agent run also requires a host ACP entry and credentials. ageval lock does not.

git clone https://github.com/ZJU-REAL/AgEval.git
cd ageval
uv sync --frozen --all-packages
uv run ageval -V
uv run ageval tasks examples/datasets/minimal-demo
uv run ageval lock examples/datasets/minimal-demo --task terminal-jsonl-agg
uv run ageval run  examples/datasets/minimal-demo --task terminal-jsonl-agg
uv run ageval run  examples/datasets/minimal-demo --task terminal-jsonl-agg \
  --profiles examples/datasets/minimal-demo/profiles.e2b-acp.yaml --probe
uv run ageval executors -v
uv run ageval view examples/datasets/minimal-demo --no-browser

Default examples/datasets/minimal-demo profiles use environment: docker. Bind a shipped harness with --agent pi (no install). Optional --model overrides this run. Custom overlay packs still use ageval agent install then --agent org/name@version.

In-repo examples: examples/README.mdminimal-demo, a five-task tau3-airline cut, and catalog Agents.

Architecture

  ageval.yaml + task.yaml + profiles.yaml
                 │
                 ▼
           ageval lock                 digest · extension_bindings
                 │
                 ▼
           ageval run  ── Attempt ── environment → run → evaluate → record
                 │                      finally cleanup
                 ▼
        .ageval/runs/<id>/             lock.json · result.json · trajectory.jsonl
                 │
      ┌──────────┼──────────┐
      ▼                     ▼
 ageval view          Registry / Hub
 local Jobs           publish · upload-suite · Leaderboard
  • lock is the normative gate: unknown format fails once. Plugins change the binding, not the five Attempt phases.
  • Attempt owns identity, deadlines, cleanup, and the score.
  • Local Viewer reads files; Hub talks to Registry.

Project structure

Simplified from ARCHITECTURE.md. Generated trees (.ageval/, .venv/) are not source.

ageval/
├── src/ageval/
│   ├── cli/                         # argv, help, exit code
│   ├── application/
│   │   ├── composition.py           # sole production wiring; CLI imports build_* here
│   │   ├── lock.py                  # load_and_lock
│   │   ├── run.py                   # mint identity → run_attempt
│   │   ├── campaign.py / suite/     # matrix · suite · Always-k
│   │   └── agent_ops/ / plugin_ops / registry_ops/
│   ├── attempt/                     # visible pipeline
│   │   ├── __init__.py              # run_attempt
│   │   └── phases/                  # environment → run → evaluate → record · cleanup
│   ├── config/                      # dataset + task.yaml + profiles
│   ├── environments/protocol.py     # EnvironmentProvider · caps; no vendor SDK
│   ├── plugins/
│   │   ├── slots.py                 # exclusive / chain
│   │   └── contrib/                 # acp · local · docker · e2b · daytona · ssh
│   ├── runtime/                     # identity, parent Agent Service, task_worker
│   ├── evaluation/                  # barrier + bind PASS
│   └── evidence/                    # trajectory.jsonl layout
├── src/ageval_sdk/                  # ageval_sdk for run.py (no PASS, no host credentials)
├── plugins/                         # external ageval.plugin/1 (nooa, dsh, miniswe, …)
├── examples/
│   ├── datasets/
│   │   ├── minimal-demo/            # terminal-jsonl-agg · tau2-dialog-min · multiagent-env-min
│   │   └── tau3-airline/            # airline-00 … airline-04
│   └── agents/                      # ageval.agent/1
├── apps/viewer                      # ageval view SPA
├── apps/hub                         # Hub SPA
├── services/registry/               # package + results HTTP
├── docker/attempt/                  # official image; ACP entries baked in
├── docs/                            # mechanism design
└── website/                         # product docs

Docs

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ageval_cli-0.7.1.tar.gz (4.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ageval_cli-0.7.1-py3-none-any.whl (1.6 MB view details)

Uploaded Python 3

File details

Details for the file ageval_cli-0.7.1.tar.gz.

File metadata

  • Download URL: ageval_cli-0.7.1.tar.gz
  • Upload date:
  • Size: 4.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","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}

File hashes

Hashes for ageval_cli-0.7.1.tar.gz
Algorithm Hash digest
SHA256 4f2ed8b4c30fee8a2002b505ac27b794a064bb8a5d652b5cad788829e8905f2d
MD5 866d9a735c443e68d83af6bf15cfc145
BLAKE2b-256 f382abd95eab873c7e1f465bc042caea8d0f97b5e6f863b16d5b5b22387b5b1f

See more details on using hashes here.

File details

Details for the file ageval_cli-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: ageval_cli-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 1.6 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","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}

File hashes

Hashes for ageval_cli-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0c44480a2b8fa440707c62a2623d9a3d6a70dfc77348251f1b8f32667f0abce1
MD5 22d1d430f151926a1a838cf42a8cc5fc
BLAKE2b-256 9fcf6a9c79b309d7a648089c1676cabd624a4f01583ceeafeab7248167793d56

See more details on using hashes here.

Release history Release notifications | RSS feed

0.8.1

2 files

0.8.0

2 files

0.7.3

2 files

0.7.2

2 files

This release

0.7.1 This release

2 files

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