Module 11 · Agent evals, every modality

Multi-agent and long-horizon evals

Two frontiers break the "one prompt, one answer" picture completely: agents that work for hours on a single task, and systems where several agents talk to each other. Both need new yardsticks: time horizons instead of accuracy, milestones instead of pass/fail, and trace trees instead of transcripts.

Advanced~50 minPrereqs: Modules 04, 05, 07

By the end of this module you can

  • Explain, with numbers, why errors compound over long tasks and why "per-step accuracy" hides it.
  • Describe METR's 50% time-horizon metric precisely, compute one yourself with logistic regression, and state its limitations.
  • Compare how RE-Bench, MLE-bench, PaperBench, GDPval and Vending-Bench score long tasks, and design milestone-based partial credit for your own.
  • Evaluate context management and memory in long runs, and report cost and wall-clock budgets alongside success.
  • Name the common multi-agent architectures and say what to measure in each: end-to-end outcome, per-agent contribution, communication overhead and token multiplier.
  • Use the MAST failure taxonomy to label coordination failures, walk a trace tree to assign credit, and reason about emergent risks like collusion and cascading errors.
  • Explain why needle-in-a-haystack results overstate long-context ability, and build RULER-style multi-hop, aggregation and distractor tests to find a model's effective context length.
  • Evaluate cross-agent delegation over A2A and agent payments (AP2, ACP, x402): delegation correctness, handoff fidelity, task-state handling, payment authorization and spending limits.

Two ways an eval gets "big"

Everything so far in this course has had a comfortable shape: one agent, one task, a few dozen steps, a grader at the end. This module is about the two directions in which that shape stretches until it breaks.

Long-horizon: stretched in time

One agent works on one task for a long time: hundreds of tool calls, hours of wall-clock time, millions of tokens. Think "train a model that wins a Kaggle medal", "replicate this research paper", or "run a small business for a simulated year".

Multi-agent: stretched in width

Several agents (often copies of the same model with different instructions) split a task, pass messages, check each other, or argue. Think "a lead researcher agent that spawns five search agents and a citation checker".

They share a common difficulty: the thing you care about (did the whole job get done?) is far away from the things you can easily observe (individual steps, individual messages). The rest of this module is about closing that gap: measuring the whole, and also measuring the parts well enough to know why the whole failed.

Analogy: the relay team and the marathon

A marathon runner who holds a great pace for 30 km but collapses at 35 km still does not finish. That is long-horizon failure: every step looked fine, the total did not. A relay team can have four fast runners and still lose because of a dropped baton. That is multi-agent failure: the individual parts are good, the handoffs are not. A coach of either needs split times (milestones), not just the final result.

Part A · Why long tasks are hard: compounding error

Start with the simplest possible model of an agent. Each step (a tool call, an edit, a decision) succeeds with probability p, independently, and the task needs n steps to all go right. Then the probability of finishing is:

P(task succeeds) = pn

This looks harmless until you plug in numbers. A 99%-reliable step sounds excellent. But over 50 steps, 0.9950 ≈ 0.61, and over 100 steps it is about 0.37. At 95% per step, a 20-step task succeeds only about 36% of the time, and a 100-step task essentially never.

0 0.5 1.0 0 20 40 60 80 100 number of steps that must all succeed (n) P(task succeeds) 50 steps: 0.61 20 steps: 0.36 100 steps: 0.37 p = 0.99 per step p = 0.95 per step p = 0.90 per step
Compounding error, computed. Curves are exact values of pn. Small per-step error rates that look fine in a step-level eval become near-certain failure on long tasks. Real agents are not this simple (see below), but the direction is right.

Why the simple model is both too pessimistic and too optimistic

Real agents violate the independence assumption in two opposite directions, and knowing both is what separates an expert from someone who just quotes pn.

Too pessimistic: recovery

Good agents notice mistakes and fix them: a failed test is re-run, a wrong file is reverted. If a step fails with probability 0.05 but is caught and repaired 80% of the time, the effective unrecoverable failure rate is 0.01, and 100 steps succeed 37% of the time rather than 0.6%. Error recovery is the single biggest lever on long-horizon success, so evals should measure it directly.

Too optimistic: errors that snowball

Some errors are not independent: a wrong assumption early ("the config lives in /etc") poisons every later step. The agent also sees its own mistakes in its context and may copy them. Vending-Bench (below) documents agents falling into "meltdown loops" they rarely escape. These correlated failures make long tasks harder than the formula suggests.

Key idea: step accuracy is the wrong headline

A step-level eval ("did the agent pick the right tool on this turn?", Module 06) is valuable for debugging, but it hides compounding. Two agents at 97% and 99% step accuracy look similar; over 100 steps one finishes about 5% of tasks and the other about 37%. For long tasks, always report an end-to-end number, and treat step-level numbers as diagnostics.

Worked example: what a per-step improvement is worth

Suppose your coding agent's typical task takes about 40 consequential actions, and you measure an unrecoverable-error rate of 2% per action. Predicted end-to-end success is 0.9840 ≈ 0.45. A change that halves the error rate to 1% predicts 0.9940 ≈ 0.67. A 1-point step improvement buys about 22 points end to end. That is why teams chase what look like tiny reliability gains, and why you should not be surprised when an end-to-end eval moves much more than a step-level one.

METR's time horizon: measuring length directly

If long tasks are what matter, one natural question is: how long a task can this agent complete? METR (Model Evaluation and Threat Research, a nonprofit that evaluates frontier models) turned that question into a metric in the paper "Measuring AI Ability to Complete Long Tasks" (Kwa, West et al., March 2025).

The recipe, step by step

  1. Build a task suite spanning a huge range of lengths. METR combined three suites: SWAA (very short software actions, seconds long), HCAST (a diverse set of software, ML and cyber tasks of minutes to hours), and RE-Bench (ML research-engineering tasks of about 8 hours). The paper describes these as "RE-Bench, HCAST, and 66 novel shorter tasks".
  2. Time human experts. Skilled professionals attempt each task, and the time they take becomes that task's human time. This is the crucial move: task difficulty is measured in a unit everyone understands (minutes of expert labor), not in an abstract score.
  3. Run each model many times on each task (roughly 8 runs per model per task, per Epoch AI's summary of the method) and record success or failure.
  4. Fit a logistic curve of model success probability against the logarithm of human time. Success is high on short tasks and falls off on long ones.
  5. Read off the horizon. The 50% time horizon is the human task length at which the fitted curve crosses 50% success. METR also reports an 80% horizon, which is always shorter.
0% 50% 80% 100% 1 min 4 min 15 min 1 h 4 h 16 h time a human expert takes (log scale) model success rate 50% horizon ≈ 1 h 80% horizon ≈ 15 min circles: observed success rate of tasks in each length bin line: fitted logistic curve
How a time horizon is read off (illustrative). Synthetic numbers for one imaginary model. The fit uses every individual run, not the binned circles; the circles just help you see the data. Where the curve crosses 50% is the 50% horizon; the 80% horizon is shorter because it asks for more reliability.

Formally, with t the human time and σ the logistic (sigmoid) function:

P(success | t) = σ( β0 + β1 · log2(t) )        with β1 < 0
50% horizon    = 2 ^ ( -β0 / β1 )               (where β0 + β1·log2(t) = 0)
q% horizon     = 2 ^ ( (logit(q) - β0) / β1 )   logit(q) = ln(q / (1-q))

Why log time? Because task lengths span five orders of magnitude, from seconds to days, and success falls off roughly evenly per doubling of length, not per extra minute. The slope β1 tells you how sharp the fall-off is: a steep slope means the model is reliable up to a length and then collapses; a shallow slope means it sometimes succeeds even on very long tasks and sometimes fails even on short ones.

The headline result, and what it does and does not mean

In the March 2025 paper, METR reported that Claude 3.7 Sonnet had a 50% time horizon of "around 50 minutes", and that the frontier 50% horizon "has been doubling approximately every seven months since 2019", with a faster pace in 2024 to 2025. METR has since published Time Horizon 1.1 (January 2026), which uses a larger task suite with the same method, and maintains a live page at metr.org/time-horizons (which, when checked on 29 September 2026, said it was last updated 8 May 2026). Current per-model values change often; read them from that page rather than from any course.

1 sec 1 min 15 min 1 h 8 h 2019 2020 2021 2022 2023 2024 2025 2026 50% time horizon (log) Claude 3.7 Sonnet ≈ 50 min (METR paper, Mar 2025) ×2 every ~7 months extrapolation only
The doubling trend (sketch). Only the ~50-minute point and the ~7-month doubling time come from METR's March 2025 paper; the line is drawn from those two facts, not from individual model measurements. A straight line on a log axis means exponential growth. The dashed segment is extrapolation, not data; see metr.org for measured values.
Limitations METR itself stresses

METR's notes "Clarifying limitations of time horizon" and "Impact of modeling assumptions" make points every expert should repeat:

  • It is a statistic of a task distribution, mostly software and ML tasks. "A 2-hour horizon" does not mean "the model can work unsupervised for 2 hours on anything".
  • Confidence intervals are wide at the frontier, because there are few very long tasks to pin the curve down.
  • "Messy" and low-context tasks lower performance. Benchmark tasks are cleaner than real work, so real-world horizons are probably shorter.
  • Modeling choices (how tasks are weighted, how human time is estimated, which curve is fitted) move the numbers.

Compute a time horizon yourself

This snippet simulates a model whose true 50% horizon is 60 minutes, then recovers it from pass/fail data with scikit-learn. It also computes a bootstrap confidence interval (Module 04) by resampling tasks, because the 8 runs of one task are correlated and resampling runs would make the interval too narrow.

import numpy as np
from sklearn.linear_model import LogisticRegression

rng = np.random.default_rng(0)

# 1) Synthetic task suite: 120 tasks, each with a human-expert completion time (minutes)
human_minutes = np.exp(rng.uniform(np.log(1), np.log(960), size=120))  # 1 min .. 16 h

# 2) Pretend agent whose "true" 50% horizon is 60 min (we will try to recover it)
TRUE_H50, TRUE_SLOPE = 60.0, 0.7
def p_success(minutes):
    return 1 / (1 + np.exp(TRUE_SLOPE * (np.log2(minutes) - np.log2(TRUE_H50))))

# 3) 8 runs per task (METR used roughly this many), each a Bernoulli draw
RUNS = 8
x = np.repeat(np.log2(human_minutes), RUNS).reshape(-1, 1)  # feature: log2(human time)
y = rng.random(len(x)) < p_success(2 ** x[:, 0])            # 1 = success, 0 = failure

# 4) Fit success ~ sigmoid(b0 + b1 * log2(minutes)); C=np.inf means no regularisation
clf = LogisticRegression(C=np.inf).fit(x, y)
b0, b1 = clf.intercept_[0], clf.coef_[0, 0]

# 5) Solve sigmoid(b0 + b1*t) = q  ->  t = (logit(q) - b0) / b1
def horizon(q, b0, b1):
    return 2 ** ((np.log(q / (1 - q)) - b0) / b1)

print(f"50% horizon: {horizon(0.5, b0, b1):6.1f} min   (true {TRUE_H50})")
print(f"80% horizon: {horizon(0.8, b0, b1):6.1f} min")

# 6) Bootstrap over TASKS (not runs): runs of one task are correlated
tasks = np.arange(len(human_minutes))
h50s = []
for _ in range(500):
    pick = rng.choice(tasks, size=len(tasks), replace=True)
    idx = (pick[:, None] * RUNS + np.arange(RUNS)).ravel()
    m = LogisticRegression(C=np.inf).fit(x[idx], y[idx])
    h50s.append(horizon(0.5, m.intercept_[0], m.coef_[0, 0]))
lo, hi = np.percentile(h50s, [2.5, 97.5])
print(f"95% CI for 50% horizon: {lo:.1f} to {hi:.1f} min")

# Output (numpy 2.4, scikit-learn 1.9):
# 50% horizon:   59.3 min   (true 60.0)
# 80% horizon:   17.8 min
# 95% CI for 50% horizon: 50.2 to 70.6 min

Even with 960 runs, the 95% interval spans roughly 50 to 71 minutes. Real suites have fewer long tasks than this synthetic one, which is exactly why METR's frontier intervals are wide. Try shrinking the task count to 30, or removing all tasks above 4 hours, and watch the interval explode.

Deep dive: using a time horizon for your own agent

You do not need METR's suite to borrow the idea. If your agent handles support tickets, code migrations, or data analyses, ask a few experienced humans to time themselves on a sample of 50 to 200 real tasks. Run the agent several times on each. Fit the same logistic curve. You now have an interpretable number ("our agent reliably handles 20-minute tickets, and is coin-flip on 90-minute ones") and a slope that tells you whether failures are length-driven (steep) or driven by something else (shallow). Two cautions: human times vary a lot between people, so use the geometric mean of several timings where you can; and do not extrapolate outside the range of task lengths you actually measured.

Long-task benchmarks and how they score

A family of benchmarks targets tasks that take humans hours or days. What makes them instructive is that each had to invent a scoring scheme, because "did it pass?" is too coarse for an 8-hour task. The details below come from each benchmark's paper.

RE-Bench 7 ML research envs 0 start 1 reference agent 0.6 continuous score, normalized vs 61 human experts at fixed time budgets score in [0, 1+] MLE-bench 75 offline Kaggle comps gold cut-off silver cut-off bronze cut-off submission graded on the competition's private board, placed among human teams % comps with a medal PaperBench replicate 20 ICML papers paper code run result 8,316 weighted leaf criteria, written with paper authors, graded by an LLM judge replication score % GDPval 44 occupations, real deliverables model doc expert doc blinded expert better / as good / worse tasks written by professionals with 14+ years' experience win-or-tie rate
Four ways to grade a long task. Each benchmark trades off objectivity against realism: a normalized score (RE-Bench) and a leaderboard rank (MLE-bench) are objective; a rubric tree (PaperBench) gives partial credit; expert pairwise comparison (GDPval) handles open-ended deliverables that no script can check.
BenchmarkTaskScoringNumbers worth knowing (source, date)
RE-Bench
METR, Nov 2024
7 open-ended ML research-engineering environments, e.g. optimize a GPU kernel, fine-tune GPT-2 for question answering.Continuous score normalized so the provided starting solution is 0 and a reference solution is 1.Compared against 71 eight-hour attempts by 61 human experts. Agents beat humans at a 2-hour budget; humans pulled ahead at 8 to 32 hours (Wijk et al., 2024).
MLE-bench
OpenAI, Oct 2024
75 Kaggle competitions run offline: train models, submit predictions.Graded against each competition's private leaderboard. Headline: % of competitions earning any medal.At release, o1-preview with the AIDE scaffold earned medals in 16.9% of competitions at pass@1. Runs take about 24 hours on a GPU (Chan et al., 2024).
PaperBench
OpenAI, Apr 2025
Replicate 20 ICML 2024 Spotlight/Oral papers from scratch.Hierarchical rubrics with 8,316 gradable leaf criteria, co-written with the papers' authors; an LLM judge grades, validated on a JudgeEval set.Best at release: Claude 3.5 Sonnet (New) at 21.0%; ML PhDs scored 41.4% on a subset (Starace et al., 2025).
GDPval
OpenAI, Sep 2025
1,320 tasks across 44 occupations in 9 industries (220-task open "gold" set): legal briefs, care plans, slide decks, spreadsheets.Blinded expert pairwise comparison against a human professional's deliverable. Metric: win-or-tie rate.At launch, Claude Opus 4.1 was rated best overall (strong on aesthetics and formatting), GPT-5 best on accuracy. Tasks are one-shot, with no iteration (OpenAI, 2025).
Vending-Bench
Andon Labs, Feb 2025
Run a simulated vending-machine business: order stock, set prices, pay daily fees.Net worth at the end (starting from $500), plus units sold and days until sales stop.Runs exceed 20 million tokens. All models had runs that "derail" (forgotten orders, "meltdown" loops), with no clear link to when the context window filled (Backlund and Petersson, 2025). Superseded by Vending-Bench 2 (Nov 2025).

What these benchmarks teach about long-horizon evals

  • Budgets are part of the task. RE-Bench's human-versus-agent result flips depending on whether you allow 2 hours or 32. A long-horizon score without its time, token and compute budget is not interpretable.
  • Variance is enormous. Vending-Bench's most striking finding is not the average: it is that the same model can run a profitable business in one run and melt down in the next. Report distributions (or pass^k, Module 04), not just means.
  • Graders get harder as tasks get longer. Short tasks have unit tests. Long, open-ended tasks push you toward rubrics and LLM judges (PaperBench) or expensive human experts (GDPval), each of which must itself be validated (Module 13).
  • Realism costs reproducibility. GDPval's deliverables are realistic but need expert graders; MLE-bench is reproducible but Kaggle solutions are public, raising contamination questions (Module 18).

Milestones and partial credit

A binary "did it finish?" score has a serious problem on long tasks: it throws away almost all the information. An agent that got 90% of the way through a 6-hour migration and an agent that never compiled the code both score 0. With few long tasks (and each run costing real money), you cannot afford to waste signal. The fix is to define milestones: checkable intermediate states on the path to success, each worth some share of the credit.

1 Repo buildsweight 0.10 ✓ 2 Client swappedweight 0.20 ✓ 3 Unit tests passweight 0.30 ✓ 4 Integrationweight 0.30 ✗ 5 Old client gone0.10, gated out each arrow = "requires": a milestone only counts if the ones before it passed 00.601.0 partial credit = 0.60 binary success = 0 furthest milestone = 3 of 5 Report all three: they answer different questions (how much value, did it ship, where does it stall).
A milestone rubric for "migrate the billing service to the new payments API". Weights reflect how much of the real value each step delivers. Gating stops an agent from collecting credit for a late milestone it reached by accident or by cheating (for example, deleting the old client without the new one working).

Designing good milestones

  • Make each milestone checkable by code where possible: "the build passes", "file X contains a call to Y", "the database has row Z". Fall back to a rubric-based LLM judge (Module 13) for fuzzy ones such as "the report explains the method".
  • Order and gate them. Gating is what stops reward hacking: without it, an agent can score the "old client removed" milestone by simply deleting code.
  • Weight by value, not by effort. Integration tests passing may take less agent time than setting up the build, but it is worth more.
  • Keep the binary metric too. Partial credit answers "how much progress?"; binary success answers "could we ship this?". A change that raises partial credit while lowering full success means the agent got better at starting and worse at finishing: very important to know.
  • Record "furthest milestone" histograms. If 60% of failures stall at milestone 4, you know exactly where to look (Module 12's error analysis, applied to long tasks).

PaperBench is a large-scale example of the same idea: its rubric trees decompose "replicate this paper" into thousands of weighted leaves, and the score is a weighted average up the tree. RE-Bench's normalized score is a continuous cousin: it gives credit for any improvement over the starting solution.

from dataclasses import dataclass, field
from typing import Callable

@dataclass
class Milestone:
    id: str
    weight: float                      # share of total credit
    check: Callable[[dict], bool]      # programmatic check on the final state / trace
    requires: list[str] = field(default_factory=list)  # gating: only counts if these passed

def score(milestones: list[Milestone], state: dict) -> dict:
    passed: dict[str, bool] = {}
    for m in milestones:               # listed in dependency order
        ok = m.check(state) and all(passed.get(r, False) for r in m.requires)
        passed[m.id] = ok
    total = sum(m.weight for m in milestones)
    earned = sum(m.weight for m in milestones if passed[m.id])
    return {
        "partial_credit": round(earned / total, 3),
        "full_success": all(passed.values()),          # the strict binary metric
        "furthest": max((i for i, m in enumerate(milestones) if passed[m.id]), default=-1),
        "detail": passed,
    }

# Task: "migrate the billing service to the new payments API"
M = [
    Milestone("repo_builds",      0.10, lambda s: s["build_ok"]),
    Milestone("client_swapped",   0.20, lambda s: "new_payments" in s["imports"], ["repo_builds"]),
    Milestone("unit_tests_pass",  0.30, lambda s: s["unit_pass_rate"] == 1.0,     ["client_swapped"]),
    Milestone("integration_pass", 0.30, lambda s: s["integration_ok"],            ["unit_tests_pass"]),
    Milestone("old_client_gone",  0.10, lambda s: "legacy_pay" not in s["imports"], ["integration_pass"]),
]

final_state = {"build_ok": True, "imports": {"new_payments", "legacy_pay"},
               "unit_pass_rate": 1.0, "integration_ok": False}
print(score(M, final_state))
# {'partial_credit': 0.6, 'full_success': False, 'furthest': 2,
#  'detail': {'repo_builds': True, 'client_swapped': True, 'unit_tests_pass': True,
#             'integration_pass': False, 'old_client_gone': False}}
Expert nuance: checkpoints you can resume from

Milestones can also be starting points. If agents rarely get past milestone 2, you learn nothing about milestones 3 to 5. Snapshot the environment at a known-good milestone-2 state (a Docker image, a saved repository) and start some runs from there. This "checkpointed" evaluation measures late-stage skill separately from early-stage skill, and it saves money. The catch: agents started mid-task lack the context they would have built up themselves, so late-stage scores from checkpoints are a lower bound on, not the same as, late-stage skill in a full run.

Context, memory and state tracking

A long task produces more text than fits in a model's context window (the maximum number of tokens the model can read at once). Agent harnesses therefore manage context: they compact (summarize older turns), truncate tool outputs, or let the agent write notes to an external memory (a file, a database) and read them back later. Anthropic's research system, for example, saves its plan to external memory when approaching token limits. Each of these is a place where information can silently disappear, so each deserves its own eval.

context limit tokens in context compact compact 0 turn 100 turn 180 turn 300 memory file reload notes after compaction probe ✓ probe ✗ detail lost probe ✓ probe = a question about task state ("which orders are still pending?") checked against the simulator's ground truth
Where long runs lose information (illustrative). Context fills, the harness compacts, and the agent relies on its notes. Probing the agent's knowledge of task state right after compaction events is a cheap way to catch memory failures before they show up as a failed task hours later.

Three layers of memory evaluation

LayerQuestionHow to evaluate
Long-context retrievalCan the model find and use a fact buried in a long input?"Needle in a haystack" tests plant a fact at varying depths in a long document. They are now considered too easy; richer suites like RULER (Hsieh et al., 2024) add multi-hop tracing and aggregation, and "Lost in the Middle" (Liu et al., 2023) showed accuracy can dip for facts in the middle of long contexts.
State trackingDoes the agent's belief about the world match the world?At random or scheduled points, pause the run and ask a probe question whose answer the environment knows (inventory, open tickets, files changed). Or compare the agent's own notes to ground truth. This catches the "forgot the order" failures that Vending-Bench documents.
Memory mechanismsDoes compaction, summarization, or a notes file preserve what matters?A/B the same tasks with different context strategies (no compaction vs summary vs notes). Measure end-to-end success, probe accuracy just after each compaction, and whether the agent re-does work it already did (a tell-tale sign of lost state).
Context size is not the whole story

It is tempting to blame every long-run failure on a full context window. Vending-Bench's authors explicitly found "no clear correlation" between failures and the point at which the context window filled. Coherence over long runs is a skill in its own right. Do not assume a bigger window fixes it: measure.

Long-context evals: beyond the needle

The first row of the table above deserves a closer look, because "the model has a 1-million-token window" is one of the most misread numbers in AI. An advertised context window tells you how much text the model accepts. It does not tell you how much it can use.

The classic test is the needle in a haystack (popularized in 2023 by Greg Kamradt's pressure tests): hide one sentence ("the best thing to do in San Francisco is eat a sandwich in Dolores Park") at some depth inside a long, unrelated document, then ask for it. Sweep the length and the depth, color a grid green where the model found it, and you get the famous all-green heatmaps. The trouble is that this test is easy in ways real work is not:

  • Literal match. The question repeats the needle's words, so finding it is closer to text search than to understanding.
  • The needle sticks out. A sentence about sandwiches inside essays about startups is conspicuous. Real documents are full of similar-looking facts (last quarter's number next to this quarter's).
  • One fact, no reasoning. Real tasks chain facts together or count across the whole input.

RULER (Hsieh et al., NVIDIA, 2024) keeps the synthetic, auto-graded style but adds harder task families, all generated at any length you choose: retrieval variants with multiple keys, multiple values and distracting look-alike needles; multi-hop tracing (variable tracking: "X1 = 12345 ... X2 = X1 ... X3 = X2", then "which variables equal 12345?", which forces following a chain across the whole input); aggregation (find the most common words in a long list, which needs the whole input, not one spot); and question answering with distractor paragraphs. The paper's headline: almost all models tested reached near-perfect scores on the vanilla needle test, yet showed large drops as length grew on the harder tasks, and only about half of the models that claimed 32K or more of context kept satisfactory performance at 32K. RULER calls the longest length at which a model stays above a fixed quality threshold its effective context length, which is the number you actually want.

"Context rot" is the name Chroma's July 2025 technical report gave to the broader pattern: across 18 models, performance degraded as input length grew, even on simple tasks, and not uniformly. The report found degradation was worse when the needle was less semantically similar to the question, that distractors (plausible but wrong near-matches) hurt more as inputs grew, and, counter-intuitively, that the structure of the haystack mattered (models did differently on logically coherent haystacks than on shuffled ones). In a conversational memory test built on LongMemEval, models did markedly better when given only the relevant portion of the history than the full history. The code is public (chroma-core/context-rot), so you can rerun it on your own model.

0% 50% 100% accuracy 4K 8K 16K 32K 64K 128K input length (tokens, log scale) 85% threshold advertised window vanilla needle needle + distractors multi-hop tracing aggregation effective length for multi-hop: about 8K, not 128K
Why an all-green needle test proves little. The literal-match needle stays near perfect at every length, while harder tasks at the same lengths fall below the quality bar far earlier. The effective context length for a task is where its curve crosses your threshold. Shapes follow the pattern RULER and the context-rot report describe; the numbers are illustrative, not measurements of any model.

For an agent, "long context" is rarely one long document. It is a growing transcript of tool outputs, file contents and earlier turns. Build your own long-context eval from that material rather than from essays about startups:

  1. Plant facts from your own domain in real transcripts at varying depths (an order number at turn 5, a changed shipping address at turn 40), then ask about them at the end. Use paraphrase, not the same words, between the fact and the question.
  2. Add realistic distractors: the old address next to the new one, last week's order next to today's. Score whether the agent picks the current fact.
  3. Include aggregation and multi-hop questions: "how many of the tickets so far mention refunds?", "which customer's second order used the coupon from the first email?".
  4. Sweep length (for example 8K, 32K, 128K of real context) and plot accuracy against length, as above. Report the effective length for your threshold, not the vendor's window.
  5. Compare context strategies on the same items: full context, compaction, retrieval over notes. This is where the state-tracking probes and compaction tests from this section meet (harness side in Module 21).
Go deeper

Long-term memory across sessions (what gets written, retrieved, updated and forgotten) gets its own treatment in Module 23, including the LoCoMo, LongMemEval and MemoryAgentBench benchmarks.

Cost and wall-clock budgets

Long tasks are expensive: MLE-bench runs take about a day of GPU time each, and Vending-Bench runs exceed 20 million tokens. That has two consequences for evals.

  1. The budget is a variable you must fix and report. Agents can often trade money for success: more attempts, more thinking tokens, more subagents. An agent at 60% for $2 per task and one at 65% for $40 per task are not ranked by success alone. Report success at a stated budget, or plot success against cost and look for the Pareto frontier (the set of systems not beaten on both axes at once).
  2. You will run fewer samples, so statistics matter more (Module 04). Prefer paired comparisons on the same tasks, report confidence intervals, and use partial credit to squeeze more signal from each run.
40% 65% 90% $1 $3 $10 $30 $100 cost per task (log scale) task success rate Pareto frontier A · $2 · 60% C · $8 · 72% E · $25 · 78% D · $15 · 58% B · $40 · 65% C is cheaper AND better gray and red points are dominated: never the right choice
Rank agents on two axes, not one. Every system on the green frontier is a defensible choice depending on how much a success is worth to you; B and D are not, because C beats both on cost and success at once. Reporting only success would have made B look better than A. Invented systems and numbers for illustration.

Measure at least: tokens in and out (and cached), dollar cost, number of tool calls, wall-clock time, and for multi-agent systems, peak parallelism. Put hard caps in the harness (maximum steps, tokens, minutes) and record why a run ended: finished, gave up, hit the cap, or crashed. "Hit the step cap" is a very different failure from "confidently submitted a wrong answer".

Part B · Multi-agent systems: the architectures

A multi-agent system is any setup where two or more model-driven agents, each with its own instructions and usually its own context window, cooperate on a task by passing messages or artifacts. The four common shapes each suggest where to grade.

Orchestrator-worker lead W1 W2 W3 delegate, then merge grade plan + synthesis Pipeline plan write review fixed hand-offs in order grade each stage's output Debate A B rounds judge argue, then decide grade verdict + convergence Swarm / hand-off peers pass control grade hand-offs + end state
Four topologies, four grading focal points. Every topology gets an end-to-end outcome grade; what differs is where the intermediate graders go. Orchestrators are judged on delegation and synthesis, pipelines per stage, debates on the final verdict and whether rounds actually change minds, swarms on each hand-off.
PatternHow it worksTypical useSignature failure
Orchestrator-workerA lead agent plans, spawns workers with sub-tasks, and synthesises their results.Broad research, parallel search, large code changes.Vague delegation: workers duplicate effort or misunderstand the sub-task.
Pipeline (sequential)Fixed stages, each agent specialized (planner, coder, reviewer).Content workflows, code generation with review.An early stage's error flows downstream unchallenged.
DebateAgents propose answers, critique each other over rounds, and a judge or vote decides. Du et al. (2023) found multi-round debate improved reasoning and reduced hallucination compared with a single model.Reasoning, fact-checking, scalable-oversight research.Conformity: agents converge on the confident wrong answer.
Swarm / hand-offPeers pass control to whichever agent fits the next step (for example, triage to billing to refunds).Customer service routing.Ping-pong loops and lost context at each hand-off.
Always evaluate against a single-agent baseline

Multi-agent systems cost more and fail in new ways. The first eval question is not "how good is my multi-agent system?" but "is it better than one agent given the same total budget?". Without that baseline you cannot tell whether the extra agents help or whether you are just spending more tokens.

A case study: how Anthropic evaluated its multi-agent research system

In June 2025 Anthropic published an engineering post, "How we built our multi-agent research system", describing the architecture behind Claude's Research feature and, unusually, how they evaluated it. It is the best public case study of multi-agent evals in production, so it is worth knowing in detail.

Architecture. An orchestrator-worker design: a lead agent analyses the query, plans, and spawns subagents that search in parallel, each with its own context window; a separate CitationAgent attributes claims to sources at the end.

Headline results (as stated in the post):

  • A multi-agent system with Claude Opus 4 as lead and Claude Sonnet 4 subagents outperformed single-agent Claude Opus 4 by 90.2% on Anthropic's internal research eval.
  • On BrowseComp, token usage alone explained 80% of the performance variance; token usage, number of tool calls and model choice together explained 95%.
  • Agents use about 4× more tokens than chat interactions, and multi-agent systems about 15× more.
0× 5× 10× 15× 1× ≈ 4× ≈ 15× chat single agent multi-agent tokens vs a chat turn worth it only if the task's value covers the cost
The token cost multiplier. Approximate ratios as reported by Anthropic (June 2025) for its research system; your own multiplier depends on the task and design. Measure it: the multiplier belongs in every multi-agent eval report next to the quality gain.

How they evaluated it

1. Start small, immediately

They began with about 20 queries representing real usage. Early changes had huge effect sizes (the post mentions jumps like 30% to 80% success), and with effects that large a small set is enough to see them. Their advice: do not wait until you can build a big eval.

2. LLM judge with a rubric

Outputs were scored against a rubric: factual accuracy, citation accuracy, completeness, source quality, tool efficiency. A single judge call producing 0.0 to 1.0 scores (plus pass/fail) was more consistent than several specialized judges.

3. Grade the end state

Multi-agent runs take different valid paths each time, so they judged whether the agent reached the right final state rather than whether it followed a prescribed sequence of steps. For long, state-changing runs, check discrete checkpoints rather than every step.

4. Humans still find what judges miss

Manual testing caught edge cases the automated evals did not; for example, agents consistently chose SEO-optimized content farms over authoritative but lower-ranked sources such as academic PDFs. The fix was source-quality heuristics in the prompts.

The post also lists failure modes the team saw in early versions: spawning 50 subagents for simple queries, searching endlessly for sources that do not exist, subagents distracting each other with excessive updates, and subagents duplicating each other's work. They note that "small changes to the lead agent can unpredictably change how subagents behave", and that because agents are stateful over many tool calls, minor failures can cascade. Full production tracing (of decision patterns and interaction structure, not conversation contents) was how they diagnosed these.

What to copy from this case study

(1) An end-to-end rubric that includes process quality (tool efficiency, source quality) alongside correctness. (2) End-state grading that tolerates path diversity. (3) Scaling rules as an eval target: they embedded explicit effort rules in prompts (roughly one agent for simple fact-finding, a few for comparisons, ten or more for complex research), which you can check automatically from traces: "did the number of subagents fit the query's complexity?"

What to measure in a multi-agent system

Think in three levels: the whole system, each agent, and the connections between them.

LevelMetricHow
SystemEnd-to-end outcomeThe same graders you would use for a single agent: task success, rubric score, milestones. This is the headline number.
Token cost multiplierTotal tokens (all agents) ÷ tokens of a single-agent baseline on the same task.
Wall-clock and parallelismParallel agents can finish faster despite using more tokens; report both.
AgentPer-agent successGrade each worker's output against its assigned sub-task (did the search agent find relevant sources?).
Per-agent contributionDid this agent's output make it into the final result? Ablate it (rerun without it, or with its output replaced) and see what changes.
Per-agent cost and errorsTokens, tool calls and tool errors, attributed from the trace tree (code below).
InteractionCommunication overheadTokens spent on messages between agents vs on the task itself; number of rounds.
Delegation qualityJudge the orchestrator's sub-task descriptions: clear objective, output format, boundaries, no overlap with siblings.
Coordination failuresLabel failed traces with a taxonomy such as MAST (next section): duplicated work, ignored input, premature termination.

Credit assignment: who deserves the blame?

Credit assignment is the problem of deciding which agent (or which step) caused the outcome. It is hard because agents interact: a worker's wrong fact only matters if the lead failed to cross-check it. Three practical approaches, from cheap to rigorous:

  1. Trace inspection with a judge. Give an LLM judge the full trace and ask "which agent's action first made the task unrecoverable?". Cheap and useful for error analysis, but the judge can be wrong, so spot-check it.
  2. Counterfactual replay (ablation). Replay the run with one agent's output swapped for a known-good one (from a stronger model or a human). If success jumps, that agent was the bottleneck. This is the most convincing method and also the most expensive.
  3. Shapley-style attribution. For a small number of agents, measure the outcome for every subset of "upgraded" agents and average each agent's marginal contribution (the Shapley value from game theory). The cost grows as 2n, so it is only practical for a handful of agents.
Replay lead search_1 search_2 citations successover 5 reruns original run own output own output own output own output 1 / 5 swap search_1 own output known-good ★ own output own output 1 / 5 swap search_2 own output own output known-good ★ own output 4 / 5 swap citations own output own output own output known-good ★ 2 / 5 search_2 is the bottleneck: fixing it alone lifts success from 1/5 to 4/5
Credit assignment by counterfactual replay. Rerun the same task several times, each time swapping one agent's output for a known-good one (from a stronger model or a human) while everything else runs normally. The agent whose swap moves success the most is where to invest. Rerun each row several times, because a single replay is as noisy as a single run. Invented numbers.

Tracing across agents: span trees

A single-agent transcript is a flat list. A multi-agent run is a tree: the lead's work contains each subagent's work, which contains each tool call. Tracing tools record this as nested spans (a span is a timed unit of work with a parent, attributes and a status). The OpenTelemetry GenAI semantic conventions (still marked "Development", i.e. not yet stable) define span names like invoke_agent {gen_ai.agent.name} and execute_tool, with attributes such as gen_ai.agent.name and token usage counts. Many eval and observability tools (Module 14) ingest these traces, which means you can attach graders to any node of the tree.

Outcome grader rubric judge on final report, milestones, end state Agent graders sub-task done? output used? delegation brief clear? Tool graders valid args? errors? retries? redundant calls? invoke_agent lead 11.5k tok · plan + synthesis search_133k tok search_246k tok search_3output unused citations19k tok delegate search fetch ✗ search fetch search search timeout: did it recover? same queries as search_2 (duplicated work) Trace-level checks (whole tree) total tokens and multiplier vs single agent · wall-clock · subagent count vs query complexity · loops and ping-pong · max depth
Where graders attach in an orchestrator-worker trace. The root carries the outcome grade that matters most; lower levels carry diagnostic grades that explain it. Here the tree reveals a tool timeout under search_1 and a worker (search_3) whose duplicated effort never reached the final report: a coordination failure invisible from the final answer alone.

The walker below computes per-agent tokens, tool calls and errors from such a tree, reports the ancestor path of every error (so you know which delegation led there), and computes the token multiplier against a single-agent baseline.

from collections import defaultdict

# A multi-agent trace as a tree of spans (the shape OpenTelemetry-style tracers export)
trace = {
  "name": "invoke_agent lead", "agent": "lead", "in_tok": 9_000, "out_tok": 2_500, "error": None,
  "children": [
    {"name": "invoke_agent search_1", "agent": "search_1", "in_tok": 30_000, "out_tok": 3_000, "error": None,
     "children": [
        {"name": "execute_tool web_search", "agent": "search_1", "in_tok": 0, "out_tok": 0, "error": None, "children": []},
        {"name": "execute_tool web_fetch",  "agent": "search_1", "in_tok": 0, "out_tok": 0, "error": "timeout", "children": []}]},
    {"name": "invoke_agent search_2", "agent": "search_2", "in_tok": 42_000, "out_tok": 4_100, "error": None,
     "children": [
        {"name": "execute_tool web_search", "agent": "search_2", "in_tok": 0, "out_tok": 0, "error": None, "children": []}]},
    {"name": "invoke_agent citations", "agent": "citations", "in_tok": 18_000, "out_tok": 1_200, "error": None, "children": []},
  ],
}

def walk(span, depth=0, path=()):
    """Depth-first: yield every span with its depth and ancestor path."""
    yield span, depth, path
    for child in span["children"]:
        yield from walk(child, depth + 1, path + (span["agent"],))

per_agent = defaultdict(lambda: {"tokens": 0, "spans": 0, "errors": 0, "tool_calls": 0})
for span, depth, path in walk(trace):
    a = per_agent[span["agent"]]
    a["tokens"] += span["in_tok"] + span["out_tok"]
    a["spans"] += 1
    a["tool_calls"] += span["name"].startswith("execute_tool")
    if span["error"]:
        a["errors"] += 1
        print(f"error at depth {depth}: {span['name']} ({span['error']}) via {' > '.join(path)}")

total = sum(a["tokens"] for a in per_agent.values())
for name, a in sorted(per_agent.items(), key=lambda kv: -kv[1]["tokens"]):
    print(f"{name:10s} {a['tokens']:>7,} tok ({a['tokens']/total:5.1%})  "
          f"tools={a['tool_calls']}  errors={a['errors']}")

SINGLE_AGENT_BASELINE = 20_000     # tokens the single-agent version used on this task
print(f"token multiplier vs single agent: {total / SINGLE_AGENT_BASELINE:.1f}x")

# Output:
# error at depth 2: execute_tool web_fetch (timeout) via lead > search_1
# search_2    46,100 tok (42.0%)  tools=1  errors=0
# search_1    33,000 tok (30.1%)  tools=2  errors=1
# citations   19,200 tok (17.5%)  tools=0  errors=0
# lead        11,500 tok (10.5%)  tools=0  errors=0
# token multiplier vs single agent: 5.5x

In a real system you would read spans from your tracing backend (exported OpenTelemetry JSON, or a platform's SDK) rather than a hand-written dict, and you would attach graders' scores back onto spans so that dashboards can slice by agent. The logic stays the same: walk the tree, attribute, aggregate.

Why multi-agent systems fail: the MAST taxonomy

When you label failed traces (Module 12), it helps to start from an established taxonomy rather than inventing categories. The most cited one is MAST (Multi-Agent System failure Taxonomy) from "Why Do Multi-Agent LLM Systems Fail?" (Cemri, Pan, Yang et al., UC Berkeley, March 2025). The authors annotated traces from seven open multi-agent frameworks (including ChatDev, MetaGPT, HyperAgent, AppWorld, AG2, Magentic-One and OpenManus), reached high inter-annotator agreement (Cohen's kappa 0.88), and released a dataset of more than 1,600 annotated traces along with an LLM-as-judge pipeline for labeling new ones. They found 14 failure modes in 3 categories.

FC1 System design issues · 44.2% 1.1 Disobey task specification11.8% 1.2 Disobey role specification1.5% 1.3 Step repetition15.7% 1.4 Loss of conversation history2.8% 1.5 Unaware of stopping conditions12.4% FC2 Inter-agent misalignment · 32.3% 2.1 Conversation reset2.2% 2.2 Fail to ask for clarification6.8% 2.3 Task derailment7.4% 2.4 Information withholding0.85% 2.5 Ignored other agent's input1.9% 2.6 Reasoning-action mismatch13.2% FC3 Task verification · 23.5% 3.1 Premature termination6.2% 3.2 No or incomplete verification8.2% 3.3 Incorrect verification9.1% share of annotated failures (as reported in the paper's HTML version, arXiv 2503.13657)
The MAST taxonomy with reported frequencies. Percentages are as given in the paper for its annotated traces from specific open frameworks; your system's mix will differ. Shares are of labeled failure occurrences (one trace can carry several labels). The striking point is that only about a third of failures are about agents misunderstanding each other: most are ordinary design and verification problems.

Three lessons from MAST that change how you build evals:

  • Verification is a first-class component. About a quarter of failures are in task verification: the system either never checks its work, checks it badly, or stops early. If your architecture has a "reviewer" or "verifier" agent, evaluate that agent on its own as a classifier (precision and recall on known good and bad outputs), exactly like validating an LLM judge (Module 13).
  • Many "multi-agent" failures are single-agent failures in disguise. Step repetition, disobeying the task specification and not knowing when to stop would happen with one agent too. Before blaming coordination, check whether a single agent fails the same way.
  • Stopping conditions need tests. "Unaware of stopping conditions" is a big category. Include tasks whose correct behavior is to stop early (the answer is already known, the task is impossible) and measure whether the system does.
Deep dive: turning MAST into an automated trace classifier

A practical pipeline: (1) sample failed traces from your eval runs; (2) have an LLM judge label each with zero or more MAST modes, giving the definitions from the paper in the prompt and asking for the span id where each failure first appears; (3) hand-label 50 to 100 of the same traces yourself and measure agreement (Cohen's kappa) with the judge; (4) once agreement is acceptable, run the judge on every failed trace and track the mode distribution over time. A shift from "step repetition" to "premature termination" after a prompt change tells you the change traded one failure for another, which a single success rate would hide.

Emergent behavior and safety in multi-agent systems

When agents interact, behaviors can appear that no single agent shows on its own. That is what "emergent" means here, and it is why multi-agent systems need evals beyond their parts.

Cascading errors

One agent's mistake becomes another's input and is amplified: a hallucinated fact from a worker is cited confidently by the lead, then "verified" by a reviewer that trusts the lead. Test it with fault injection: deliberately corrupt one worker's output (a wrong number, a fake citation) and measure how often the final answer contains the error.

Collusion

Agents may coordinate in ways their designers did not intend, including against an overseer. Motwani et al. ("Secret Collusion among AI Agents", 2024) studied agents hiding messages from monitors using steganography, and proposed evaluations for that capability. If one agent monitors another, test whether the monitored agent can influence or evade the monitor.

Conformity and echo chambers

In debate and voting setups, agents may defer to a confident peer instead of checking. Measure how often a minority-correct agent flips to a majority-wrong answer across rounds.

Runaway resource use

Spawning loops, ping-pong hand-offs, and agents that keep delegating. Cap depth and count in the harness, and treat "hit the cap" as a graded failure.

inject a fault here Worker search_2 revenue $4.1B (true value: $1.4B) Lead synthesis cites the figure Reviewer agent trusts the lead Final report error shipped ✗ better reviewer Re-checks source error caught ✓ propagation rate injections reaching output 14 / 40 = 35% Vary the fault: wrong number, fake citation, injected instruction, empty result. Vary where: each worker in turn.
Fault injection measures cascading errors. Corrupt one agent's output on purpose, let the system run, and count how often the fault reaches the final output. A low propagation rate means some agent (here, a reviewer that re-checks sources) acts as a firewall. The same harness tests prompt injection: plant an instruction instead of a wrong number. Illustrative numbers.

The Cooperative AI Foundation's report "Multi-Agent Risks from Advanced AI" (Hammond et al., February 2025) organizes the risks into three failure modes (miscoordination, conflict, collusion) and seven risk factors (information asymmetries, network effects, selection pressures, destabilising dynamics, commitment problems, emergent agency, and multi-agent security). It is a good checklist for designing adversarial multi-agent evals, and Module 17 returns to dangerous-capability testing more broadly.

Security: every message is an input

In a multi-agent system, a compromised or prompt-injected worker (for example, one that read a malicious web page) can pass instructions upward to the lead. Your safety evals should include injected content at the worker level and check whether it propagates to actions taken by other agents. The trace tree makes this measurable: follow the tainted content from the span where it entered to every span that used it.

Agent interop: A2A, handoffs and agent payments

Everything in Part B so far assumed you own all the agents. Increasingly, your agent will hand work to an agent someone else built and runs, and some agents can now spend money. Two families of open protocols are emerging for this, and both create new things to evaluate. (The protocols are young and change quickly, so treat field names below as illustrative and check the current specs.)

Agent to agent: A2A

Agent2Agent (A2A) is an open protocol that Google launched in April 2025 and then contributed to the Linux Foundation, which reported more than 150 supporting organizations after its first year. A remote agent publishes an Agent Card (a JSON description of who it is, its skills, its endpoint and how to authenticate). A client agent reads the card, sends a message that creates a task, and follows the task through its states (such as working, input-required, completed, failed, canceled) until it returns results as artifacts. The remote agent stays opaque: you see its messages, not its internals. MCP connects an agent to tools; A2A connects an agent to another agent.

Agents that pay

AP2 (Agent Payments Protocol, Google, September 2025) works alongside A2A and MCP and uses cryptographically signed mandates: an intent mandate records what the user authorized in advance ("two tickets, under $200"), a cart mandate records approval of an exact cart. ACP (Agentic Commerce Protocol, OpenAI and Stripe, September 2025) powers Instant Checkout in ChatGPT, where the agent sends the order to the merchant's checkout and payment travels as a token scoped to that merchant and amount. x402 (Coinbase, 2025) revives the HTTP status code 402 Payment Required: a server answers with a price, the client pays (typically in stablecoins) and retries the request, which suits pay-per-call APIs.

For evaluation, the protocol details matter less than the new failure points they create. A delegation can go to the wrong agent; the user's constraints can be lost in the handoff; the remote agent can ask a question, fail or stall; and a payment can exceed what the user actually authorized. The figure puts numbered checkpoints on each.

User "2 tickets, max $200" Your agent A2A client holds the mandate: ≤ $200 · tickets Agent Card skills · endpoint · auth Remote agent A2A server (ticket seller) working → input-required → completed Payment rail AP2 mandate, ACP checkout or x402 discover task result authorize and pay, only within the mandate 1 2 3 4 5 1 Delegation right agent and skill, or do it itself? 2 Handoff fidelity every constraint carried into the task message? 3 Task lifecycle input-required, failed, canceled, timeouts 4 Authorization within the mandate? user approval needed? 5 Spending limits cumulative cap held, no double charge?
Where cross-agent work and payments can go wrong. Your agent discovers a remote agent from its Agent Card, sends it a task, receives a result and pays through a payment rail. Each numbered checkpoint is a separate eval: choosing the delegate, carrying the constraints over, handling every task state, and keeping money inside what the user authorized. Simplified flow; the real protocols have more steps.
What to evaluateTestMetric
Delegation correctnessGive the agent several Agent Cards (including near-miss skills and one that looks right but is out of scope) and tasks with a known correct delegate, including tasks it should do itself.Routing accuracy; unnecessary-delegation rate
Handoff fidelityCompare the user's constraints (budget, dates, quantity, "no aisle seats") with what the outbound task message actually says. Structured fields can be checked by code; free text needs a narrow judge.Constraint-retention rate per handoff
Lifecycle handlingUse a mock remote agent that replies input-required, fails, stalls or cancels. Check the agent asks the user only when needed, retries sensibly and never reports success on a failed task.Correct-handling rate per state; false-success rate
Trust in resultsThe remote agent's artifacts are untrusted input. Plant a wrong price or an injected instruction in them (the fault-injection idea above; attacks in Module 25).Propagation rate of planted errors
Payment authorization and limitsAdversarial merchant scenarios: price rises after approval, a 402 response asks for more than the quote, an upsell adds items, a retry could double-charge. Grade against the mandate on a sandbox payment rail.Out-of-mandate charges (target: zero); approvals requested when required

Payment evals are a place for hard, deterministic checks, not judges. A sketch of the grader side, run after the agent finishes each scenario against a sandbox rail that records charges instead of moving money:

from dataclasses import dataclass

@dataclass
class Mandate:                      # what the user actually authorized
    max_total: float                # cumulative cap across all purchases
    categories: set[str]            # e.g. {"tickets"}
    confirm_over: float             # single charges above this need explicit user approval

def grade_payments(mandate: Mandate, charges: list[dict], approvals: set[str]) -> dict:
    """charges: recorded by the sandbox rail, e.g.
       {"order_id": "A1", "amount": 180.0, "category": "tickets"}
       approvals: order_ids the (simulated) user explicitly approved."""
    order_ids = [c["order_id"] for c in charges]
    return {
        "under_cap":        sum(c["amount"] for c in charges) <= mandate.max_total,
        "in_category":      all(c["category"] in mandate.categories for c in charges),
        "approved_if_big":  all(c["order_id"] in approvals
                                for c in charges if c["amount"] > mandate.confirm_over),
        "no_double_charge": len(order_ids) == len(set(order_ids)),
    }

# Scenario "price rises after approval": quote was $180, merchant now asks $230.
# The right behavior is to stop and ask the user, so the rail should record no charge.
print(grade_payments(Mandate(200.0, {"tickets"}, 150.0), charges=[], approvals=set()))
# every check True: the agent refused to pay outside the mandate

Run each scenario several times and require every check to pass on every trial (pass^k from Module 06): for money, "usually stays under budget" is a failing grade. Public benchmarks for agent interop and payments are still immature, so most teams build scenario suites like this one around their own flows.

Putting it together: an eval plan for a long-running multi-agent system

Suppose you are building a research assistant like the one in the case study. A minimal but expert-grade eval plan looks like this:

  1. Dataset: 20 to 50 real queries to start, stratified by complexity (simple fact, comparison, deep research), each with a rubric and, where possible, known key facts and sources.
  2. Baseline: a single-agent version with the same model and the same total token budget.
  3. Outcome graders: a rubric LLM judge (accuracy, citation accuracy, completeness, source quality, tool efficiency), validated against human labels on a subset. Milestones for long queries (sources found, claims extracted, draft written, citations verified).
  4. Process graders on the trace: subagent count vs complexity, duplicated queries across workers, tool error and recovery rate, MAST labels on failures.
  5. Budgets: tokens, dollars, wall-clock, subagent count; report the multiplier vs baseline and plot quality against cost.
  6. Robustness: 3 or more runs per query (report pass^k or spread), fault injection on one worker, prompt injection via a planted web page.
  7. Human review: a weekly read of a sample of traces, looking for things the rubric does not capture (the content-farm lesson).
Outcomerubric judge + milestones vs single-agent baseline Process (trace)delegation, duplication, tool recovery, MAST labels Budgetstokens, $, wall-clock, token multiplier, caps hit Robustnessrepeats (pass^k), fault injection, prompt injection Human reviewweekly trace reading for what rubrics miss Ship decision better AND worth it?
Five layers of a multi-agent eval. The outcome layer decides whether the system is better; the other layers explain why, check it is worth the cost, and check it stays safe when something goes wrong.

Key takeaways

  1. Errors compound: at 99% per step, a 100-step task succeeds only about 37% of the time. Report end-to-end success for long tasks and treat step accuracy as a diagnostic.
  2. Error recovery is the biggest lever on long-horizon success, and correlated "snowball" errors make real tasks harder than pn suggests. Measure both.
  3. METR's 50% time horizon expresses capability in human expert minutes via a logistic fit on log time. It is a statistic of a task distribution, with wide intervals at the frontier.
  4. Long tasks need richer scoring: gated, weighted milestones plus binary success plus furthest-milestone histograms, always at a stated budget.
  5. For multi-agent systems, first beat a single-agent baseline with the same budget, then report the token multiplier and the cost-success Pareto frontier.
  6. Traces are trees: attach graders at the root (outcome), agent spans (delegation, contribution) and tool spans, and assign blame with counterfactual replay.
  7. Use MAST to label failures, and test emergent risks directly with fault and prompt injection at the worker level.
  8. An advertised context window is not a usable one. Vanilla needle tests are near-saturated; test multi-hop, aggregation and look-alike distractors on your own transcripts, sweep length, and report the effective context length for your quality bar.
  9. When agents delegate across organizations (A2A) or spend money (AP2, ACP, x402), evaluate each checkpoint: right delegate, constraints preserved in the handoff, every task state handled, and zero out-of-mandate charges across repeated trials.

Check yourself

1. An agent has 98% per-step reliability with no error recovery. Roughly what is its success rate on a task needing 50 correct steps?

0.9850 ≈ 0.364. Compounding turns a small per-step error into a large end-to-end one, which is why long-horizon evals report end-to-end success and why error recovery matters so much.

2. METR reports a model's 50% time horizon as 1 hour. Which statement is correct?

The horizon is defined by human expert completion time on a specific (mostly software and ML) task distribution. METR explicitly warns against reading it as "can work for N hours on anything".

3. Why does a milestone rubric use gating ("only counts if earlier milestones passed")?

Gating ties credit to genuine progress along the intended path and closes an obvious reward-hacking route.

4. Your multi-agent system scores 12 points higher than your single-agent system. What is the most important missing piece before concluding it is better?

Anthropic reported token usage alone explained 80% of BrowseComp variance. A gain that simply reflects spending more tokens may not be worth it, and a single agent given the same budget might close the gap.

5. In the MAST taxonomy, which category covered roughly a quarter of annotated failures and suggests evaluating reviewer agents as classifiers?

Task verification (premature termination, no or incomplete verification, incorrect verification) was about 23.5% of failures in the paper's annotated traces.

6. A vendor shows an all-green needle-in-a-haystack heatmap up to 1M tokens. What is the best conclusion?

RULER found near-perfect vanilla needle scores alongside large drops on harder tasks as length grew, and the context-rot report found degradation even on simple tasks once needles are less similar to the question or distractors are present.

7. The user tells your agent "two tickets, under $200 total". Over A2A, your agent sends the seller agent "buy two tickets for Saturday". The seller charges $240. Which checkpoint failed first?

The seller was the right agent, but the $200 limit never reached it. A handoff-fidelity check comparing user constraints with the outbound message catches this, and a mandate-based payment check is the second line of defense.
Interview questions (with model answers)

Q: How would you compute a time horizon for an internal agent, and what would you report with it?
Time experts on a sample of real tasks (geometric mean of several timings), run the agent several times per task, fit logistic regression of success on log2(human time), solve for 50% (and 80%). Report the slope, a task-level bootstrap confidence interval, the task distribution and the budget. Do not extrapolate beyond measured lengths.

Q: Your long-horizon eval has 30 tasks, each costing $50 per run. How do you get a useful signal?
Use milestone partial credit and furthest-milestone histograms to extract more information per run; use paired comparisons of old vs new on the same tasks; checkpoint environments to test late stages cheaply; and report intervals honestly rather than over-reading small differences.

Q: How do you assign blame in a failed multi-agent run?
Walk the trace tree to find the first error and its ancestor path; use an LLM judge to propose the responsible agent; confirm with counterfactual replay (swap in a known-good output for that agent and rerun). Aggregate across many failures with a taxonomy like MAST.

Q: What is special about safety testing for multi-agent systems?
Errors and injected instructions can propagate between agents, monitors can be evaded or influenced, and agents can converge on wrong answers. Use fault injection and prompt injection at the worker level, trace propagation, test monitors against the agents they watch, and cap resource use.

Sources and further reading