---
title: "Benchmarks · Affordances"
description: "How the benchmark compares a browser agent, a screenshot agent and an Affordances agent on the same tasks, and where its results are published."
url: "https://affordances.vercel.app/docs/benchmarks"
image: "https://affordances.vercel.app/og/docs/benchmarks"
lang: "en"
---

# Benchmarks

How the benchmark compares a browser agent, a screenshot agent and an Affordances agent on the same tasks, and where its results are published.

The bench runs the same tasks against the example store, Acme Store, with three agents, using the same model for all three:

1. a **browser agent** driving Chromium through Playwright, reading each page as an accessibility snapshot (`goto`, `click`, `fill`, `press`). It selects radios and checkboxes with `check()`, as clicking their label would;
2. a **screenshot agent** on Claude's computer use toolset, the way most browser agents work today: a 1280×800 Chromium screen, seen only as screenshots, and acted on by coordinates and keystrokes. Its actions answer OK, and it takes a screenshot when it wants to see. It has the same `goto` and the same session as the browser agent;
3. an **Affordances agent**, headless, whose only tools are `affordances_open` and `affordances_call`, given the site index (every route and action) up front, as an MCP client gets it from `@affordances/mcp`.

Neither baseline ever sees the store's demo-only Agent view toggle. Acme Store is built to read like a real shop: category menus, breadcrumbs, a product gallery, reviews, related products and a footer, rendered accessibly and never padded. Making it read that way changed none of its pages' graphs.

The tasks are the ones a shopper does: find a product and add it to the cart, change a quantity, check out (including the confirm step), search, look up an order, and two longer ones: buy two named items and check out, and make three edits to a cart (swap a variant, change a quantity, add an item). Each run records turns, tool calls, tokens (input, cache reads, cache writes, output), dollar cost, wall time, time to first action, a trace of every tool call, and whether the task succeeded, checked against the store rather than the agent's word. Results are committed as JSON in `apps/bench/results`, one file per model, with the commit they ran against.

## What the numbers say

As of the October 29, 2026 runs, five per task on Claude Opus 5.5 and Claude Haiku 5.5:

- **Nearly every run finishes.** On Opus, all three agents complete every task. On Haiku, the screenshot agent failed one of its five order-status runs; the other two agents completed everything. What Affordances changes here is mostly the cost of finishing.
- **Against the stronger baseline, the Affordances agent uses about eight times fewer tokens.** The headline figures always compare with whichever baseline did better on that measure. Median per task on Opus: 4,093 tokens against the screenshot agent's 34,551 (8.4×) and the browser agent's 47,681 (11.6×); 8.9s against the browser agent's 17.1s (1.9×); $0.019 per successful task against the screenshot agent's $0.097 (5.1×). On Haiku: 7.8× fewer tokens than the screenshot agent, 2.5× faster than the browser agent, and 4.9× cheaper than the screenshot agent.
- **The longer the task, the wider the gap.** Buying two items or editing a cart takes the browser agent 178,000 to 219,000 tokens on Opus, because it re-reads a large snapshot every turn; the screenshot agent about 107,000; the Affordances agent 16,000 to 19,000, in 5 to 7 turns against 10 to 13.
- **The baselines trade places.** The screenshot agent reads fewer tokens than the browser agent on most tasks, but it's the slowest: a median 20.3s on Opus and up to 47s on editing a cart, one screenshot and one coordinate at a time.
- **Search is the browser agent's win on time.** On Opus it answers in 6.9s against the Affordances agent's 7.9s, a results page being cheap to read; it still uses four times the tokens (10,825 against 2,724).

These are five runs per task on one store. Read the per-task medians as a direction, not a precise ratio.

## Results

The newest full run of each model.

### Claude Opus 5.5

Medians of 5 runs per task, run on 2026-10-29 at commit `ff7ddb4`. Cost is per successful run.

Median per run: 47,681 tokens for the browser agent, 34,551 tokens for the screenshot agent, 4,093 tokens for the Affordances agent; 17.1s for the browser agent, 20.3s for the screenshot agent, 8.9s for the Affordances agent; 6 turns for the browser agent, 5 turns for the screenshot agent, 3 turns for the Affordances agent. Cost per successful task: $0.10 for the browser agent, $0.097 for the screenshot agent, $0.019 for the Affordances agent. Tasks completed: 100% for the browser agent, 100% for the screenshot agent, 100% for the Affordances agent. Against the stronger baseline on each measure: 8.4× fewer tokens than the screenshot agent (11.6× fewer than the browser agent); 1.9× faster than the browser agent (2.3× faster than the screenshot agent); 5.1× cheaper per success than the screenshot agent (5.3× cheaper than the browser agent).

| Task               | Agent       | Turns | Tokens  | Time  | Cost    | Passed |
| ------------------ | ----------- | ----- | ------- | ----- | ------- | ------ |
| Add to cart        | Browser     | 6     | 47,681  | 15.9s | $0.087  | 5/5    |
|                    | Screenshot  | 6     | 45,515  | 21.7s | $0.091  | 5/5    |
|                    | Affordances | 3     | 4,093   | 9.2s  | $0.014  | 5/5    |
| Change quantity    | Browser     | 6     | 40,189  | 16.8s | $0.078  | 5/5    |
|                    | Screenshot  | 3     | 16,086  | 10.6s | $0.059  | 5/5    |
|                    | Affordances | 3     | 4,347   | 8.8s  | $0.013  | 5/5    |
| Checkout           | Browser     | 7     | 48,555  | 20.3s | $0.075  | 5/5    |
|                    | Screenshot  | 5     | 34,038  | 17.4s | $0.079  | 5/5    |
|                    | Affordances | 3     | 4,005   | 8.9s  | $0.012  | 5/5    |
| Search             | Browser     | 3     | 10,825  | 6.9s  | $0.037  | 5/5    |
|                    | Screenshot  | 5     | 34,551  | 20.0s | $0.095  | 5/5    |
|                    | Affordances | 2     | 2,724   | 7.9s  | $0.011  | 5/5    |
| Order status       | Browser     | 3     | 9,145   | 10.2s | $0.028  | 5/5    |
|                    | Screenshot  | 3     | 15,982  | 7.3s  | $0.058  | 5/5    |
|                    | Affordances | 2     | 2,189   | 4.0s  | $0.0079 | 5/5    |
| Two items checkout | Browser     | 11    | 177,717 | 21.2s | $0.18   | 5/5    |
|                    | Screenshot  | 10    | 106,845 | 37.6s | $0.15   | 5/5    |
|                    | Affordances | 7     | 19,208  | 15.6s | $0.035  | 5/5    |
| Edit cart          | Browser     | 13    | 219,337 | 24.6s | $0.22   | 5/5    |
|                    | Screenshot  | 10    | 107,192 | 47.3s | $0.15   | 5/5    |
|                    | Affordances | 5     | 16,013  | 15.5s | $0.040  | 5/5    |

Where the tokens go, median per run. Every turn re-reads the conversation so far from the cache, so cache reads grow with each step an agent takes.

| Agent       | Input | Cache read | Cache write | Output |
| ----------- | ----- | ---------- | ----------- | ------ |
| Browser     | 14    | 32,786     | 13,254      | 431    |
| Screenshot  | 12    | 20,169     | 13,714      | 496    |
| Affordances | 8     | 2,287      | 1,641       | 211    |

### Claude Haiku 5.5

Medians of 5 runs per task, run on 2026-10-29 at commit `ff7ddb4`. Cost is per successful run.

Median per run: 47,356 tokens for the browser agent, 40,270 tokens for the screenshot agent, 5,138 tokens for the Affordances agent; 8.8s for the browser agent, 16.5s for the screenshot agent, 3.5s for the Affordances agent; 6 turns for the browser agent, 5 turns for the screenshot agent, 3 turns for the Affordances agent. Cost per successful task: $0.0031 for the browser agent, $0.0026 for the screenshot agent, $0.00053 for the Affordances agent. Tasks completed: 100% for the browser agent, 97% for the screenshot agent, 100% for the Affordances agent. Against the stronger baseline on each measure: 7.8× fewer tokens than the screenshot agent (9.2× fewer than the browser agent); 2.5× faster than the browser agent (4.7× faster than the screenshot agent); 4.9× cheaper per success than the screenshot agent (5.8× cheaper than the browser agent).

| Task               | Agent       | Turns | Tokens  | Time  | Cost     | Passed |
| ------------------ | ----------- | ----- | ------- | ----- | -------- | ------ |
| Add to cart        | Browser     | 5     | 38,333  | 8.9s  | $0.0022  | 5/5    |
|                    | Screenshot  | 5     | 40,270  | 15.8s | $0.0018  | 5/5    |
|                    | Affordances | 3     | 4,142   | 3.2s  | $0.00031 | 5/5    |
| Change quantity    | Browser     | 5     | 31,358  | 7.4s  | $0.0017  | 5/5    |
|                    | Screenshot  | 4     | 28,927  | 10.6s | $0.0017  | 5/5    |
|                    | Affordances | 3     | 4,354   | 3.4s  | $0.00023 | 5/5    |
| Checkout           | Browser     | 7     | 49,211  | 8.8s  | $0.0018  | 5/5    |
|                    | Screenshot  | 5     | 40,155  | 11.8s | $0.0016  | 5/5    |
|                    | Affordances | 3     | 5,366   | 2.8s  | $0.00041 | 5/5    |
| Search             | Browser     | 3     | 11,015  | 4.1s  | $0.00076 | 5/5    |
|                    | Screenshot  | 7     | 59,318  | 58.0s | $0.0023  | 5/5    |
|                    | Affordances | 3     | 5,138   | 3.6s  | $0.00032 | 5/5    |
| Order status       | Browser     | 3     | 9,225   | 4.3s  | $0.00051 | 5/5    |
|                    | Screenshot  | 3     | 17,515  | 6.1s  | $0.0015  | 4/5    |
|                    | Affordances | 2     | 2,194   | 1.5s  | $0.00014 | 5/5    |
| Two items checkout | Browser     | 12    | 239,475 | 22.7s | $0.0066  | 5/5    |
|                    | Screenshot  | 11    | 141,793 | 40.4s | $0.0044  | 5/5    |
|                    | Affordances | 7     | 21,501  | 6.5s  | $0.0011  | 5/5    |
| Edit cart          | Browser     | 13    | 268,359 | 22.0s | $0.0079  | 5/5    |
|                    | Screenshot  | 11    | 143,932 | 43.0s | $0.0045  | 5/5    |
|                    | Affordances | 5     | 17,094  | 5.8s  | $0.0012  | 5/5    |

Where the tokens go, median per run. Every turn re-reads the conversation so far from the cache, so cache reads grow with each step an agent takes.

| Agent       | Input | Cache read | Cache write | Output |
| ----------- | ----- | ---------- | ----------- | ------ |
| Browser     | 14    | 31,722     | 11,021      | 571    |
| Screenshot  | 12    | 36,541     | 12,650      | 555    |
| Affordances | 8     | 3,752      | 1,529       | 316    |

## Run history

Every committed results file, newest first, with each agent's median tokens per run; a dash means the run didn't have that agent. A partial run re-ran some of the tasks (`--tasks`) and isn't used above.

| Finished                                                                                                                                                                             | Model     | Tasks × runs      | Commit  | Browser | Screenshot | Affordances |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | ----------------- | ------- | ------- | ---------- | ----------- |
| [10-29 23:43](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29T2343-claude-haiku-5-5.json)                                                              | Haiku 5.5 | All 7 × 5         | ff7ddb4 | 47,356  | 40,270     | 5,138       |
| [10-29 23:16](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29T2316-claude-opus-5-5.json)                                                               | Opus 5.5  | All 7 × 5         | ff7ddb4 | 47,681  | 34,551     | 4,093       |
| Earlier runs used the simpler store and five tasks, without the screenshot agent; see [changes to the method](https://affordances.vercel.app/docs/benchmarks#changes-to-the-method). |           |                   |         |         |            |             |
| [10-29 21:22](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29T2122-claude-haiku-5-5.json)                                                              | Haiku 5.5 | All 5 × 5         | e9bd8bd | 11,977  | –          | 5,077       |
| [10-29 21:18](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29T2118-claude-opus-5-5.json)                                                               | Opus 5.5  | All 5 × 5         | e9bd8bd | 15,600  | –          | 4,006       |
| Earlier runs measured the browser agent before its fixes; see [changes to the method](https://affordances.vercel.app/docs/benchmarks#changes-to-the-method).                         |           |                   |         |         |            |             |
| [10-29 18:16](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29T1816-claude-opus-5-5.json)                                                               | Opus 5.5  | All 5 × 5         | 1543f36 | 17,992  | –          | 3,985       |
| [10-29 18:13](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29T1813-claude-haiku-5-5.json)                                                              | Haiku 5.5 | All 5 × 5         | 1543f36 | 16,834  | –          | 5,096       |
| [10-29 18:04](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29-claude-opus-5-5-search.json)                                                             | Opus 5.5  | Search × 5partial | 787f51c | 4,982   | –          | 2,690       |
| [10-29 17:40](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29-claude-opus-5-5.json)                                                                    | Opus 5.5  | All 5 × 5         | 6626064 | 14,979  | –          | 5,072       |
| [10-29 17:39](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29-claude-haiku-5-5.json)                                                                   | Haiku 5.5 | All 5 × 5         | 6626064 | 16,811  | –          | 5,723       |
| [10-29](https://github.com/vltpkg/affordances/blob/main/apps/bench/results/2026-10-29.json)                                                                                          | Opus 5.5  | All 5 × 5         | –       | 14,931  | –          | 5,487       |

## Changes to the method

**October 29, 2026, later that day: a realistic store, longer tasks, and a screenshot agent.** The store was unusually minimal, which flattered the browser agent. It now has what typical stores have (category menus, breadcrumbs, a gallery, reviews, related products, a footer), and its accessibility snapshots grew 2.9 to 6.4 times: a product page went from 1,151 to 7,313 characters, still lighter than most real stores. No page's graph changed with it; every one is byte-identical. Two longer tasks joined the five, and the screenshot agent joined as a second baseline. One change helps the Affordances agent: `search` now returns each result's variants with their SKUs, so adding to the cart is a search and an `addToCart`, three turns instead of four. Runs before this are marked in the history above; compare them only with each other.

**October 29, 2026: a fairer browser agent.** The store's size options are styled radios: a visually hidden input under its label, which takes the pointer. Every click the browser agent made on one waited 5 seconds and failed, which made up most of the add-to-cart gap and was why it failed add-to-cart on Haiku. It also kept clicking the store's Agent view toggle, a demo control no real store has, which put the page's graph in its snapshot. It now selects radios and checkboxes with `check()`, as clicking their label would, and the toggle is hidden from it. Runs before this change are marked in the history above; compare them only with each other.
