← Blog

BLOG

Agent Browser Record: How to Log and Replay AI Browser Sessions

Agent browser record: capture, replay, and debug AI browser sessions with hosted Chromium. Learn the CDP and Playwright setup for production.

August 27, 20269 min readRemote Browser

# Agent Browser Record: How to Log and Replay AI Browser Sessions

When you run an AI agent that browses the web, you need more than a screenshot at the end. You need a full agent browser record—a replayable trace of every navigation, click, input, and network request. This is the difference between debugging a flaky agent in minutes versus hours.

In this guide, we'll cover what an agent browser record actually is, why it matters for production AI workloads, and how to implement it using hosted Chromium, CDP, and Playwright. We'll also compare the recording approaches and show you a concrete TypeScript example.

What Is an Agent Browser Record?

An agent browser record is a structured log of everything that happens inside a browser session driven by an AI agent. Unlike a simple video capture, a record includes:

  • DOM snapshots at each step
  • Network requests and responses (URLs, status codes, payloads)
  • Console logs and errors
  • Mouse and keyboard events (or their CDP equivalents)
  • Screenshots at configurable intervals
  • Agent decisions (the prompt, the tool call, the result)

The record is not just for post-mortem debugging. It's the foundation for:

  • Replaying a session to reproduce a bug
  • Evaluating agent performance against a benchmark
  • Auditing what an agent did (compliance, safety)
  • Training better agents with real interaction data

The term "agent browser record" is often conflated with "session recording" or "video replay." But for AI agents, the record must be machine-readable, not just human-viewable. You need to query it, diff it, and feed it back into your evaluation pipeline.

Why a Local Browser Record Isn't Enough

You can record a browser session locally with Playwright's built-in tracing or Chrome DevTools Protocol (CDP) methods. For a single script, that works. But in production, AI agents run across multiple cloud workers, often in ephemeral environments. Here's where local recording breaks down:

ConcernLocal BrowserHosted Chromium (Remote Browser)
Session persistenceLost when the worker diesSurvives across workers via persistent profiles
Record storageOn the local disk, hard to shareCentralized, accessible via API
Live debuggingRequires port forwarding or VNCLive viewer built into the runtime
Network visibilityLimited to local devtoolsFull request/response logging at the proxy level
ScalingOne browser per machineMany isolated sessions on demand
Replay fidelityDepends on local environmentDeterministic in a controlled runtime

If you're running browser automations with Selenium or Playwright across a fleet of workers, you need the record to be a first-class artifact, not an afterthought.

How to Record an Agent Browser Session with CDP

The Chrome DevTools Protocol is the lowest-level interface for recording browser activity. Every Chromium-based browser exposes it. When you connect to a hosted browser via CDP, you can subscribe to events and build your own record.

Here's a minimal TypeScript example that connects to a Remote Browser session and captures network and console events:

import CDP from 'chrome-remote-interface';
import { RemoteBrowser } from '@remote-browser/sdk';

async function recordAgentSession() {
  // 1. Create a hosted browser session
  const browser = await RemoteBrowser.create({
    apiKey: process.env.REMOTE_BROWSER_API_KEY,
    // Persistent profile keeps cookies and state across sessions
    profileId: 'my-agent-profile',
  });

  // 2. Get the CDP websocket endpoint
  const cdpUrl = await browser.getCdpUrl();
  const client = await CDP({ target: cdpUrl });

  const { Network, Page, Runtime, Log } = client;

  // 3. Enable the domains we want to record
  await Network.enable();
  await Page.enable();
  await Runtime.enable();
  await Log.enable();

  // 4. Collect events into a structured record
  const record: any[] = [];

  Network.requestWillBeSent((params) => {
    record.push({
      type: 'network',
      timestamp: Date.now(),
      url: params.request.url,
      method: params.request.method,
      status: params.response?.status,
    });
  });

  Log.entryAdded((params) => {
    record.push({
      type: 'console',
      timestamp: Date.now(),
      level: params.entry.level,
      text: params.entry.text,
    });
  });

  Runtime.consoleAPICalled((params) => {
    record.push({
      type: 'console-api',
      timestamp: Date.now(),
      type: params.type,
      args: params.args.map((arg) => arg.value),
    });
  });

  // 5. Navigate and let the agent work
  await Page.navigate({ url: 'https://example.com' });
  await Page.loadEventFired();

  // 6. Save the record for later replay
  await browser.saveRecord(record, { format: 'jsonl' });

  // 7. Close the session or keep it alive for the next task
  await browser.close();
}

This gives you a raw event stream. For most production use cases, you'll want to enrich it with DOM snapshots and screenshots at key decision points.

Using Playwright Tracing for a Higher-Level Record

If you're already using Playwright, you don't need to hand-roll CDP event capture. Playwright's built-in tracing is a solid agent browser record format. It captures screenshots, DOM snapshots, network, and console in a single .zip file that you can open in the Playwright Trace Viewer.

Here's how to enable it on a hosted browser:

import { chromium } from 'playwright-core';
import { RemoteBrowser } from '@remote-browser/sdk';

async function recordWithPlaywright() {
  const browser = await RemoteBrowser.connect({
    apiKey: process.env.REMOTE_BROWSER_API_KEY,
    // Use the CDP endpoint to attach Playwright
    cdpUrl: await RemoteBrowser.getCdpUrl(),
  });

  const context = await browser.newContext({
    recordVideo: { dir: 'videos/' },
    trace: 'on', // Capture trace for every action
  });

  const page = await context.newPage();

  // Your agent loop here
  await page.goto('https://example.com');
  await page.click('text=Get Started');

  // Save the trace
  await context.tracing.stop({ path: 'agent-trace.zip' });

  // The trace file contains the full agent browser record
  await browser.uploadArtifact('agent-trace.zip');

  await browser.close();
}

The Playwright trace is excellent for debugging. But it's not ideal for feeding back into an LLM evaluation loop because it's a binary format. For that, you'll want a JSONL record of decisions and outcomes.

What to Record for AI Agent Evaluation

A raw event log is not an evaluation dataset. To actually measure agent performance, your record should include the agent's reasoning and tool calls alongside the browser events.

Here's a practical schema for an agent browser record:

{
  "session_id": "abc-123",
  "timestamp": "2026-08-27T10:00:00Z",
  "steps": [
    {
      "step": 1,
      "agent_prompt": "Find the pricing page and extract the monthly cost",
      "tool_call": "browser_navigate",
      "tool_input": { "url": "https://remote-browser.dev/pricing" },
      "tool_output": { "status": 200, "title": "Pricing - Remote Browser" },
      "dom_snapshot": "<html>...</html>",
      "screenshot_path": "s3://records/abc-123/step1.png",
      "network_requests": [
        { "url": "https://remote-browser.dev/pricing", "status": 200 }
      ],
      "latency_ms": 1200
    }
  ]
}

This structure lets you:

  • Replay the exact sequence of tool calls
  • Diff two runs to see where behavior diverged
  • Score whether the agent achieved the goal
  • Filter for failure patterns (e.g., repeated 404s, timeouts)

Keeping Sessions Alive Across Cloud Workers

One of the hardest problems in production browser automation is session persistence. If your agent runs on a serverless worker, the browser context dies when the function ends. The next invocation starts from scratch—losing cookies, local storage, and the navigation history.

The solution is a persistent browser profile. With Remote Browser, you create a profile once and attach it to any new session. The profile stores cookies, localStorage, and other state. This means your agent can pick up where it left off, even across different cloud workers.

Here's the pattern:

// Worker 1: Start the task
const session1 = await RemoteBrowser.create({
  profileId: 'user-42-profile',
});

// ... agent works, session ends

// Worker 2: Continue the task
const session2 = await RemoteBrowser.create({
  profileId: 'user-42-profile', // Same profile, new session
});

// session2 has the same cookies and state as session1

This is critical for long-running tasks like form submissions, multi-page checkouts, or any workflow that requires authentication.

Live Debugging: The Missing Piece

A record is useful after the fact, but you also need to see what the agent is doing *right now*. That's where a live viewer comes in. Remote Browser provides a live viewer that streams the browser viewport in real time. You can watch the agent navigate, click, and type—and intervene if it goes off track.

For debugging, combine the live viewer with the record:

  1. Watch live to see the current state.
  2. Pause the agent if it's stuck.
  3. Inspect the record to see the exact sequence of events that led to the failure.
  4. Replay the record in a fresh session to test a fix.

This workflow is far more efficient than reading logs or watching a video after the fact.

Comparison: Recording Approaches

ApproachGranularityReplayLLM-FriendlySetup Effort
CDP raw eventsHigh (network, console, DOM)ManualYes (JSONL)High
Playwright TraceMedium (screenshots, DOM, network)Built-in viewerNo (binary)Low
Custom agent recordHigh (agent + browser)CustomYes (JSON)Medium
Video onlyLow (visual)ManualNoLow

For production AI agents, we recommend a hybrid: use Playwright tracing for debugging, and a custom JSONL record for evaluation and replay.

Production Criteria for Agent Browser Recording

Before you adopt any recording approach, verify these criteria:

  1. Storage: Where does the record live? Can you query it? S3-compatible object storage is a good default.
  2. Retention: How long do you keep records? Define a policy based on compliance needs.
  3. Privacy: If the agent handles PII, the record contains it. Encrypt at rest and in transit.
  4. Cost: Recording every network request can be expensive. Sample or filter based on importance.
  5. Determinism: Can you replay the record in a clean environment and get the same result? If not, your record is incomplete.

Getting Started with Remote Browser

Remote Browser is a hosted Chromium runtime designed for AI agents and browser automation. It gives you:

  • CDP access for low-level control
  • Playwright and Puppeteer compatibility via the standard APIs
  • Persistent profiles for session continuity
  • Live viewer for real-time debugging
  • Configurable browser settings for proxy and stealth-related needs

To start recording agent browser sessions in production, see the documentation for API details, or check the pricing page for current limits and rates.

If you're new to hosted browsers, read our guide on remote browsers for AI agents to understand the runtime layer. For a deeper dive into the practical setup, see remote web browser and remote control browser.

Conclusion

An agent browser record is not a nice-to-have; it's a requirement for any serious AI web automation workload. It enables debugging, evaluation, and compliance. The best approach combines CDP-level event capture with a structured agent log, stored centrally and replayable on demand.

Hosted Chromium makes this practical. You get persistent sessions, centralized records, and live debugging without managing browser infrastructure yourself. Start with Playwright tracing for quick wins, then build a custom JSONL record for evaluation. Your future self—and your agents—will thank you.

For the technical details on connecting via CDP, refer to the Chrome DevTools Protocol documentation. For Playwright-specific tracing, see the Playwright trace viewer docs.