Python · cell 1
An agent is a language model that acts. It reads a situation, calls a tool or runs a command, looks at the result, and repeats until the job is done. Evaluating an agent means running it on test tasks inside a test environment, usually several times per task, and grading what it did. This section shows how to do that so that the number means what you think it means. It matters because agent scores now decide launches and back research claims, and they are easier to get wrong than any other score in this chapter.
Three published results show how an agent score can mislead. The first is about reliability. In June 2024 a team at the company Sierra released τ-bench, a test in which an agent serves simulated customers of an online store and of an airline (Yao et al. 2024). The agent reads a policy document, talks with a customer played by another language model, and calls tools that read and change a database. The best agent they tested was gpt-4o with function calling, meaning the model writes structured tool calls that the surrounding code executes. It completed 61.2% of the store tasks on a single try. Then the authors ran every task eight times, and fewer than 25% of the tasks were completed on all eight tries. A real customer meets your agent many times. Which of the two numbers belongs on the slide?
The second result is about grading. SWE-bench asks an agent to fix a real GitHub issue in a Python repository, and grades the fix by running tests the agent never sees (Jimenez et al. 2023). Aleithan et al. (2024) read every fix that one agent, the SWE-agent program driving GPT-4, had gotten right. In 32.67% of them the solution was already written in the issue or its comments. Another 31.08% passed only because the tests were too weak to notice a wrong fix. Without those tasks the agent's success rate fell from 12.47% to 3.97%, a drop of more than two thirds. The third result is the shortest. On τ-bench's airline tasks, an agent that does nothing at all passes 38% of them (Zhu et al. 2025).
None of these failures is bad luck in which tasks were drawn, the sampling error of §22.2. None is test data that leaked into training, the contamination of §22.3. §22.1 split the error of any evaluation into five parts, validity, sampling, leakage, grader, and environment. The SWE-bench audit and the do-nothing agent are failures of the last two. The grader accepted wrong fixes, and the benchmark was built so that an empty answer passes. The τ-bench gap is something new. A model answering one question has a single score, but an agent that is run many times has a reliability, and every run has a price. Does the agent succeed every time, or only on average? And what did each success cost?
This section builds an agent evaluation piece by piece. It starts with the words for the parts (tasks, trials, environments, graders), then shows how to grade an outcome and a path, and how to keep the environment from moving the score. Then it derives the two numbers every agent report needs and most get wrong, a reliability metric called and the trade-off between cost and accuracy. It ends with what each major agent benchmark measures and how each one breaks.
Stated precisely, an agent is a model in a loop. It observes an environment and chooses an action, such as a tool call, a shell command, or a click. It receives the result and repeats, until it decides to stop or runs out of budget. How to build such a loop is the subject of Chapter 24, from the agent loop and function calling to code agents and computer use. Here we need only the loop itself and the words for testing it.
Start with one test case. A customer of an online store asks the agent to cancel order W1 and refund 54.04 dollars. The store's database starts with W1 marked pending. Run the agent on this request three times. Each run leaves a full record of what the agent said and did, and leaves the database in some final state.
A grader looks at each run and returns pass or fail. Only the first run should pass. Every agent evaluation is many runs like these, and the box names their parts.
These terms follow Anthropic's engineering guide to agent evaluations (Anthropic 2026). The scaffold is the one people forget. When you evaluate "an agent", you evaluate a model and a scaffold together, under one budget, in one version of one environment.
Now the score itself. §22.1 treated an evaluation as an estimator, an average of grader scores over test items that stands in for the quality we care about. For agents the items are tasks, and each task is run several times. Say our cancellation task passed 1 of its 3 trials and a second task passed 3 of 3. The score is the average of the two tasks' success rates, .
In general, write the benchmark as tasks indexed by , and let be the probability that one trial of task succeeds. This probability belongs to the whole protocol, meaning the model, the scaffold, the tools, the environment version, the budget, and the grader. Change any of them and changes. The benchmark's single-trial success rate is the average . Run trials of task and count successes. The usual estimate is
In plain words, take each task's success rate over its trials, then average over tasks.
Everything that goes wrong in this section goes wrong in one of three places. The grader can disagree with the truth, so a trial "passes" though the customer was not helped. The environment can make measure something other than the agent's skill, for example through a sandbox that crashes or a task whose answer is visible. And the single number can be the wrong summary, because it hides how reliable the agent is from trial to trial and what each success cost.
Teams run agent evaluations for two purposes that pull in opposite directions, and they keep them apart.
The two are read differently. A capability eval is read through its mean and the interval around it. A regression eval is read through its failures, and it needs the reliability metric of this section, because "passed once" is not the same as "still works". §22.6 builds regression suites and release gates for your own product on top of what we derive here.
A grader can look at two things, the outcome and the transcript. Most agent benchmarks grade the outcome. The outcome is what the user cares about, and there are usually many valid ways to reach it. Four kinds of outcome grader are common.
State comparison needs a precise statement, because the obvious ways to code it are wrong. Think of the database as a set of records. Each record is a set of named fields with values, such as order W1 with status "pending" and refund 0. A task's goal is a patch, the list of fields the task must set and the values they must take. For the cancellation task the patch sets W1's status to "cancelled" and its refund to 54.04.
In plain words, the agent must make exactly the changes the task asks for, with exactly the right values, and no others. Two choices in the definition do the work. Comparing the whole final state with , rather than checking only the fields in the patch, catches side effects. Comparing exact values, rather than checking that something changed, catches wrong values.
Let's test both claims on a toy store with two pending orders and the task "cancel W1 and refund 54.04". We run four agents through three graders of increasing strictness. One agent does the task right, one does nothing, one only claims to have done it, and one also cancels W2. The first grader reads the agent's messages for a claim of success. The second checks only the fields the goal names. The third is the full-state grader of the box.
The grader that reads the agent's claim passes the agent that lied. The grader that checks only the goal's fields passes the agent that cancelled a second customer's order. Only the full-state grader passes exactly the correct agent.
The last line of output is the subtle one. Some tasks have the correct outcome "change nothing". An example is a request the policy forbids, such as changing a non-refundable ticket, where the agent must refuse. On such a task the do-nothing agent is right and should pass. That is not a bug in the grader. It becomes a flaw in the benchmark when such tasks are a large share of it, because then doing nothing earns a high score. Zhu et al. (2025) found that 38% of τ-bench's airline tasks and 6% of its retail tasks are of this kind. An agent that returns empty responses scores 38% on airline, above the 35.2% of the gpt-4o agent in the τ-bench paper.
In an interview, expect to be asked whether 40% on some agent benchmark is good. The first answer is a question back. Compared with what floor?
Implement grade_state(initial, final, goal, ignore=(), required_outputs=(), messages=()), the full-state grader of the box above.
goal is the patch, a dict from record id to the fields the task must set. A record id that is not in initial is a record the task must create, with exactly those fields.final is the database after the trial, or None if the trial crashed before the state could be read.ignore lists field names that are never compared, such as timestamps.required_outputs must appear in at least one of the agent's messages.Return True exactly when the final state equals the initial state with the goal applied (on every record and every field not ignored) and every required output was said. Do not modify the inputs.
An outcome grader cannot see how the outcome was reached, and sometimes the path is the point. τ-bench's authors note that a reward of 1 is necessary but not sufficient for a good episode. An agent can issue the right refund without first getting the customer's explicit confirmation, which the policy requires, and the database will look exactly right. Safety rules are the same. Take "never delete a production table". An agent that deletes the table and then restores it from a backup leaves a final state that looks untouched, so only the transcript shows the violation.
Trajectory grading checks the transcript against rules. The cleanest form has three parts, the actions the task requires, an order among them, and actions that are forbidden. Here is a small case. To cancel an order, the agent must verify the customer's identity and look up the order, in either order, and only then cancel. Writing " before " as a pair, the rules are (verify, cancel) and (look up, cancel). Pairs like these define a partial order. It fixes some orderings and leaves the rest free, so "verify, look up, cancel" and "look up, verify, cancel" both pass while "cancel, verify, look up" fails.
Partial credit comes from the same rules. AgentBoard (Ma et al. 2024) defined a progress rate, the fraction of required subgoals the agent reached. An agent that verifies and finds the order but fails to cancel then scores above one that fails at the first step. Partial credit is what lets a capability eval show progress before agents can finish whole tasks.
The third kind of grader reads the transcript with a language model and scores it against a rubric, such as "the agent explained when the refund will arrive" or "the agent stayed within policy". Everything §22.4 says about model judges holds here. Their verdicts carry biases toward position, length, and their own outputs, and they must be checked against human labels before they are trusted. Two things are new for agents. Agent transcripts are long, so a judge can miss something buried in them. And the judge can itself be an agent that opens files and inspects the workspace. Zhuge et al. (2024) built such a judge for 55 AI development tasks with 365 requirements, arranged so that some requirements depend on others. They found it far more reliable than a judge that only reads, and as reliable as their human evaluation baseline.
Anthropic's guide adds a warning from practice (Anthropic 2026). Graders that demand a specific sequence of tool calls are brittle, because capable agents find valid paths the designer did not foresee. Grade what the agent produced, and keep path checks for what must or must not happen along the way. Exercise 22.5b implements those checks.
Implement grade_trajectory(actions, required, order=(), forbidden=()), a trajectory grader with required actions, an order among them, and forbidden actions.
actions is the trajectory, a list of action names in the order they happened.required lists the actions the task needs.order is a list of pairs (before, after) over required actions.forbidden lists actions that must never happen.A required action is done in order if it occurs and, at its first occurrence, every prerequisite named in order was already done in order. The definition is recursive, and a later repeat does not undo an early violation. Return (valid, progress). Here progress is the fraction of required actions done in order (1.0 if nothing is required), and valid is True exactly when progress is 1.0 and no forbidden action occurs anywhere in the trajectory.
Most real tasks combine graders. An outcome check decides pass or fail, path rules enforce policy and safety, and a rubric judge scores the quality of the conversation. The table compares them.
| grader | looks at | strengths | weaknesses | used by |
|---|---|---|---|---|
| hidden tests | outcome (code) | objective, cheap, reproducible | weak tests pass wrong fixes, narrow tests fail right ones | SWE-bench, Terminal-Bench |
| state comparison | outcome (database, files) | objective, catches side effects | blind to how the state was reached, rewards doing nothing on refusal tasks | τ-bench, WebArena, OSWorld |
| answer match | final answer | trivial to run | brittle to formatting, answers can be looked up | GAIA, BrowseComp |
| path rules | transcript | enforces policy and safety, gives partial credit | brittle if over-specified, needs the rules written out | AgentBoard, policy checks |
| model judge | transcript and outputs | handles open-ended quality | biased and noisy (§22.4), long transcripts | rubric graders, agent judges |
| human review | everything | the reference for the others | slow, expensive, inconsistent at scale | calibration samples |
A score belongs to the environment as much as to the agent. So the environment must be the same for every trial and every agent, and it must not leak the answer. The table lists what has gone wrong in practice, sorted by which way it pushes the score.
| bug | effect on the score | documented case |
|---|---|---|
| the solution is in the task text | inflates | 32.67% of SWE-Agent with GPT-4's successful SWE-bench patches (Aleithan et al. 2024) |
| tests too weak to reject a wrong fix | inflates | 31.08% of the same patches |
| doing nothing passes | inflates | 38% of τ-bench airline (Zhu et al. 2025) |
| a substring check passes an agent that lists every candidate answer | inflates | 2% of τ-bench airline tasks, so dumping the database scores 40% there (Zhu et al. 2025) |
| state shared between trials | inflates | an agent read the git history left by earlier trials (Anthropic 2026) |
| the answer is on the internet | inflates | agents found benchmarks on Hugging Face instead of solving them (Kapoor et al. 2025) |
| tests or task descriptions so flawed that correct fixes fail | deflates | 59.4% of 138 audited SWE-bench Verified tasks (OpenAI 2026) |
| rigid answer matching | deflates | CORE-Bench rejected "96.12" against "96.124991" (Anthropic 2026) |
| the live website changed | deflates | broken page selectors, a 28-point underestimate on OSWorld's Chrome tasks (Zhu et al. 2025) |
| sandbox crashes and resource limits | deflates | memory exhaustion that fails several trials at once (Anthropic 2026) |
The defenses are engineering, and they are as much a part of the benchmark as its tasks.
Some trials die for reasons that have nothing to do with the agent. A container fails to start, the tool server times out, or a rate limit runs out. Say a task has and 5% of trials crash this way. If a crash is scored as a failure, the task's measured rate is . The agent lost 3 points it did not deserve to lose.
The fix is to rerun crashed trials, and only crashed trials. With one rerun, a trial succeeds if the first attempt runs and succeeds, or if it crashes and the rerun runs and succeeds. That has probability , within 0.15 points of the truth.
The tempting variant is to rerun every failed trial "in case it was a flake". That measures something else. A task now counts as solved if either of two attempts succeeds, which is the agent's pass@2, the chance that at least one of two tries succeeds. In the example it gives , 21 points too high. The box states all three cases in general.
Proof. With crashes scored as failures, a trial succeeds when it runs and the agent succeeds, with probability . With up to reruns of crashes, the trial succeeds when, for some from 0 to , the first attempts crash and attempt runs and succeeds. Summing over gives . Rerunning every failure turns a task into two independent attempts that each succeed with probability , and the task counts as solved unless both fail. Average each over tasks.
So the harness must tell a crash from a failure, which is why good harnesses log infrastructure errors separately from agent errors. An interviewer who asks how you handle a flaky sandbox wants to hear exactly this. Rerun crashes, never failures, and report the crash rate. The cell checks all three formulas on 200,000 simulated tasks whose difficulties differ.
A 5% crash rate costs 3 points. Rerunning only the crashes recovers nearly all of them. Rerunning every failure adds 14 points that the agent did not earn on a single attempt. That is fewer than the 21 points of the one-task example, because these simulated tasks differ in difficulty. A second try helps little on a task the agent almost never solves, and not at all on one it always solves. That effect of spread across tasks returns in the reliability part below.
A standard error says how far a score would move if the benchmark's tasks were drawn again. The usual formula, the spread of the task scores divided by , assumes the tasks are independent. Real agent tasks come from the same repository, the same website, or the same template, and tasks in such a cluster tend to succeed or fail together. So they carry less information than the same number of independent tasks.
A tiny case shows how much less. Take four tasks, three from one repository and one from another. If each repository is either easy or hard for the agent as a whole, the four tasks are really two pieces of evidence, and the first piece counts three times. In a sense made precise below, these four tasks are worth 1.6 independent repositories, closer to one than to two.
The fix is the clustered standard error of §0.11, which §14.7 applied to questions that share a reading passage. It adds up the deviations from the mean within each cluster before squaring them. For task scores with mean , grouped into clusters indexed by ,
In plain words, deviations in one cluster that share a sign add up instead of cancelling, and the error bar grows to match. The factor is a small-sample correction.
Agent benchmarks are extreme cases. Of SWE-bench Verified's 500 tasks, 231 come from Django and 75 from SymPy, and the other ten repositories share the remaining 194. How much information about codebases in general is left? A simple model answers it. Suppose each repository has its own difficulty shift , drawn independently with variance and shared by all of its tasks.
Proof. The are independent, so the variance of the sum is the sum of the variances, . A mean of independent effects has variance , and matching the two gives .
For the four-task case, . For SWE-bench Verified, and .
The cell simulates this. Each repository gets a random difficulty with a standard deviation of 0.8 on the log-odds scale. That is the scale inside a logistic function, where a shift of 0.8 moves a task that succeeds 80% of the time to about 64% or 90%. Each task also gets its own random difficulty, with a standard deviation of 1.0, around a base log-odds of 1.4, so the mean score is about 75%. Each of 2,000 draws recomputes the score and both standard errors.
Under this model the standard error that assumes independence says 1.9 points, the clustered one about 4.2, and the true spread of the score over fresh draws of repository effects is about 6.4. The clustered estimate is closer but still low. A clustered standard error computed from only twelve clusters, one of them nearly half the data, is itself biased downward.
Which error bar is right depends on the claim, the question of §22.2. For "this agent on these twelve repositories", the repository effects are fixed and the independent-tasks error is the right one. For "this agent on Python repositories in general", the honest error bar is several times wider, and no number of extra Django tasks will narrow it. Interviewers like this point because it turns a vague "the benchmark is biased" into a number.
Now back to the τ-bench gap from the opening, 61.2% on one try against under 25% on all eight. A deployed agent meets the same kind of task again and again. A customer who is helped on Monday and harmed on Tuesday does not average the two. Say an agent solves some task 90% of the time and a customer brings it that task eight times. If the tries are independent, the customer is helped every time with probability . A 90% agent fails this customer more often than not.
The metric that captures this asks for every try to succeed. For one task it is the success probability raised to the number of tries, and for a benchmark it is the average of that over tasks.
Compare it with pass@ from §18.2, the probability that at least one of trials succeeds, for one task. For the 90% task, pass@ is , essentially 1, while is 0.43. Both metrics equal at . As grows, pass@ rises toward the fraction of tasks the agent can ever solve, and falls toward the fraction it always solves.
They answer different product questions. pass@ is the right number when something at deployment can pick the success out of attempts, such as unit tests for a coding agent. is the right number when every attempt reaches a user and every failure costs something, such as a support agent changing a real account. Which of the two you would report for a given product is one of the most common agent questions in interviews.
We never know . We run trials of a task and see successes. The obvious estimate, , is biased. The fix is the counting argument that §18.2 used for pass@, where the estimate is the fraction of groups of trials that contain a success. Here, instead of raising the observed rate to a power, count the fraction of groups of trials that are all successes. With 3 successes in 4 trials and , there are 6 pairs of trials, 3 of them both successes, so the estimate is rather than .
Proof. Choose a set of of the trials uniformly at random, independently of their outcomes. Given the outcomes, the probability that every trial in succeeded is the number of -subsets of the successes over the number of -subsets of all trials, . Taking expectations over the outcomes, by the law of total probability,
The trials are i.i.d., independent and identically distributed. Because is chosen without looking at the outcomes, the trials in are themselves i.i.d. trials, and they all succeed with probability .
Writing out the binomial coefficients gives the product form, . The product never forms a large number, so it is safe for any . The estimator needs . With it is the plain indicator "all trials passed", which is unbiased but as noisy as a single coin flip. With it averages that indicator over all -subsets, which can only lower the variance.
Which way is the plug-in biased? Jensen's inequality says that for a convex function (one that curves upward), the average of the function is at least the function of the average. The function is convex on , so , with equality only for or . The plug-in overstates reliability. That is the opposite direction from pass@, whose plug-in §18.2 showed to be biased low. The two plug-ins err in opposite directions, so no rule of thumb corrects both. The safe habit is the unbiased estimator, and an interviewer who asks for it will usually ask for the direction of the plug-in's bias next.
Implement pass_hat_k(n, c, k), the unbiased estimate for one task with c successes in n trials, returned as a float. Compute it as the product , so that it stays accurate for n in the hundreds of thousands. Return exactly 0.0 when c < k, and raise ValueError when k > n or k < 1.
Then implement benchmark_pass_hat_k(trials, k). Here trials is a list with one 0/1 array per task, and tasks may have different numbers of trials. Return the mean of the per-task estimates, and raise ValueError if any task has fewer than k trials.
A tiny case shows what the τ-bench gap is telling us. Two benchmarks each have two tasks and the same mean success rate of 0.5.
Back to τ-bench. If every retail task had the same success probability 0.612, eight trials would all succeed with probability . The paper reports a below 25% but near it, about ten times higher. The gap is not noise. It is information about how difficulty is spread over the tasks, as in benchmark B. That spread is called heterogeneity, and it always pushes the two metrics apart. In words, spread across tasks keeps above what the mean alone predicts, and keeps pass@ below it.
Proof. Let be the success probability of a task chosen uniformly at random, so and . The function is convex on , strictly for , so Jensen's inequality gives , with equality exactly when is constant. Since , , so , with equality exactly when . For pass@, is also convex, so , and subtracting from 1 reverses the inequality.
In plain words, a benchmark whose tasks are each nearly always or nearly never solved keeps its near , because the easy tasks keep succeeding. It gains little pass@ from retries, because the hard tasks keep failing. A benchmark of uniformly middling tasks shows the opposite. The single number cannot tell these apart, and at a few values of can.
To put numbers on this we need a model of how the are spread. The standard choice is the Beta distribution, a family of distributions on with two positive parameters and that can be bell-shaped, flat, or U-shaped. Its density is proportional to , its mean is , and its variance is (here and are local to this section). The sum is a concentration. Large puts every task near the same , and small piles the tasks up near 0 and 1, like benchmark B.
The moments of a Beta have a closed form. It uses the Gamma function , which extends the factorial to real numbers. It satisfies for whole numbers and for every . The Beta function is the constant that makes the Beta density integrate to one, so
The third step holds because the integral is the normalizing constant of a density. The last step applies times in the numerator and in the denominator. The same computation with gives .
The widget below draws pass@ and against for any mean and concentration. The solid curves come from tasks spread as in the histogram beside them, and the dashed curves from tasks that all sit at the mean. Before you slide, keep the mean at 0.612, set the concentration to 100, and predict what happens as you lower it to 0.3. Which way does move, which way does pass@ move, and how does the histogram change shape? Then raise the mean to 0.9 and ask whether a 90% agent is reliable at .
The cell computes the same curves with betaln, the logarithm of the Beta function, which never overflows. It prints and pass@ at four concentrations and plots both curves for .
The printed rows show the trade directly. As the concentration falls from 200 to 0.5, climbs from 0.021 to 0.405 while pass@ falls from 0.999 to 0.801. Spread across tasks moves the two metrics in opposite directions around the same .
The widget also answers the question about a 90% agent. At a mean of 0.9 and concentration 2, is 0.53, and with every task at 0.9 it is only 0.034. So a 90% agent serves a user who brings the same task 32 times without a failure only about half the time when its tasks are spread, and almost never when they are alike.
The unbiased estimator needs at least trials per task. Agent trials are expensive, since a long coding task can take many minutes and several dollars of tokens per trial. A team that ran four trials per task may still want to know , because a user will meet the task sixteen times. That needs a model of how is spread across tasks, and the Beta model gives one.
Here is the idea in words. Each task has its own unknown , drawn from a Beta. Given , the task's success count out of trials is binomial. Averaging the binomial over the Beta gives the distribution of counts we actually observe, called the beta-binomial,
Fit and by maximum likelihood over all tasks, that is, choose the values under which the observed counts are most probable. Then plug them into to predict for any .
A closed-form fit also exists. It is the method of moments, which picks the parameters whose moments equal the observed ones, and the unbiased estimates are exactly estimates of the moments of . Write and , unbiased estimates of and . For a Beta with , and . Substituting into the second gives , so
In plain words, the excess of over is the variance of across tasks, and that variance fixes the concentration. This fit needs only two trials per task.
For fixed and large , . A ratio of Gamma functions whose arguments differ by a fixed behaves like a power, as . To see it, use Stirling's formula at and at ,
Write . The right side becomes . Setting gives
So when tasks differ, reliability decays like a power of , not exponentially like . The exponent is , the parameter that controls how much mass sits near (the density near 1 behaves like ). For the τ-bench fit, and , the asymptote gives at , against the exact 0.197.
The practical warning is the flip side. A prediction of depends almost entirely on the shape of the task distribution near , which four trials per task barely constrain. Extrapolate a few doublings of , not a hundred.
The cell plants a Beta(1.224, 0.776) population, runs four trials per task, fits by the method of moments, and predicts .
With four trials on each of 115 tasks, the size of τ-retail, the moment fit predicts against a truth of 0.121. With 2,000 tasks it predicts 0.127. The guess that ignores spread, , says 0.0004, off by a factor of 300. Maximum likelihood uses the whole distribution of counts rather than two moments, and it is the method of Exercise 22.5d.
Implement two functions. fit_beta_binomial(c, n) takes an array c of per-task success counts, each out of n trials, and returns the maximum-likelihood (a, b) of the beta-binomial model. pass_hat_curve(a, b, ks) returns the predicted for each k in ks, as an array. Optimize over so that both parameters stay positive, using scipy.optimize.minimize and scipy.special.betaln. The tests plant a Beta(1.2, 0.8) population of 3,000 tasks with four trials each.
One assumption has carried all of this, that the trials of a task are independent. They are only if each trial's randomness is fresh. Seed the simulated user identically for every trial of a task and run the agent at temperature 0, and the trials become near copies of each other. Then stays close to for every , and the metric measures little. Give each trial its own recorded seed instead. Every trial can then be replayed exactly, and no two trials are the same draw, so reproducibility and independence hold together. Interviewers like to ask how to make an environment reproducible without making its trials identical, and this is the answer.
An agent's score is bought with tokens, tool calls, and time, and agents differ in price by orders of magnitude. The cost of one attempt is roughly the input tokens times their price plus the output tokens times theirs, plus tool and sandbox costs. Output tokens cost more per token than input tokens. The model reads all the input tokens in one parallel pass, but it writes output one token per pass, and §20.1 shows why that makes each output token dearer to serve.
Agents have one more twist. Each step resends the whole transcript so far as input, so the total input tokens of an attempt grow with the square of the number of steps.
Leaderboards that rank by accuracy alone hide this. Kapoor et al. (2024) re-ran the agents at the top of the HumanEval leaderboard, a set of 164 Python programming problems graded by unit tests, next to simple baselines. One baseline retried GPT-4 up to five times at temperature 0 while its code failed the example tests given with the problem. Another did the same while raising the temperature from 0 to 0.5 across retries, which they called warming. Warming was not significantly less accurate than the best agent design. The most elaborate design, a tree search over the model's possible actions (Zhou et al. 2023), cost over 50 times more than warming. Agents of similar accuracy differed in cost by almost two orders of magnitude, and none of the papers reported cost as a headline number.
The fix is to report the two numbers together and to call one agent better than another only if it is at least as good on both. Write for agent 's mean dollar cost per task and for its success rate.
For example, an agent at 70% for $6 dominates one at 68% for $15. The front is the menu of sensible choices, since any agent off it is beaten on both counts by something on it. Two further facts sharpen the comparison.
The first is that you can mix agents. Run a cheap agent on some tasks and an expensive one on the rest, chosen by a coin flip, and you get any cost and accuracy on the straight line between them. Mixing $0.03 at 55% and $1.50 at 66% half and half, for instance, gives $0.765 at 60.5%. The upper convex hull of a set of points is the boundary you get by stretching a string over them from above, so it is made of straight segments between some of the points.
The proof is linearity of expectation, applied to cost and to success separately. The Holistic Agent Leaderboard, HAL, plots its frontiers this way, as convex hulls that include the origin (Kapoor et al. 2025). A router can do better than any mixture. It sends each task to the cheap or the expensive agent based on the task itself, or escalates only when the cheap agent fails a check, so it uses information a coin flip does not. Kapoor et al.'s escalation baseline is a router of this kind. It starts with a cheap model and moves to more expensive ones when the example tests fail.
The second fact settles most arguments about whether an expensive agent is worth it. When a checker can recognize success, the cheap agent can try again until it succeeds. A verifier here means such a checker, for example unit tests, that is available when the agent is deployed. Say a cheap agent costs 1 cent per try and solves a task half the time. Allowed 3 tries, it solves the task with probability . It stops at the first success, so it uses tries on average, 1.75 cents. The box states the general case.
Proof. The task is solved unless all attempts fail, which has probability . The number of attempts is a nonnegative integer, so . For , exactly when the first attempts all fail, which has probability . Summing the geometric series gives the formula.
In plain words, when a checker exists, the honest baseline for an expensive agent is the cheap agent retried at the same spend. The cheap agent usually spends less than its budget, because it stops at the first success. The heterogeneity result above says when retries disappoint. Tasks with near 0 stay unsolved however often you retry, so the expensive agent must beat the average of , never .
The cell finds the front of four agents (only the ensemble is dominated) and shows the retried small agent climbing from 42% to 82% at 10 tries while spending under 4 cents. Its gains slow after that, from 82% at 10 tries to 91% at 30, because the tasks it almost never solves stay unsolved.
The widget starts from these five agents, and you can drag any of them to a new cost and accuracy. The budget slider sets the spend per task, and the concentration sets how spread out the small agent's per-task success is, where a low value means many tasks are nearly hopeless for it. Watch whether the dotted curve of the retried small agent passes above the agents you can afford. The no-verifier switch takes retries away, so only single attempts compete.
At real scale the same lessons hold. HAL ran 21,730 rollouts, each one full agent run on a task, of 9 models on 9 benchmarks for about $40,000 (Kapoor et al. 2025). In 21 of 36 pairings of a model, a scaffold, and a benchmark, higher reasoning effort gave equal or lower accuracy. On the web benchmark Online Mind2Web, the SeeAct scaffold with GPT-5 Medium cost $171 in total and the Browser-Use scaffold with Claude Sonnet 4 cost $1,577, nine times more, for a two-point difference in accuracy. Claude models did better with Browser-Use and OpenAI models with SeeAct. The scaffold is part of the entry, and cost must sit beside accuracy for the number to be usable. An interviewer who hears "our agent is 5 points better" will ask at what cost, and against what retry baseline.
Implement pareto_front(acc, cost). Return the indices of the agents that no other agent dominates, where dominating means higher or equal accuracy at lower or equal cost with at least one strict. Sort them by cost, then by index. Identical agents both stay.
Then implement budget_matched_accuracy(p, cost_per_try, budget) for a cheap agent with per-task success probabilities p. It is retried with a perfect verifier until it succeeds or has used tries (the small constant guards against floating-point division). Return (accuracy, expected_cost), the mean over tasks of and the mean expected spend per task. Return (0.0, 0.0) when the budget buys no try.
Every widely used agent benchmark combines a source of tasks, an environment, a grader, and a metric, and each has a documented weakness. The status column is as of October 2026, from the benchmarks' own leaderboards and Epoch AI's Benchmarking Hub (Epoch AI 2026).
| benchmark | tasks | environment and grader | known weakness | status, October 2026 |
|---|---|---|---|---|
| SWE-bench (Jimenez et al. 2023) | 2,294 GitHub issues from 12 Python repositories | repository container, hidden FAIL_TO_PASS and PASS_TO_PASS tests | solutions leaked in issues, weak tests (SWE-bench+) | superseded; Claude 2 resolved 1.96% at release |
| SWE-bench Verified (OpenAI 2024) | 500, kept from 1,699 tasks screened by 93 developers, each task labeled three times | as SWE-bench | 46% of tasks from Django; flawed tests and training contamination (OpenAI 2026) | OpenAI stopped reporting it in February 2026; Epoch's own runs top out at 83.5% (Claude Opus 4.7, April 2026) |
| SWE-Bench Pro (Deng et al. 2025) | 1,865 from 41 repositories, with held-out and proprietary subsets | as SWE-bench, human-verified | outsiders can run only the public subset | OpenAI's recommended replacement |
| τ-bench (Yao et al. 2024) | 115 retail and 50 airline tasks | tools over a JSON database, a policy document, a simulated user; graded on the final database and required outputs | doing nothing passes 38% of airline | extended by τ²-bench (Barres et al. 2025), where the user also acts on a shared telecom environment |
| WebArena (Zhou et al. 2023) | 812 tasks from 241 templates on four self-hosted sites | functional checks of pages and backend state, string matching, some model judging | string matching and an unvalidated judge overestimate by 1.4% to 5.2% (Zhu et al. 2025) | a GPT-4 agent scored 14.41% against 78.24% for humans at release |
| OSWorld (Xie et al. 2024) | 369 tasks across desktop and web applications | full virtual machines, a custom evaluation script per task | live websites drift and break the scripts | 72.1% (Claude Sonnet 4.6) against humans' 72.36%; the harder OSWorld 2 has a top score of 31.4% (Claude Opus 5) |
| GAIA (Mialon et al. 2023) | 466 questions, answers to 300 withheld | open web and tools, exact match on a short answer | the 166 validation answers are public, so only the 300 withheld ones are a clean test | humans 92% against 15% for GPT-4 with plugins at release |
| BrowseComp (Wei et al. 2025) | 1,266 hard-to-find facts | open web, short answer compared with a reference | grades only the final string, never how it was found | GPT-4o 0.6%, 1.9% with browsing, Deep Research 51.5% at release |
| Terminal-Bench 2.0 (Merrill et al. 2026) | 89 tasks drawn from real terminal workflows | a unique container per task, graded by tests, with a human-written reference solution | results depend on the scaffold as much as the model | 84.7% for GPT-5.5 in the NexAU-AHE scaffold (standard error 2.1 points); under 65% at release |
| MLE-bench (Chan et al. 2024) | 75 Kaggle competitions | GPU container, graded against each competition's leaderboard medal thresholds | public Kaggle solutions may sit in pretraining data, which the authors test for | o1-preview with the AIDE scaffold reached a medal in 16.9% at release |
Two patterns stand out. A benchmark gives way to a successor once top agents reach its human baseline, as OSWorld did to OSWorld 2, or once its flaws come to dominate its error, as SWE-bench Verified did to SWE-Bench Pro. And an entry on a leaderboard is a model in a scaffold, so the Terminal-Bench leader is a pair, not a model. Agents that do machine learning research, the subject of MLE-bench, are treated with research agents.
A different summary of agent capability is the time horizon of the research group METR. It is the length of task, measured by how long a skilled human needs for it, that an agent completes with 50% probability (Kwa et al. 2025). §19.4 derived it as a logistic regression of success on log task length and fit its doubling trend. Its intervals are wide. As of October 2026 the longest measured horizon in METR's Time Horizon 1.1 data, which Epoch's hub also lists, is about 1,045 minutes, or 17 hours, for an early preview of Claude Mythos. Its 95% interval runs from 509 to 3,304 minutes, a factor of six and a half. There are three reasons for the width. Few tasks are long enough to pin the curve where it crosses one half. Tasks come in correlated families. And the estimate extrapolates the fitted curve beyond most of the data. METR itself calls measurements above 16 hours unreliable with its current tasks, so this one is a lower-confidence reading than the rest of the series, which §24.1 reads in full. How horizons stretch for agents that work for days is taken up with long-running agents.
The last group of failures comes from the agent itself. A capable agent finds shortcuts that the benchmark's designers did not foresee, and each one needs its own defense.
At scale the estimators run over thousands of tasks at once, and the beta-binomial fit is a two-parameter optimization that autograd handles directly. The block below computes unbiased and pass@ for every task at once. It works with lgamma, the logarithm of the Gamma function, so the binomial coefficients never overflow. It then fits the beta-binomial on with L-BFGS, an optimizer that builds an approximation of the curvature from recent gradients, and compares the predicted with the truth.