INTEGRITY Dokumentace

Agent prohlížeče

Sestavte agenta, který dokáže procházet web, zkoumat stránky, pořizovat snímky obrazovky a ladit problémy frontendu pomocí Browser Run nástroje. Beta

Místo pevné sady akcí prohlížeče (click, screenshot, navigate) LLM píše kód JavaScriptu, který spouští příkazy CDP proti živé relaci prohlížeče, a má tak přístup ke všem doménám, příkazům, událostem a typům protokolu.

K dispozici jsou dva nástroje:

Nástroj Popis
browser_search Dotazujte se na specifikaci CDP a zjišťujte příkazy, události a typy. Specifikace se dynamicky načítá z endpointu CDP prohlížeče a ukládá se do mezipaměti.
browser_execute Spouštějte příkazy CDP v živém prohlížeči přes cdp pomocná funkce. Každé volání otevře novou relaci prohlížeče, spustí kód a poté ji uzavře.

Kdy použít nástroje prohlížeče

Nástroje prohlížeče se hodí, když váš agent potřebuje:

Pro základní načítání stránek, které nepotřebuje vykreslené DOM, použijte fetch() místo toho.

Instalovat

Nástroje prohlížeče vyžadují Agents SDK a @cloudflare/codemode:

npm install agents @cloudflare/codemode ai zod

Rychlý start

1. Nakonfigurujte vazby

Přidejte vazby Browser Run (dříve Browser Rendering) a Worker Loader do konfigurace wrangler:

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

[browser]
binding = "BROWSER"

[[worker_loaders]]
binding = "LOADER"

2. Vytvořte nástroje prohlížeče

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

const browserTools = createBrowserTools({
	browser: env.BROWSER,
	loader: env.LOADER,
});
import { createBrowserTools } from "agents/browser/ai";

const browserTools = createBrowserTools({
	browser: env.BROWSER,
	loader: env.LOADER,
});

Chcete-li se místo bindingu Browser Run připojit k vlastnímu CDP koncovému bodu, předejte cdpUrl.

3. Použijte se streamText

Předejte nástroje prohlížeče spolu s ostatními nástroji. model může být libovolný poskytovatel AI SDK, v tomto případě Workers AI:

import { streamText } from "ai";
import { createWorkersAI } from "workers-ai-provider";

const workersai = createWorkersAI({ binding: env.AI });

const result = streamText({
	model: workersai("@cf/zai-org/glm-4.7-flash"),
	system: "You are a helpful assistant that can inspect web pages.",
	messages,
	tools: {
		...browserTools,
		...otherTools,
	},
});
import { streamText } from "ai";
import { createWorkersAI } from "workers-ai-provider";

const workersai = createWorkersAI({ binding: env.AI });

const result = streamText({
	model: workersai("@cf/zai-org/glm-4.7-flash"),
	system: "You are a helpful assistant that can inspect web pages.",
	messages,
	tools: {
		...browserTools,
		...otherTools,
	},
});

Oba nástroje přijímají code parametr obsahující asynchronní arrow funkci JavaScriptu. Sandbox vkládá globální proměnné podle nástroje, spec pro browser_search a cdp pro browser_execute.

Když LLM použije browser_search, kód dotazuje specifikaci CDP přes vložené spec objekt:

async () => {
	const s = await spec.get();
	return s.domains
		.find((d) => d.name === "Network")
		.commands.map((c) => ({ method: c.method, description: c.description }));
};

Když LLM použije browser_execute, kód spouští příkazy CDP přes vložené cdp pomocná funkce:

async () => {
	const { targetId } = await cdp.send("Target.createTarget", {
		url: "https://example.com",
	});
	const sessionId = await cdp.attachToTarget(targetId);
	const { root } = await cdp.send("DOM.getDocument", {}, { sessionId });
	const { outerHTML } = await cdp.send(
		"DOM.getOuterHTML",
		{ nodeId: root.nodeId },
		{ sessionId },
	);
	await cdp.send("Target.closeTarget", { targetId });
	return outerHTML;
};

Použití s Agentem

Typický vzor spočívá ve vytvoření nástrojů prohlížeče uvnitř AIChatAgent handler zpráv, který zajišťuje perzistenci zpráv a streamování:

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

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

		const result = streamText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			system: "You can browse the web and inspect pages.",
			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 { createWorkersAI } from "workers-ai-provider";
import { streamText, convertToModelMessages, stepCountIs } from "ai";

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

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

		return result.toUIMessageStreamResponse();
	}
}

TanStack AI

Pro TanStack AI použijte /tanstack-ai export:

import { createBrowserTools } from "agents/browser/tanstack-ai";
import { chat, workersAIText } from "@tanstack/ai";

const browserTools = createBrowserTools({
	browser: env.BROWSER,
	loader: env.LOADER,
});

const stream = chat({
	adapter: workersAIText(env.AI, "@cf/zai-org/glm-4.7-flash"),
	tools: [...browserTools, ...otherTools],
	messages,
});
import { createBrowserTools } from "agents/browser/tanstack-ai";
import { chat, workersAIText } from "@tanstack/ai";

const browserTools = createBrowserTools({
	browser: env.BROWSER,
	loader: env.LOADER,
});

const stream = chat({
	adapter: workersAIText(env.AI, "@cf/zai-org/glm-4.7-flash"),
	tools: [...browserTools, ...otherTools],
	messages,
});

Model spuštění

Pomocné API CDP

Uvnitř browser_execute, kódu v sandboxu jsou k dispozici následující funkce.

cdp.send(method, params?, options?)

Odešlete příkaz CDP a počkejte na odpověď.

Parametr Typ Popis
method string Metoda CDP, například "DOM.getDocument" nebo "Network.enable"
params unknown Parametry metody
options.timeoutMs number Časový limit na příkaz (výchozí: 10 sekund)
options.sessionId string ID cílové relace (vyžadováno pro příkazy s rozsahem stránky)

cdp.attachToTarget(targetId, options?)

Připojí se k cíli a získá ID relace. Používá Target.attachToTarget hodnotou flatten: true.

Parametr Typ Popis
targetId string Cíl, ke kterému se má připojit
options.timeoutMs number Časový limit pro příkaz attach

Vrací sessionId řetězec.

cdp.getDebugLog(limit?)

Získat nedávné položky ladicího protokolu CDP (odesílání, přijímání, chyby). Výchozí hodnota je posledních 50 položek, maximálně 400.

cdp.clearDebugLog()

Vymazat vyrovnávací paměť ladicího logu.

Konfigurace

createBrowserTools(options)

Vrací nástroje AI SDK (browser_search a browser_execute).

Možnost Typ Výchozí Popis
browser Fetcher , Vazba Browser Run
cdpUrl string , Volitelné přepsání vlastního CDP endpointu
cdpHeaders Record<string, string> , Hlavičky pro zjišťování URL CDP (například Cloudflare Access)
loader WorkerLoader povinné Vazba Worker Loader pro spouštění v sandboxu
timeout number 30000 Časový limit spuštění v milisekundách

Buď browser nebo cdpUrl musí být zadán. Pokud jsou zadány oba, cdpUrl má přednost.

Surový přístup

Pro vlastní integrace importujte stavební bloky přímo:

import {
	CdpSession,
	connectBrowser,
	connectUrl,
	createBrowserToolHandlers,
} from "agents/browser";

// Connect to a custom CDP endpoint
const session = await connectUrl("http://localhost:9222");
const version = await session.send("Browser.getVersion");
session.close();
import {
	CdpSession,
	connectBrowser,
	connectUrl,
	createBrowserToolHandlers,
} from "agents/browser";

// Connect to a custom CDP endpoint
const session = await connectUrl("http://localhost:9222");
const version = await session.send("Browser.getVersion");
session.close();

Lokální vývoj

Nedávná vydání Wrangleru podporují Browser Run v místním vývoji. npx wrangler dev automaticky zajistí prohlížeč, takže stejný browser: env.BROWSER nastavení funguje lokálně i po nasazení.

Použijte cdpUrl pouze tehdy, když se záměrně chcete připojit k jinému endpointu prohlížeče kompatibilnímu s CDP, například k tunelu nebo ručně spravované instanci Chromu.

Bezpečnostní aspekty

Aktuální omezení


Přímé používání Puppeteer

Pokud chcete prohlížeč ovládat programově bez kódu generovaného LLM, můžete použít Puppeteer s Browser Run API přímo.

npm i -D @cloudflare/puppeteer
import puppeteer from "@cloudflare/puppeteer";

export class MyAgent extends Agent {
	async browse(browserInstance, urls) {
		let responses = [];
		for (const url of urls) {
			const browser = await puppeteer.launch(browserInstance);
			const page = await browser.newPage();
			await page.goto(url);

			await page.waitForSelector("body");
			const bodyContent = await page.$eval(
				"body",
				(element) => element.innerHTML,
			);

			let resp = await this.env.AI.run("@cf/zai-org/glm-4.7-flash", {
				messages: [
					{
						role: "user",
						content: `Return a JSON object with the product names, prices and URLs from the website content below. <content>${bodyContent}</content>`,
					},
				],
			});

			responses.push(resp);
			await browser.close();
		}

		return responses;
	}
}
import puppeteer from "@cloudflare/puppeteer";

interface Env {
	BROWSER: Fetcher;
	AI: Ai;
}

export class MyAgent extends Agent<Env> {
	async browse(browserInstance: Fetcher, urls: string[]) {
		let responses = [];
		for (const url of urls) {
			const browser = await puppeteer.launch(browserInstance);
			const page = await browser.newPage();
			await page.goto(url);

			await page.waitForSelector("body");
			const bodyContent = await page.$eval(
				"body",
				(element) => element.innerHTML,
			);

			let resp = await this.env.AI.run("@cf/zai-org/glm-4.7-flash", {
				messages: [
					{
						role: "user",
						content: `Return a JSON object with the product names, prices and URLs from the website content below. <content>${bodyContent}</content>`,
					},
				],
			});

			responses.push(resp);
			await browser.close();
		}

		return responses;
	}
}

Přidejte vazbu prohlížeče do konfigurace wrangler:

{
	"ai": {
		"binding": "AI",
	},
	"browser": {
		"binding": "BROWSER",
	},
}
[ai]
binding = "AI"

[browser]
binding = "BROWSER"

Používání Browserbase

Můžete také použít Browserbase ↗ pomocí Browserbase API přímo ve svém Agentu.

Jakmile máte svůj API klíč Browserbase ↗, můžete ho přidat do svého Agenta vytvořením secret:

cd your-agent-project-folder
npx wrangler@latest secret put BROWSERBASE_API_KEY

Nainstalujte @cloudflare/puppeteer balíček a použijte jej uvnitř svého Agenta k volání Browserbase API:

npm i @cloudflare/puppeteer
import puppeteer from "@cloudflare/puppeteer";

export class MyAgent extends Agent {
	async browse(url) {
		const browser = await puppeteer.connect({
			browserWSEndpoint: `wss://connect.browserbase.com?apiKey=${this.env.BROWSERBASE_API_KEY}`,
		});
		const page = await browser.newPage();
		await page.goto(url);
		const content = await page.content();
		await browser.close();
		return content;
	}
}
import puppeteer from "@cloudflare/puppeteer";

interface Env {
	BROWSERBASE_API_KEY: string;
}

export class MyAgent extends Agent<Env> {
	async browse(url: string) {
		const browser = await puppeteer.connect({
			browserWSEndpoint: `wss://connect.browserbase.com?apiKey=${this.env.BROWSERBASE_API_KEY}`,
		});
		const page = await browser.newPage();
		await page.goto(url);
		const content = await page.content();
		await browser.close();
		return content;
	}
}