DEV Community

Mhmad hassn
Mhmad hassn

Posted on AI-assisted

I built a browser for AI agents, then benchmarked it against Playwright MCP and browser-use

AgentGo

Every agent I tried on the web had the same problem: it was reading too much. A browser tool hands the model a page snapshot, the model clicks, and then gets a fresh snapshot of the whole page again. Most of the tokens go on re-reading things that didn't change.

So I built AgentGo, a Chromium browser for Windows (Rust, on CEF) made to be driven by an agent over MCP. Then I measured it against the two tools most people use today.

The result

Same model (gpt-6-luna, medium reasoning), same 24 BrowserGym MiniWoB++ tasks, a fresh agent session for every task, only that browser's MCP tools, and the page's own reward decides.

Agent benchmark: tasks solved, time, tokens and turns for four setups

Setup Solved Median time Input tokens Agent turns
AgentGo 0.1.5 22/24 32 s 94.7k 7.7
browser-use 0.13.11 19/24 92 s 209.9k 13.2
Playwright MCP 0.0.83 18/24 42 s 178.4k 13.0

About half the tokens, roughly half the turns, and the fastest median per task.

Why it uses fewer tokens

Three design choices do most of the work:

  1. A compact outline instead of a snapshot. browser_open returns headings plus the things you can act on, one per line, as [ref] role "name". The refs stay stable while the page changes.
  2. Only what changed. After browser_act, the reply is the diff: + for new elements, - for removed ones, ~ for changed values. The model doesn't re-read the page to find out whether its click worked.
  3. The browser waits, not the model. Each action waits for the page to settle before answering, so the agent doesn't spend turns calling "wait" and reading again.

It's also a real browser rather than a test harness: its own pointer and keyboard (so date pickers, sliders and key-listening widgets behave), the agent can have its own signed-in accounts, and payments or final submissions pause until the person approves them in the browser window.

What it got wrong

Two tasks beat every setup, AgentGo included:

  • form-sequence-2: the instruction never says to press Submit, and no agent did.
  • click-pie: every agent opened the pie menu and clicked the item, and the page didn't count the click.

And the limits of the test itself: one machine, one run per task and setup, one model. MiniWoB++ pages are small; a different model or another run will move single tasks. The full method, every task's result, and a separate check on 20 real websites are in the benchmark write-up.

GoMini

AgentGo also ships GoMini, a small model (322M parameters) that runs on your own GPU and takes routine steps, like filling the values you supplied, so the big model doesn't have to read every page. On 13 held-out task types it went from 15 to 39 of 65 subgoals between versions. It's still in development: with it on, AgentGo solved the same 22/24, at slightly more tokens.

Try it

  • AgentGo (Windows 11, free): https://github.com/Moha2005269/agentgo
  • Claude Code: /plugin install agentgo --marketplace Moha2005269/agentgo-mcp
  • Other MCP clients: the installer connects Claude Code, Codex or Droid, or run agentgo mcp. It's also on the official MCP Registry as io.github.Moha2005269/agentgo.

I built this solo. I'd love to hear what breaks, and which sites you want me to try next.

Top comments (3)

Collapse
 
agenshive profile image
Agenshive •

The diff-based observation model is the standout idea — re-reading a full page snapshot after every action is exactly where agent token budgets die in practice. I'd love to see the benchmark extended beyond MiniWoB++ to pages with heavy client-side rendering, where "the page has settled" is the hard part and refs may not survive aggressive re-renders. Did you test any live SPA-like pages yet?

Collapse
 
moe110 profile image
Mhmad hassn •

yess we actually did, but not enough benchmarking to publish the results yet. I built a small set of self-grading SPA pages that hit exactly what you described: skeletons with a background re-sync, late hydration, keyed and key={index} React lists, a virtualized list, pushState routing, debounced autocomplete, late modals and toasts, optimistic rollback, a page that never stops polling and infinite scroll, plus a few live pages like TodoMVC, react.dev search and GitHub’s file tree. Same setup as before: one model, a fresh session per task, and the page decides the score. Short version: AgentGo came out ahead, solving the most tasks on the set every browser ran, finishing faster, and using a lot fewer tokens (about 35% less than Playwright MCP and 60% less than browser-use). But you were right about re-renders. On a key={index} list a ref can stay valid while React swaps the item behind it, and AgentGo clicked the wrong row. That’s top of the list for 0.1.6, along with a few other things the run turned up, and once it’s out I’ll rerun everything properly and publish the full SPA results

Collapse
 
galagent profile image
Qingfeng •

the form-sequence-2 row is the most interesting one in that table - no agent pressing Submit because the instruction never said so is exactly the failure a diff-only feed hides: the last action returns an empty diff and the agent reads that as nothing left to do rather than not finished yet. we hit the same shape driving android UIs, and the fix was to treat an empty diff as an error and wait on a named predicate (button gone, row present) instead of on the page settling. curious whether you also make the agent stop when refs it expected disappear, or just let it re-read the outline and carry on?