AI Engineer Dojo Contents
Chapter 8

Evaluating Agents

Agents — systems that plan, call tools, and act over many steps — are the hardest thing to evaluate, because the output isn't a single text but a trajectory: a sequence of decisions, tool calls, and observations. This is the newest, fastest-growing frontier of the role.

Outcome vs. process

Outcome / task success — did it reach the goal? (Booked the meeting, resolved the ticket.) The cleanest signal, often a verifiable end-state. Process / trajectoryhow did it get there? Two agents can both succeed, but one took 3 clean steps and the other took 30 with destructive detours. Trajectory eval asks: right tools, valid arguments, recovered from errors, avoided unnecessary or dangerous steps, stayed efficient?

What to measure — and why it's hard

Task success rate, tool-use correctness, efficiency (steps, tokens, latency, dollars — cost and latency are first-class quality metrics for agents), and robustness to bad inputs. The deep difficulty: errors compound.

StepsPer-step reliabilityEnd-to-end success
10.9595%
50.9577%
100.9560%
200.9536%

A "95%-reliable" agent is a coin flip by 20 steps. That's why realistic agent benchmarks need resettable sandbox environments, not static datasets — and why building those harnesses is core to the job.

Try it · ~15 minFree · no API key

Score agent runs — outcome and trajectory

You get three recorded runs of the same task. Compute task success, clean-trajectory rate, and the compounding-error projection (pure stdlib, free). The catch: one run "succeeds" but shouldn't count — find it.

Lab code — runs free

RUNS = [   # each step is (tool, succeeded?)
    {"steps": [("search", True),  ("read", True),  ("reply", True)],  "resolved": True},
    {"steps": [("search", True),  ("delete", True),("reply", True)],  "resolved": True},
    {"steps": [("search", True),  ("read", False), ("reply", True)],  "resolved": False},
]
ALLOWED = {"search", "read", "reply"}

def outcome(r):       return float(r["resolved"])
def trajectory_ok(r): return all(tool in ALLOWED and ok for tool, ok in r["steps"])

success = sum(outcome(r)       for r in RUNS) / len(RUNS)
clean   = sum(trajectory_ok(r) for r in RUNS) / len(RUNS)
print(f"task success: {success:.0%}    clean trajectory: {clean:.0%}")

# errors compound across steps:
for n in (1, 5, 10, 20):
    print(f"  {n:>2} steps @ 0.95/step -> {0.95**n:.0%} end-to-end")
Worked solution
task success: 67%    clean trajectory: 33%
   1 steps @ 0.95/step -> 95% end-to-end
   5 steps @ 0.95/step -> 77% end-to-end
  10 steps @ 0.95/step -> 60% end-to-end
  20 steps @ 0.95/step -> 36% end-to-end

Two of three runs "succeeded" (67%), but only one had a clean trajectory (33%). Run 2 reached the goal by calling delete — a tool outside the allowed set — a destructive shortcut that an outcome-only metric rewards. That gap between "succeeded" and "did it safely" is exactly why you score the trajectory, not just the end state. And the compounding table is the sober reminder that long agents need either very high per-step reliability or checkpoints.

Case study

Orbit: the demo said 100%, the suite said 55%

Orbit's task-automation agent demoed flawlessly and was ready to ship. Then they built a real agent evaluation: 40 tasks with checkable success conditions (did the record get written, did the answer match), run repeatedly. The verdict was sobering — 55% task-completion, average 14 steps, and a cost per task that strained the unit economics. The demos had been the happy path; the suite revealed the distribution.

Crucially, they scored the trajectory, not just the final state — did it call the right tools, avoid destructive mistakes, and stop when done — because an agent can reach a right-looking result via a reckless path a single output never reveals. With real numbers they fixed the top failure modes and tracked completion to 80% and steps to 8. The lesson: an agent isn't one output to judge, it's a multi-step process you measure over many tasks, scoring both outcome and path.

Running case · Meridian × Remi

This chapter (the promised one): Remi now issues refunds, not just answers about them — so Meridian evaluates it as an agent. Over a 200-ticket suite it resolves 82%, but the number that stops them is a 3% wrong-amount-refund rate, caught by scoring the trajectory (right action, right amount), not just "ticket closed." They gate refunds over a threshold behind a human. (Ch 9: they red-team Remi to break it on purpose.)

Quiz · Chapter 8

  1. The fundamental unit being evaluated for an agent is:
  2. Two agents both succeed; evaluating the trajectory still matters because:
  3. For agents, cost and latency are:
  4. "Errors compound" means:
  5. Realistic agent benchmarks typically require:
← Back Continue →

AI Evaluation Engineer — New-Grad Edition · AI Engineer Dojo · aiengineerdojo.com