vlt / affordances
  • Quickstart
  • Concepts
  • Guides
  • Reference
  • For agents
  • Why Affordances
  • Quickstart
  • Benchmarks

Concepts
  • Overview
  • Actions
  • State
  • Expose
  • Guards and confirm
  • Deltas
  • Plugins

Guides
  • Overview
  • React and WebMCP
  • MCP
  • Lint
  • Security

Plugins
  • Overview

Reference
  • Overview
  • Protocol
  • Options
  • CLI
  • What the numbers say
  • Results
  • Run history
  • Changes to the method

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.

fewer tokens than the screenshot agent
8.4×
11.6× fewer than the browser agent
Affordances agent 4,093browser agent 47,681screenshot agent 34,551
faster than the browser agent
1.9×
2.3× faster than the screenshot agent
Affordances agent 8.9sbrowser agent 17.1sscreenshot agent 20.3s
cheaper per success than the screenshot agent
5.1×
5.3× cheaper than the browser agent
Affordances agent $0.019browser agent $0.10screenshot agent $0.097
tasks completed
100%
Affordances agent 100%browser agent 100%screenshot agent 100%

Per task

Tokens, median of 5 runs

Browser agentScreenshot agentAffordances agent
Metric
Per task medians on Claude Opus 5.5, 5 runs each
TaskBrowser agent tokensScreenshot agent tokensAffordances agent tokensBrowser agent timeScreenshot agent timeAffordances agent timeBrowser agent passedScreenshot agent passedAffordances agent passed
Add to cart47,68145,5154,09315.9s21.7s9.2s5 of 55 of 55 of 5
Change quantity40,18916,0864,34716.8s10.6s8.8s5 of 55 of 55 of 5
Checkout48,55534,0384,00520.3s17.4s8.9s5 of 55 of 55 of 5
Search10,82534,5512,7246.9s20.0s7.9s5 of 55 of 55 of 5
Order status9,14515,9822,18910.2s7.3s4.0s5 of 55 of 55 of 5
Two items checkout177,717106,84519,20821.2s37.6s15.6s5 of 55 of 55 of 5
Edit cart219,337107,19216,01324.6s47.3s15.5s5 of 55 of 55 of 5
Per task on Claude Opus 5.5: medians of 5 runs, cost per successful run
TaskAgentTurnsTokensTimeCostPassed
Add to cartBrowser647,68115.9s$0.0875/5
Screenshot645,51521.7s$0.0915/5
Affordances34,0939.2s$0.0145/5
Change quantityBrowser640,18916.8s$0.0785/5
Screenshot316,08610.6s$0.0595/5
Affordances34,3478.8s$0.0135/5
CheckoutBrowser748,55520.3s$0.0755/5
Screenshot534,03817.4s$0.0795/5
Affordances34,0058.9s$0.0125/5
SearchBrowser310,8256.9s$0.0375/5
Screenshot534,55120.0s$0.0955/5
Affordances22,7247.9s$0.0115/5
Order statusBrowser39,14510.2s$0.0285/5
Screenshot315,9827.3s$0.0585/5
Affordances22,1894.0s$0.00795/5
Two items checkoutBrowser11177,71721.2s$0.185/5
Screenshot10106,84537.6s$0.155/5
Affordances719,20815.6s$0.0355/5
Edit cartBrowser13219,33724.6s$0.225/5
Screenshot10107,19247.3s$0.155/5
Affordances516,01315.5s$0.0405/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.

Tokens by kind on Claude Opus 5.5, median per run
AgentInputCache readCache writeOutput
Browser1432,78613,254431
Screenshot1220,16913,714496
Affordances82,2871,641211

Claude Haiku 5.5

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

fewer tokens than the screenshot agent
7.8×
9.2× fewer than the browser agent
Affordances agent 5,138browser agent 47,356screenshot agent 40,270
faster than the browser agent
2.5×
4.7× faster than the screenshot agent
Affordances agent 3.5sbrowser agent 8.8sscreenshot agent 16.5s
cheaper per success than the screenshot agent
4.9×
5.8× cheaper than the browser agent
Affordances agent $0.00053browser agent $0.0031screenshot agent $0.0026
tasks completed
100%
Affordances agent 100%browser agent 100%screenshot agent 97%

Per task

Tokens, median of 5 runs

Browser agentScreenshot agentAffordances agent
Metric
Per task medians on Claude Haiku 5.5, 5 runs each
TaskBrowser agent tokensScreenshot agent tokensAffordances agent tokensBrowser agent timeScreenshot agent timeAffordances agent timeBrowser agent passedScreenshot agent passedAffordances agent passed
Add to cart38,33340,2704,1428.9s15.8s3.2s5 of 55 of 55 of 5
Change quantity31,35828,9274,3547.4s10.6s3.4s5 of 55 of 55 of 5
Checkout49,21140,1555,3668.8s11.8s2.8s5 of 55 of 55 of 5
Search11,01559,3185,1384.1s58.0s3.6s5 of 55 of 55 of 5
Order status9,22517,5152,1944.3s6.1s1.5s5 of 54 of 55 of 5
Two items checkout239,475141,79321,50122.7s40.4s6.5s5 of 55 of 55 of 5
Edit cart268,359143,93217,09422.0s43.0s5.8s5 of 55 of 55 of 5
Per task on Claude Haiku 5.5: medians of 5 runs, cost per successful run
TaskAgentTurnsTokensTimeCostPassed
Add to cartBrowser538,3338.9s$0.00225/5
Screenshot540,27015.8s$0.00185/5
Affordances34,1423.2s$0.000315/5
Change quantityBrowser531,3587.4s$0.00175/5
Screenshot428,92710.6s$0.00175/5
Affordances34,3543.4s$0.000235/5
CheckoutBrowser749,2118.8s$0.00185/5
Screenshot540,15511.8s$0.00165/5
Affordances35,3662.8s$0.000415/5
SearchBrowser311,0154.1s$0.000765/5
Screenshot759,31858.0s$0.00235/5
Affordances35,1383.6s$0.000325/5
Order statusBrowser39,2254.3s$0.000515/5
Screenshot317,5156.1s$0.00154/5
Affordances22,1941.5s$0.000145/5
Two items checkoutBrowser12239,47522.7s$0.00665/5
Screenshot11141,79340.4s$0.00445/5
Affordances721,5016.5s$0.00115/5
Edit cartBrowser13268,35922.0s$0.00795/5
Screenshot11143,93243.0s$0.00455/5
Affordances517,0945.8s$0.00125/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.

Tokens by kind on Claude Haiku 5.5, median per run
AgentInputCache readCache writeOutput
Browser1431,72211,021571
Screenshot1236,54112,650555
Affordances83,7521,529316

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.

Every committed bench run, newest first, with median tokens per run
FinishedModelTasks × runsCommitBrowserScreenshotAffordances
10-29 23:43Haiku 5.5All 7 × 5ff7ddb447,35640,2705,138
10-29 23:16Opus 5.5All 7 × 5ff7ddb447,68134,5514,093
Earlier runs used the simpler store and five tasks, without the screenshot agent; see changes to the method.
10-29 21:22Haiku 5.5All 5 × 5e9bd8bd11,977–5,077
10-29 21:18Opus 5.5All 5 × 5e9bd8bd15,600–4,006
Earlier runs measured the browser agent before its fixes; see changes to the method.
10-29 18:16Opus 5.5All 5 × 51543f3617,992–3,985
10-29 18:13Haiku 5.5All 5 × 51543f3616,834–5,096
10-29 18:04Opus 5.5Search × 5partial787f51c4,982–2,690
10-29 17:40Opus 5.5All 5 × 5662606414,979–5,072
10-29 17:39Haiku 5.5All 5 × 5662606416,811–5,723
10-29Opus 5.5All 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.


PreviousQuickstartNextOverview

On this page

  • What the numbers say
  • Results
  • Run history
  • Changes to the method
Edit this page

Make your app agent-operable

Give every page a graph and every server action an agent path: HTTP, WebMCP, and MCP, with the same session and the same checks. One command sets it up.

Read the quickstart