← Blog

BLOG

Web AI Agents: A Runtime Guide for Browser Automation

Web AI agents need a real browser runtime. Learn how hosted Chromium, CDP, and Playwright fit together for reliable web automation in production.

9 min readRemote Browser
Ivory computer towers connected across terracotta platforms in a quiet desert landscape
The infrastructure behind your browserREMOTE BROWSER / ILLUSTRATION

Web AI agents are LLM-driven programs that read pages, click, type, and navigate real websites to complete tasks. The model decides what to do; the browser does it. Most teams get the model loop working in a day and then spend months fighting the part nobody demos: the browser runtime underneath. This guide covers what web AI agents actually need from that runtime, where local Chrome breaks down, and how to wire a hosted Chromium session over CDP with Playwright.

If you want the conceptual background first, see Remote browsers for AI agents. This post is the implementation-focused companion.

What web AI agents actually do

Strip away the branding and a web AI agent is a loop:

  1. Observe. Capture the DOM, an accessibility tree, a screenshot, or a mix.
  2. Decide. Send that observation to a model with the task and tool definitions.
  3. Act. Execute a tool call — click a selector, type text, scroll, navigate, extract.
  4. Verify. Re-observe and check whether the page state changed as expected.

That loop is model-agnostic. It works with GPT-class models, Claude, open-weight models, or a hand-written state machine. What it is *not* is model-agnostic in its failure modes. Almost every production incident traces back to step 1 or step 3: the observation was stale, the page hadn't hydrated, the session died mid-task, or the site served a different page to a datacenter IP.

So the runtime question is not "which model is smartest." It is "which browser environment makes the observe-act-verify loop deterministic enough to trust."

Why local Chrome stops working

Running chromium.launch() on your laptop or CI box is fine for a demo. It breaks in predictable ways once agents run continuously:

  • State leakage. Cookies, localStorage, and service workers persist between runs. Agent A's logged-in session bleeds into Agent B's task.
  • Resource contention. Each Chromium instance consumes a large amount of memory. Ten parallel agents on one box will thrash.
  • No observability. When an agent fails at 3 a.m., you have a log line and no idea what the page looked like.
  • IP reputation. Cloud egress IPs get challenged by bot management far more often than residential traffic.
  • Version drift. The Chromium your agent was tested against is not the one on the next machine.

None of these are model problems. They are infrastructure problems, and they compound as concurrency grows.

What a production runtime must provide

A runtime for web AI agents needs to answer five questions well. Use this as an evaluation checklist regardless of vendor.

RequirementWhy it mattersWhat to look for
Session isolationPrevents cross-task state leakageFresh browser context per session; explicit teardown
Persistent profilesSome tasks require staying logged inOpt-in profile reuse, not default
CDP accessLets Playwright, Puppeteer, Selenium, and custom loops attachWebSocket CDP endpoint per session
Live viewerDebugging agents without a viewer is guessworkReal-time view of the session, ideally with input
Network controlsIP reputation drives success on many sitesConfigurable proxy settings, region selection
Usage meteringCost control at scalePer-session or per-hour accounting, visible in the dashboard

Remote Browser provides hosted Chromium sessions with CDP endpoints, a live viewer, persistent profiles, configurable proxy and browser settings, and usage controls. Current limits and pricing are on the pricing page — check there rather than assuming a number.

Connecting an agent to hosted Chromium

The integration path most teams use is Playwright's connectOverCDP, which attaches to a remote browser instead of launching a local one. The Playwright CDP documentation covers the API surface; the practical pattern looks like this:

import { chromium, Browser, Page } from "playwright";

interface SessionInfo {
  cdpUrl: string; // wss://... from the session creation API
}

async function runAgentTask(task: string): Promise<string> {
  const session = await createSession(); // your API call to Remote Browser
  let browser: Browser | undefined;

  try {
    browser = await chromium.connectOverCDP(session.cdpUrl);
    const context = browser.contexts()[0] ?? (await browser.newContext());
    const page: Page = context.pages()[0] ?? (await context.newPage());

    await page.goto("https://example.com", { waitUntil: "domcontentloaded" });

    // The agent loop: observe -> decide -> act -> verify.
    for (let step = 0; step < 20; step++) {
      const observation = await page.evaluate(() => ({
        url: location.href,
        title: document.title,
        text: document.body.innerText.slice(0, 4000),
      }));

      const action = await decideNextAction(task, observation); // your model call

      if (action.type === "done") return action.result;
      if (action.type === "click") await page.click(action.selector);
      if (action.type === "type") await page.fill(action.selector, action.text);
      if (action.type === "goto") await page.goto(action.url);

      await page.waitForLoadState("networkidle").catch(() => {});
    }

    throw new Error("Step budget exhausted");
  } finally {
    await browser?.close();
    await endSession(session); // release the hosted browser
  }
}

A few details that matter in practice:

  • Always close the session in `finally`. A leaked session keeps billing and holds a slot.
  • Bound the step budget. Agents that loop forever on a captcha wall burn money fast.
  • Prefer `domcontentloaded` plus explicit waits over networkidle alone; SPAs often never go idle.
  • Capture a screenshot on failure. It is the single most useful debugging artifact.

If you are still deciding between local and hosted execution, Remote browser online walks through the trade-offs.

The observe step is where agents fail

Most "the agent is dumb" reports are observation bugs. The model sees a stale DOM, a cookie banner covering the button, or an accessibility tree that omits the element it needs.

Practical mitigations:

  • Wait for the specific element, not a fixed timeout. page.waitForSelector with a state check beats sleep(2000).
  • Trim observations. Sending the full DOM of a 5,000-node page wastes tokens and buries the relevant element. Extract interactive elements, headings, and visible text.
  • Include the URL and title in every observation so the model can detect navigation.
  • Handle overlays explicitly. A dismiss-cookie-banner step before the main task saves a lot of retries.

These are agent-design decisions, but they are easier to iterate on when you can watch the session live and replay what the model saw.

Browser tools and the tool-calling layer

"Browser tools" usually refers to the function definitions you expose to the model: click, type, scroll, extract, navigate, screenshot. The quality of these tools matters more than most teams expect.

A few rules that hold up:

  • Keep the tool surface small. Ten well-documented tools beat forty overlapping ones.
  • Return structured errors. "Element not found" with the selector and a screenshot beats a stack trace.
  • Make tools idempotent where possible. Retries are inevitable; a double-click on "Submit Order" is not.
  • Separate read tools from write tools. Read tools can be retried freely; write tools need confirmation logic.

If you are building on an existing framework — browser-use, Stagehand, agent-browser, or a custom loop — the tool layer is usually where the framework ends and your code begins. The runtime underneath should not care which one you pick, as long as it speaks CDP.

Persistent profiles vs. fresh sessions

This is the most consequential configuration choice for web AI agents, and it is worth being explicit about.

ModeBest forRisks
Fresh session per taskPublic data extraction, form filling, QARe-login cost on authenticated sites
Persistent profileRecurring tasks on authenticated sitesState drift, stale cookies, cross-task contamination
Profile per tenantMulti-tenant SaaS agentsRequires disciplined profile naming

Default to fresh sessions. Add persistent profiles only when a task genuinely requires an authenticated state that cannot be re-established cheaply. When you do use profiles, scope them narrowly — one profile per user or per tenant, never one shared profile across unrelated tasks.

Remote Browser supports persistent profiles as an opt-in; see the documentation for the current API shape.

Network controls and IP reputation

Many sites treat datacenter IPs differently from residential ones. For agents doing research, price monitoring, or anything touching consumer-facing sites, IP reputation is often the difference between a clean page and a challenge wall.

What to configure:

  • Proxy region. Match the region to the site's expected audience where it matters.
  • Proxy type. Residential proxy services cost more but reduce challenge rates on consumer sites.
  • Consistency. Use the same egress for a multi-step task; switching mid-session can invalidate sessions.

Remote Browser exposes configurable proxy and browser settings per session. The right defaults depend on your target sites — measure challenge rates before and after changing anything.

Debugging and observability

An agent you cannot watch is an agent you cannot fix. The minimum viable observability stack:

  1. Live viewer during development and for on-call triage.
  2. Screenshots on every failure, stored with the task ID.
  3. Structured logs of each tool call with inputs and outputs.
  4. Session recordings for post-mortems on hard failures.

The remote control browser post covers the live-viewer workflow in more depth. For production, the goal is to reconstruct exactly what the model saw at each step — not just what it decided.

Cost and concurrency planning

Two numbers drive cost: how long each session runs, and how many run in parallel. Both are easy to underestimate.

  • Session duration includes model latency. An agent that thinks for 30 seconds per step on a 20-step task holds a browser for ten minutes even if it only "works" for two.
  • Concurrency is bounded by your provider's limits and your budget. Plan for peak, not average.
  • Idle sessions are pure waste. Close them aggressively.

Remote Browser meters usage per session; current rates and limits are on the pricing page. Model your workload against real numbers before committing to a concurrency target.

A production checklist

Before you ship web AI agents to real users:

  • [ ] Every session is closed in a finally block.
  • [ ] Step budgets are enforced per task.
  • [ ] Observations are trimmed and include URL and title.
  • [ ] Failures capture a screenshot and the last observation.
  • [ ] Persistent profiles are opt-in and scoped per tenant.
  • [ ] Proxy settings are matched to target sites and measured.
  • [ ] Concurrency limits are set below provider caps.
  • [ ] A live viewer is available for on-call debugging.
  • [ ] Cost per successful task is tracked, not just cost per session.

Where to go next

The model layer of web AI agents is commoditizing fast. The runtime layer is where reliability is won or lost. If you are moving from a local prototype to production, start with the documentation to create a session and connect over CDP, then check pricing to size your workload. For a broader look at how remote browsers fit into agent architectures, read Remote web browser.