Next.js + Vercel#

使用 Vercel Sandbox 在 Vercel 上的 Next.js 应用中运行 agent-browser。系统会按需启动一个 Linux microVM,运行 agent-browser + Chrome,然后自动关闭。没有二进制大小限制,也不需要处理 Chromium 打包复杂度。

设置#

bash
pnpm add @agent-browser/sandbox @vercel/sandbox

服务端动作#

Vercel Sandbox 运行在 Amazon Linux 上。Chromium 需要默认未安装的系统库,所以全新的沙箱在 agent-browser 启动 Chrome 之前需要先执行 dnf install。在生产环境中,可以使用下面的 sandbox snapshot 完全跳过这一步。@agent-browser/sandbox helper 默认会安装这些系统依赖并处理命令执行。

ts
"use server";
import { runAgentBrowserCommand, withAgentBrowserSandbox } from "@agent-browser/sandbox/vercel";

export async function screenshotUrl(url: string) {
  return withAgentBrowserSandbox(async (sandbox) => {
    await runAgentBrowserCommand(sandbox, ["open", url]);

    const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
      "screenshot",
    ]);
    const ssPath = ssResult.json?.data?.path;
    if (!ssPath) throw new Error("Screenshot did not return a file path.");

    const b64Result = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
    const screenshot = (await b64Result.stdout()).trim();
    await runAgentBrowserCommand(sandbox, ["close"], { json: false });
    return { ok: true, screenshot };
  });
}

export async function snapshotUrl(url: string) {
  return withAgentBrowserSandbox(async (sandbox) => {
    await runAgentBrowserCommand(sandbox, ["open", url]);

    const result = await runAgentBrowserCommand(sandbox, ["snapshot", "-i", "-c"], {
      json: false,
    });

    await runAgentBrowserCommand(sandbox, ["close"], { json: false });
    return { ok: true, snapshot: result.stdout };
  });
}

Sandbox 快照#

如果不做优化,每次 Sandbox 运行都会从零安装系统依赖、agent-browser 和 Chromium(约 30 秒)。sandbox snapshot 是一个已保存的虚拟机镜像,里面预装了所有内容,类似于 Vercel Sandbox 的 Docker 镜像。当设置了 AGENT_BROWSER_SNAPSHOT_ID 时,沙箱会从该镜像启动,而不是重新安装,从而把启动时间降到亚秒级。

这和 agent-browser 的 accessibility snapshot 不同,后者会导出页面的可访问性树。Sandbox snapshot 是 Vercel 基础设施层的概念。

运行一次辅助脚本来创建 sandbox snapshot:

bash
npx tsx scripts/create-snapshot.ts

脚本会启动一个全新的沙箱、安装系统依赖、agent-browser 和 Chromium、保存虚拟机状态,并打印 snapshot ID:

bash
AGENT_BROWSER_SNAPSHOT_ID=snap_xxxxxxxxxxxx

将其添加到 Vercel 项目的环境变量中(本地开发则放到 .env.local)。建议所有生产部署都这样做。

认证#

在 Vercel 部署中,Sandbox SDK 会通过 OIDC 自动认证。对于本地开发,请提供显式凭据:

变量描述
VERCEL_TOKENVercel 个人访问令牌
VERCEL_TEAM_IDVercel 团队 ID
VERCEL_PROJECT_IDVercel 项目 ID

当这三个都设置后,它们会被传给 Sandbox.create()。如果没有设置,SDK 会回退到 VERCEL_OIDC_TOKEN(在 Vercel 上会自动提供)。

定时工作流(cron)#

对于每日监控这类周期性任务,请使用 Vercel Cron Jobs:

ts
// app/api/cron/monitor/route.ts
import { runAgentBrowserCommand, withAgentBrowserSandbox } from "@agent-browser/sandbox/vercel";

export async function GET() {
  const result = await withAgentBrowserSandbox(async (sandbox) => {
    await runAgentBrowserCommand(sandbox, [
      "open", "https://example.com/pricing",
    ]);
    const snap = await runAgentBrowserCommand(sandbox, [
      "snapshot", "-i", "-c",
    ], { json: false });
    await runAgentBrowserCommand(sandbox, ["close"], { json: false });
    return snap.stdout;
  });

  // 处理结果、发送告警、存储数据...
  return Response.json({ ok: true, snapshot: result });
}
json
// vercel.json
{
  "crons": [
    { "path": "/api/cron/monitor", "schedule": "0 9 * * *" }
  ]
}

环境变量#

变量描述
AGENT_BROWSER_SNAPSHOT_ID用于亚秒级启动的 Sandbox snapshot ID(见上文)
VERCEL_TOKENVercel 个人访问令牌(本地开发使用;在 Vercel 上会自动使用 OIDC)
VERCEL_TEAM_IDVercel 团队 ID(本地开发使用)
VERCEL_PROJECT_IDVercel 项目 ID(本地开发使用)

演示应用#

一个可工作的演示位于 examples/environments/,包含流式进度 UI、速率限制和一键部署到 Vercel 按钮。