全部產品
Search
文件中心

Function Compute:使用 AIO Sandbox

更新時間:Jul 23, 2026

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

推薦流程

  1. 按 All-In-One 模板 構建業務模板,例如 my-all-in-one-template。

  2. 使用模板建立沙箱,並設定足夠的逾時時間。瀏覽器冷啟動、頁面載入和代碼執行會共同消耗時間。

  3. 通過 sandbox.get_host(3000) 擷取 browser 服務公網 host。

  4. 輪詢 /health,確認 browser 服務已經就緒。

  5. 通過 CDP 端點串連 Playwright 或 Puppeteer,執行網頁訪問、互動、截圖和下載。

  6. 將瀏覽器產物寫入沙箱檔案系統,再通過 Code Interpreter 或命令繼續處理。

  7. 下載結果檔案,記錄 URL、動作摘要、截圖路徑、指令碼版本和輸出結果。

  8. 任務結束後銷毀沙箱,清理臨時憑證和中間檔案。

準備本地環境

以下樣本使用 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"
  }
}

範例程式碼

樣本流程如下:

  1. 建立 my-all-in-one-template 沙箱。

  2. 等待 browser 服務 /health 返回 200。

  3. 通過 CDP 串連雲端瀏覽器,訪問 https://example.com,並將截圖寫入沙箱任務目錄。

  4. 使用 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。

相關功能