跳转到内容
搜索文档

浏览器 Tool

最后更新 查看 MarkdownAgent 设置

Agent 可使用 Browser Run 通过 Chrome DevTools Protocol (CDP) 检查并与网页交互。Beta 当 Agent 需要理解渲染页面、截取屏幕截图、调试前端行为或提取仅在 JavaScript 运行后才可用的信息时,浏览器工具很有用。

与固定浏览器操作集(点击、截图、导航)不同,模型编写代码,通过 cdp connector 对实时浏览器会话运行 CDP 命令——访问协议中的所有 domain、command、event 和 type。execution 使用持久化 Code Mode 运行时,因此运行可在审批时暂停,并在浏览器会话保持完整的情况下恢复。

在以下场景使用浏览器工具:

  • 打开并检查实时网页。
  • 截取屏幕截图或页面状态。
  • 抓取静态 HTML 中不存在的渲染内容。
  • 使用 CDP 命令调试前端问题。
  • 将页面检查与其他工具(如 RAG 或 Sandbox)结合。

工作原理

Browser Run 提供 Agent 可通过 CDP 控制的隔离浏览器会话。Agent 可导航页面、评估 JavaScript、读取 DOM 状态、截取屏幕截图,并检查网络或控制台输出。

由于浏览器会话在 Worker isolate 外运行,请将其用于需要真实浏览器环境的工作,而非轻量 HTTP fetch。

基本模式

使用 Browser Run 和 Worker Loader binding 创建浏览器工具,然后将这些工具传入模型调用。

import { AIChatAgent } from "@cloudflare/ai-chat";
import { createBrowserTools } from "agents/browser/ai";
import { streamText, convertToModelMessages, stepCountIs } from "ai";
import { createWorkersAI } from "workers-ai-provider";

export class BrowserAgent extends AIChatAgent {
	async onChatMessage() {
		const workersai = createWorkersAI({ binding: this.env.AI });
		const browserTools = createBrowserTools({
			ctx: this.ctx,
			browser: this.env.BROWSER,
			loader: this.env.LOADER,
		});

		const result = streamText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			system: "You can inspect web pages with browser tools.",
			messages: await convertToModelMessages(this.messages),
			tools: browserTools,
			stopWhen: stepCountIs(10),
		});

		return result.toUIMessageStreamResponse();
	}
}
import { AIChatAgent } from "@cloudflare/ai-chat";
import { createBrowserTools } from "agents/browser/ai";
import { streamText, convertToModelMessages, stepCountIs } from "ai";
import { createWorkersAI } from "workers-ai-provider";

export class BrowserAgent extends AIChatAgent<Env> {
	async onChatMessage() {
		const workersai = createWorkersAI({ binding: this.env.AI });
		const browserTools = createBrowserTools({
			ctx: this.ctx,
			browser: this.env.BROWSER,
			loader: this.env.LOADER,
		});

		const result = streamText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			system: "You can inspect web pages with browser tools.",
			messages: await convertToModelMessages(this.messages),
			tools: browserTools,
			stopWhen: stepCountIs(10),
		});

		return result.toUIMessageStreamResponse();
	}
}

浏览器工具必须在 Durable Object(如 Agent)内创建——持久化运行时 facet 和会话存储位于其 ctx 上。helper 暴露一个持久化 CDP tool,以及存在 browser binding 时的无状态 Quick Action tool:

工具 描述
browser_execute 通过 CDP 对实时浏览器运行沙箱化代码——截图、DOM 读取、JavaScript 评估等。
browser_markdown 将页面或原始 HTML 读取为 Markdown。
browser_extract 使用 AI 从页面提取结构化数据。
browser_links 列出页面上的链接。
browser_scrape 按 CSS 选择器抓取特定元素。

要发现协议 surface,模型调用 cdp.spec()(实时、规范化的 CDP 协议描述)或运行时的内置 codemode.search()codemode.describe()

配置

将 Browser Run 和 Worker Loader 绑定添加到 wrangler.jsonc

{
	"compatibility_flags": ["nodejs_compat"],
	"browser": {
		"binding": "BROWSER"
	},
	"worker_loaders": [
		{
			"binding": "LOADER"
		}
	]
}
compatibility_flags = [ "nodejs_compat" ]

[browser]
binding = "BROWSER"

[[worker_loaders]]
binding = "LOADER"

tool 背后的持久化运行时位于 Durable Object facet 中,因此 Worker 入口必须导出它(@cloudflare/codemode/vite 插件会自动完成):

export { CodemodeRuntime } from "agents/browser";
export { CodemodeRuntime } from "agents/browser";

agents/browser 为浏览器 tool 设置重新导出 Code Mode 运行时。Code Mode 特定示例也可从 @cloudflare/codemode 导入 CodemodeRuntime

会话生命周期

默认每次 execution 获得新的浏览器会话,运行结束时销毁(one-shot)。传入 session 选项可使用另外两种模式:

createBrowserTools({
	ctx: this.ctx,
	browser: this.env.BROWSER,
	loader: this.env.LOADER,
	session: { mode: "dynamic" }, // or { mode: "reuse", key: "main" }
});
createBrowserTools({
	ctx: this.ctx,
	browser: this.env.BROWSER,
	loader: this.env.LOADER,
	session: { mode: "dynamic" }, // or { mode: "reuse", key: "main" }
});
  • one-shot(默认)— 每次 execution 新会话;execution 达到终端状态时确定性清理。
  • reuse — 命名共享会话,在显式关闭或 sweep 前跨 execution 持久化。
  • dynamic — 以 one-shot 开始;模型可用 cdp.startSession() 提升会话(例如登录页面后),使后续 execution 在同一浏览器中继续。

reusedynamic 模式下,沙箱额外获得 cdp.startSession()cdp.sessionInfo()cdp.closeSession()cdp.resetSession()

会话在 Durable Object 存储中持久跟踪,因此可在休眠和审批暂停中存活——暂停等待人工审批的运行会与其浏览器会话、标签页和 cookie 一起恢复。若 Browser Run 在暂停等待期间使会话过期,恢复会抛出清晰错误,模型重新开始。

对于宿主侧接线(会话检查、清理、回收陈旧暂停),使用 createBrowserRuntime,返回 { runtime, connector, tools }。从调度任务调用 connector.sweep() 回收过期或陈旧会话,调用 runtime.expirePaused() 拒绝从未批准的陈旧暂停。

快捷操作

对交互式多步自动化使用 browser_execute。对一次性浏览任务,使用 Browser Run 快捷操作。快捷操作只需 browser 绑定,无需 Worker Loader 或沙箱。

import { createQuickActionTools } from "agents/browser/ai";

const tools = createQuickActionTools({ browser: this.env.BROWSER });
// browser_markdown, browser_extract, browser_links, browser_scrape
import { createQuickActionTools } from "agents/browser/ai";

const tools = createQuickActionTools({ browser: this.env.BROWSER });
// browser_markdown, browser_extract, browser_links, browser_scrape

默认情况下,存在 browser binding 时 createBrowserToolscreateBrowserRuntime 包含 Quick Action tool。传入 quickActions: false 仅保留 browser_execute,或传入 quickActions: { actions, maxChars, options } 配置无状态 tool。

createBrowserTools({
	browser: this.env.BROWSER,
	loader: this.env.LOADER,
	quickActions: { maxChars: 20_000 },
});
createBrowserTools({
	browser: this.env.BROWSER,
	loader: this.env.LOADER,
	quickActions: { maxChars: 20_000 },
});

每个 Quick Action 结果限制为 maxChars,在保护模型上下文窗口的同时保留结果形状。宿主提供的请求选项(如 cookiesauthenticategotoOptionsviewport)通过 options 一次性传入,不暴露给模型。

Quick Action 需要 Worker compatibility_date2026-03-24 或更高,且本地 wrangler dev 时 browser binding 需 remote: true

Live View 与人机协同

Live View 让人类实时观看或控制运行中的浏览器会话。用于 human-in-the-loop 步骤,如登录、MFA、CAPTCHA 或敏感输入。

由于 Code Mode 运行时可在浏览器会话完整的情况下暂停运行,交接遵循以下模式:

  1. 模型调用 cdp.getLiveViewUrl() 获取当前标签页的链接。
  2. Agent 向用户展示链接。
  3. 模型进行需审批的调用,运行持久化暂停。
  4. 审批后,运行在同一会话中恢复。
async () => {
	const { targetId } = await cdp.send({
		method: "Target.createTarget",
		params: { url: "https://example.com/login" },
	});

	const { url } = await cdp.getLiveViewUrl({ targetId, mode: "tab" });
	return { needsHumanLogin: url };
};
async () => {
	const { targetId } = await cdp.send({
		method: "Target.createTarget",
		params: { url: "https://example.com/login" },
	});

	const { url } = await cdp.getLiveViewUrl({ targetId, mode: "tab" });
	return { needsHumanLogin: url };
};

mode: "tab" 为交互式页面视图,mode: "devtools" 为完整 DevTools 检查器。URL 有效期约五分钟。再次调用 cdp.getLiveViewUrl() 创建新 URL。

从宿主侧,connector.liveView() 返回共享会话标签页的 Live View URL。每个标签页包含当前 pageUrl,Agent UI 可标注标签页并跳过空白或内部页面。

会话录制

会话录制 将 Browser Run 会话捕获为结构化 rrweb 事件。会话关闭后,用录制审计或调试自主浏览器运行的行为。

按会话通过 recording: true 选择加入:

import { createBrowserRuntime } from "agents/browser/ai";

const { connector } = createBrowserRuntime({
	ctx: this.ctx,
	browser: this.env.BROWSER,
	loader: this.env.LOADER,
	session: { mode: "reuse", key: "main", recording: true },
});
import { createBrowserRuntime } from "agents/browser/ai";

const { connector } = createBrowserRuntime({
	ctx: this.ctx,
	browser: this.env.BROWSER,
	loader: this.env.LOADER,
	session: { mode: "reuse", key: "main", recording: true },
});

会话关闭后 finalize 录制。在会话存活时捕获 session ID,然后从 Browser Rendering REST API 获取录制:

import { getBrowserRecording } from "agents/browser";

const { sessionId } = (await connector.sessionInfo()) ?? {};
if (!sessionId) {
	throw new Error("No active browser session");
}

const recording = await getBrowserRecording({
	accountId: this.env.CF_ACCOUNT_ID,
	apiToken: this.env.CF_API_TOKEN,
	sessionId,
});
import { getBrowserRecording } from "agents/browser";

const { sessionId } = (await connector.sessionInfo()) ?? {};
if (!sessionId) {
	throw new Error("No active browser session");
}

const recording = await getBrowserRecording({
	accountId: this.env.CF_ACCOUNT_ID,
	apiToken: this.env.CF_API_TOKEN,
	sessionId,
});

录制保留 30 天,每会话上限两小时。在共享 reusedynamic 会话上谨慎使用录制,因为录制跨越完整会话生命周期。

CDP 连接器 API

browser_execute 内,cdp 命名空间提供以下方法。所有方法接受单个对象参数:

方法 描述
cdp.send({ method, params?, sessionId?, timeoutMs? }) 发送 CDP 命令并等待响应。
cdp.attachToTarget({ targetId, timeoutMs? }) 附加到 target;返回页面范围 send 调用的 { sessionId }
cdp.spec() 可搜索、规范化的 CDP 协议 spec。
cdp.getDebugLog({ limit? }) 此 execution 连接最近的 CDP 流量(发送、接收、警告)。
cdp.clearDebugLog() 清除 debug log 缓冲区。
cdp.getLiveViewUrl({ targetId?, mode? }) 为标签页创建 Live View URL。
cdp.startSession() (reuse/dynamic) 提升或确保共享会话;返回其信息。
cdp.sessionInfo() (reuse/dynamic) 共享会话信息,或 null
cdp.closeSession() (reuse/dynamic) 关闭共享会话。
cdp.resetSession() (reuse/dynamic) 关闭并替换共享会话。

每个 cdp.* 调用记录在运行时的持久化 log 中。若运行暂停(审批)或沙箱 abort,恢复会重放 log 并继续——因此 connector 调用必须顺序且确定性。模型代码不得 Promise.all CDP 调用(tool 说明会强制执行),返回的 sessionId 是稳定的会话 handle,在暂停/恢复重连中保持有效。

构建浏览器 Agent

完整演练(包括 Browser Run 设置、tool 定义和截图捕获)请参阅浏览器 Agent 示例。

浏览器 Agent

构建可浏览网页、检查页面、截取屏幕截图并调试前端问题的 Agent。

相关资源

Browser Run

在 Cloudflare 上运行浏览器自动化。

这篇文档对您有帮助吗?