Skip to content
HN On Hacker News ↗

The Bitter Lesson of Browser Agents

▲ 13 points • 2 comments • by gregpr07 • 3w ago • HN discussion ↗

Pangram verdict · v3.3

We believe this text is mainly AI, with some human-written content.

67 %

AI likelihood · overall

AI
7% human-written 93% AI-generated
SEGMENTS · HUMAN 0 of 3
SEGMENTS · AI 1 of 3
WORD COUNT 707
PEAK AI % 76% · §3
Analyzed
Sep 15
backend: pangram/v3.3
Segments scanned
3 windows
avg 236 words each
Distribution
7 / 93%
human / AI fraction
Verdict
AI
Pangram v3.3

Article text · 707 words · 3 segments analyzed

Human AI-generated
§1 Mixed · 61%

When we launched Browser Use in November 2024, GPT-4o wasn't trained for computer use. Built on next-token prediction, it didn't reliably understand what it could do on a page. We had to spell it out. As models got better at coding, we moved from predefined state and actions to code: first the model wrote its actions, then its observations. Now it does both through raw CDP, inside an existing agent harness. Defining state and action space We defined the state: here's what's on the page, here's what's clickable. Then the action space: click, type, scroll. Every interaction had to fit those rules. Our early loop: we chose what the model could see and do. The model picked an action, we ran it and sent back the next state. But browser automation is a game of edge cases. Every exception needed another fix. Replacing fixed actions with code Models were getting much better at coding. We experimented with JavaScript execution in September 2025 and persistent notebooks in October. The model could write a program instead of picking actions. Let it write the actions. Still our page state. Code is illustrative. Drawing a signature or looping through comments no longer needed a new action. Variables persisted, so the model could inspect results and keep going. Hermes agent replaced 12 browser tools with browser_exec, powered by our Browser Use CLI. Mean token use fell 60% for Opus 4.8 and 66% for Kimi K3. Both versions solved 18/18 runs per model (six tasks, three runs). The limits of predefined state We'd opened up the actions, but we still decided what the model could see. That became the next problem. A cookie button can be right there on the screen and missing from the state we send. Maybe the accessibility tree doesn't expose it, or our processing drops it. Either way, the model never sees the button. The button is there. We just failed to show it.

§2 Mixed · 34%

An EHR dropdown might look like this (simplified DevTools tree): <ehr-app> #shadow-root (open) <iframe src="https://ui.example"> #document <!-- other origin --> <dropdown-menu> #shadow-root (closed) <button>Choose...</button> Our state heuristics couldn't anticipate every website.

§3 AI · 76%

We'd given the model freedom to act, but it was still looking through our assumptions. Removing predefined state What if we let it write the observations, too? We gave the LLM direct access to CDP, the Chrome DevTools Protocol. No mandatory list of clickable elements. It could write code to inspect the DOM, take a screenshot or look inside one frame. The model chooses what to inspect. CDP commands are illustrative. The browser still has state. What disappears is our requirement that everything fit one predefined representation. A screenshot might answer one question. A DOM query might answer the next. The model decides what it needs to see. Why CDP, not Playwright? CDP is Chrome's native control protocol. The model can use it directly. For Chrome, CDP gives the model access beneath Playwright's browser API. Playwright adds assumptions, such as locators that cannot see closed shadow roots. CDP can inspect those roots directly. Playwright also exposes CDP; we made direct access the default. A simple browser harness Pi, Codex and OpenCode already handle the agent loop. Coding agents have millions of users trying all sorts of work. That testing is a reason to reuse their harnesses. An agent five hours into QA shouldn't fail because of a bug in the loop. We once hit compaction that produced so much context it immediately triggered compaction again. Our customers shouldn't have to discover those bugs. We add a simple browser tool: persistent code, with text, screenshots and errors coming back to the model. A CLI or tool call connects the agent to CDP. From our Agent SDK in January 2026 to Browser Harness in April, this became the direction. Browser Harness, BrowserCode and Browser Use Pi take different approaches. All let the model choose what to see and do. What is actually the bitter lesson here? Sutton's bitter lesson favors general methods that improve with more computation. For us: Reuse a proven agent harness. Expose the simplest underlying interface the model can use well. Let the model choose its observations and actions. Browsers, computers, text, music: the same principle applies. As models change, rethink the harness.