AIO Sandbox 面向“浏览器自动化 + 代码执行 + 文件处理”连续发生的 Agent 任务。推荐基于 All-In-One 模板 创建沙箱:3000 端口提供 browser 服务,5000 端口提供 Code Interpreter/envd 服务。这样,Agent 可以在同一个隔离环境中完成网页访问、截图、下载、数据清洗、代码计算和结果导出。
如果任务只需要访问网页、点击按钮、截图或下载文件,优先使用 Browser Use Sandbox。只有浏览器产物需要立即交给 Python/Node.js 继续处理时,才选择 AIO Sandbox。
适用场景
| 场景 | 说明 |
| 网页采集后分析 | 通过浏览器访问动态页面,保存 HTML、截图或下载文件,再用 Python 清洗、汇总和导出 |
| 自动化测试报告 | 运行浏览器 E2E 测试后,在同一沙箱中分析日志、截图和测试结果 |
| 内容生产 Agent | 生成网页截图、PDF、表格、JSON 和归档文件 |
| 多工具 Agent | 在同一会话中组合浏览器、终端命令、Code Interpreter 和文件 API |
推荐流程
按 All-In-One 模板 构建业务模板,例如
my-all-in-one-template。使用模板创建沙箱,并设置足够的超时时间。浏览器冷启动、页面加载和代码执行会共同消耗时间。
通过
sandbox.get_host(3000)获取 browser 服务公网 host。轮询
/health,确认 browser 服务已经就绪。通过 CDP 端点连接 Playwright 或 Puppeteer,执行网页访问、交互、截图和下载。
将浏览器产物写入沙箱文件系统,再通过 Code Interpreter 或命令继续处理。
下载结果文件,记录 URL、动作摘要、截图路径、脚本版本和输出结果。
任务结束后销毁沙箱,清理临时凭证和中间文件。
准备本地环境
以下示例使用 Node.js 连接 All-In-One 沙箱中的浏览器,并在同一沙箱中执行 Python 代码。业务侧只需要安装 SDK 和 Playwright Core;浏览器运行在云沙箱内。
{
"name": "aio-sandbox-demo",
"version": "1.0.0",
"type": "module",
"dependencies": {
"@e2b/code-interpreter": "^2.6.1",
"playwright-core": "^1.49.0"
},
"devDependencies": {
"tsx": "^4.23.0",
"typescript": "^6.0.3"
}
}示例代码
示例流程如下:
创建
my-all-in-one-template沙箱。等待 browser 服务
/health返回 200。通过 CDP 连接云端浏览器,访问
https://example.com,并将截图写入沙箱任务目录。使用 Code Interpreter 读取浏览器产物,生成结构化摘要。
import { Sandbox } from "@e2b/code-interpreter";
import { chromium } from "playwright-core";
const TEMPLATE = process.env.E2B_AIO_TEMPLATE || "my-all-in-one-template";
const BROWSER_PORT = 3000;
const TARGET_URL = "https://example.com";
const TASK_DIR = "/tmp/aio-task";
const SCREENSHOT_PATH = `${TASK_DIR}/page.png`;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
function toArrayBuffer(bytes) {
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
}
async function waitUntilHealthy(sandbox, host, token, timeoutMs = 60_000) {
const tokenHeader = token ? `-H 'X-Access-Token: ${token}' ` : "";
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
let result;
try {
result = await sandbox.commands.run(
`curl -sS -o /dev/null -w '%{http_code}' -m 4 ` +
tokenHeader +
`https://${host}/health`,
{ timeoutMs: 10_000 },
);
} catch (error) {
result = error;
}
const code = (result.stdout || "").trim();
if (code === "200") {
return;
}
await sleep(2_000);
}
throw new Error(`browser 服务在 ${timeoutMs}ms 内未就绪`);
}
async function collectPage(cdpUrl, token) {
const browser = await chromium.connectOverCDP(cdpUrl, {
headers: token ? { "X-Access-Token": token } : {},
});
const contexts = browser.contexts();
const context = contexts.length ? contexts[0] : await browser.newContext();
const page = await context.newPage();
try {
await page.goto(TARGET_URL, {
waitUntil: "domcontentloaded",
timeout: 30_000,
});
const result = await page.evaluate(() => ({
url: location.href,
title: document.title,
textLength: document.body.innerText.length,
}));
const screenshot = await page.screenshot({ fullPage: true });
return { result, screenshot };
} finally {
await page.close();
await browser.close();
}
}
let sandbox;
try {
sandbox = await Sandbox.create(TEMPLATE, {
timeoutMs: 900_000,
});
const host = sandbox.getHost(BROWSER_PORT);
const token = sandbox.envdAccessToken;
const cdpUrl = `wss://${host}/ws/automation`;
await waitUntilHealthy(sandbox, host, token);
await sandbox.files.makeDir(TASK_DIR);
const { result: pageResult, screenshot } = await collectPage(cdpUrl, token);
await sandbox.files.write(SCREENSHOT_PATH, toArrayBuffer(screenshot));
const execution = await sandbox.runCode(`
import json
from pathlib import Path
page = ${JSON.stringify(JSON.stringify(pageResult))}
data = json.loads(page)
summary = {
"status": "ok",
"source": "aio-sandbox",
"title": data["title"],
"url": data["url"],
"text_length": data["textLength"],
"artifacts": [str(Path("${SCREENSHOT_PATH}"))],
}
print(json.dumps(summary, ensure_ascii=False))
`);
console.log(execution.logs.stdout);
} finally {
if (sandbox) {
await sandbox.kill();
}
}接入建议
使用固定的任务目录,例如
/tmp/aio-task/<task-id>,把截图、HTML、下载文件、脚本和结果文件放在同一目录。浏览器阶段和代码阶段分别记录输入、输出、日志和错误。排查问题时先确认是页面操作失败,还是后续脚本处理失败。
对下载文件先做类型、大小和路径校验,再交给代码阶段处理。
网页内容和下载文件都可能携带 prompt injection。不要把网页文本直接当作系统指令或高权限工具指令。
浏览器账号、Cookie、模型 Key 和业务凭证应通过运行时注入,不要写入模板镜像。
设置最大页面数、最大下载文件大小、命令超时和沙箱生命周期,避免 Agent 无限制爬取或计算。
如果需要实时观察浏览器,可使用 All-In-One 模板的
wss://<sandbox-host>/ws/livestream端点连接 noVNC。