使用 Computer Use Sandbox

更新时间:
复制 MD 格式

Computer Use Sandbox 面向需要“看屏幕、动鼠标、敲键盘”的 Agent。它在云沙箱中运行完整的 Linux 桌面环境,Agent 通过截图感知界面,通过鼠标、键盘操作浏览器、文件管理器、编辑器和终端等 GUI 应用,并可实时查看执行过程。

如果任务只需要访问网页、点击、填表、截图或抓取动态页面,优先使用 Browser Use Sandbox,通过 CDP 精确控制浏览器。只有当任务必须操作浏览器以外的桌面应用,或必须以“像素坐标 + 截图”的视觉方式驱动界面时,才选择 Computer Use Sandbox。

适用场景

场景说明
视觉驱动的 Computer Use Agent让视觉大模型基于截图输出鼠标坐标和键盘动作,闭环操作桌面
桌面软件自动化驱动浏览器以外的 GUI 应用,如编辑器、办公软件、桌面客户端
端到端 GUI 测试在隔离桌面中回归验证图形界面,避免污染本地或 CI 环境
演示与远程观察通过实时流查看 Agent 的每一步操作,便于演示、调试和审计

与 Browser Use Sandbox 的区别

对比项Computer Use SandboxBrowser Use Sandbox
环境形态完整 Linux 桌面无桌面,仅浏览器实例
操作对象任意桌面 GUI 应用仅浏览器页面
控制方式截图 + 鼠标坐标 + 键盘CDP over WebSocket
SDKe2b-desktop / @e2b/desktope2b / @e2b/code-interpreter + Puppeteer/Playwright
实时查看SDK 内置实时流browser 模板提供实时查看入口
适合任务桌面级、视觉级操作网页采集、表单和轻量 E2E

准备工作

  1. 按照 Desktop 模板示例 构建模板,例如 my-desktop-template

  2. 配置与模板同地域的 E2B_API_KEYE2B_API_URLE2B_DOMAIN

  3. 安装对应语言的 Desktop SDK。

Pythone2b-desktop 2.4.1):

uv venv .venv --python 3.12
source .venv/bin/activate
uv pip install e2b-desktop==2.4.1 python-dotenv

Node.js@e2b/desktop 2.3.1):

{
  "name": "computer-use-sandbox-demo",
  "version": "1.0.0",
  "type": "module",
  "dependencies": {
    "@e2b/desktop": "2.3.1",
    "dotenv": "^17.2.3"
  },
  "devDependencies": {
    "tsx": "^4.23.1"
  }
}
说明

密钥应放在 .env 并通过 .gitignore 排除,不要提交到版本库。SDK 会自动读取连接环境变量,无需在方法调用中显式传入。

Python 示例

以下示例创建桌面沙箱,启动 Chrome,完成截图和鼠标键盘操作,并开启带鉴权的实时流。

"""Computer Use Sandbox 示例。"""

import os

from dotenv import load_dotenv
from e2b_desktop import Sandbox

load_dotenv()

TEMPLATE = os.environ.get("E2B_DESKTOP_TEMPLATE", "my-desktop-template")

desktop = None
try:
    # timeout 单位为秒,需覆盖桌面冷启动与任务全过程。
    desktop = Sandbox.create(template=TEMPLATE, timeout=600)

    # 启动 Chrome,并等待窗口渲染完成;wait 单位为毫秒。
    desktop.launch("google-chrome", "https://example.com")
    desktop.wait(10000)

    # 鼠标操作。
    desktop.move_mouse(640, 400)
    desktop.left_click()
    desktop.double_click()
    desktop.scroll("down", 5)

    # 在终端中输入命令,验证键盘和组合键操作。
    desktop.launch("xfce4-terminal")
    desktop.wait(3000)
    desktop.write("computer use")
    desktop.press(["ctrl", "a"])
    desktop.write("echo ")
    desktop.press("enter")
    desktop.wait(1000)

    # 截图返回 PNG 字节,可交给视觉模型或保存到文件。
    image = desktop.screenshot()
    with open("desktop.png", "wb") as f:
        f.write(image)

    # 开启带 VNC 口令的实时流。
    desktop.stream.start(require_auth=True)
    auth_key = desktop.stream.get_auth_key()
    stream_url = desktop.stream.get_url(auth_key=auth_key)
    # 将 stream_url 交给受控后端使用,不要写入公开日志。

    # 在此执行 Agent 的“截图 -> 决策 -> 操作”循环。

    desktop.stream.stop()
finally:
    if desktop is not None:
        desktop.kill()

TypeScript 示例

将以下代码保存为 computer-use.ts

import "dotenv/config";
import { writeFileSync } from "node:fs";
import { Sandbox } from "@e2b/desktop";

const TEMPLATE = process.env.E2B_DESKTOP_TEMPLATE ?? "my-desktop-template";

let desktop: Sandbox | undefined;
try {
  // timeoutMs 单位为毫秒,需覆盖桌面冷启动与任务全过程。
  desktop = await Sandbox.create(TEMPLATE, { timeoutMs: 600_000 });

  await desktop.launch("google-chrome", "https://example.com");
  // 等待应用窗口渲染完成,避免截到尚未加载的桌面。
  await desktop.wait(10_000);

  await desktop.moveMouse(640, 400);
  await desktop.leftClick();
  await desktop.doubleClick();
  await desktop.scroll("down", 5);

  await desktop.launch("xfce4-terminal");
  await desktop.wait(3_000);
  await desktop.write("computer use");
  await desktop.press(["ctrl", "a"]);
  await desktop.write("echo ");
  await desktop.press("enter");
  await desktop.wait(1_000);

  const image = await desktop.screenshot();
  writeFileSync("desktop.png", image);

  await desktop.stream.start({ requireAuth: true });
  const authKey = desktop.stream.getAuthKey();
  const streamUrl = desktop.stream.getUrl({ authKey });
  // 将 streamUrl 交给受控后端使用,不要写入公开日志。

  // 在此执行 Agent 的“截图 -> 决策 -> 操作”循环。

  await desktop.stream.stop();
} finally {
  await desktop?.kill();
}

运行示例:

npm install
npx tsx computer-use.ts

常用能力速查

能力PythonTypeScript
创建沙箱Sandbox.create(template=..., timeout=...)Sandbox.create(template, { timeoutMs })
启动应用desktop.launch("google-chrome", url)desktop.launch("google-chrome", url)
等待desktop.wait(10000)desktop.wait(10000)
截图desktop.screenshot()desktop.screenshot()
移动鼠标desktop.move_mouse(x, y)desktop.moveMouse(x, y)
单击 / 双击 / 右键left_click() / double_click() / right_click()leftClick() / doubleClick() / rightClick()
滚动desktop.scroll("down", amount)desktop.scroll("down", amount)
拖拽desktop.drag((x1, y1), (x2, y2))desktop.drag([x1, y1], [x2, y2])
输入文本desktop.write("...")desktop.write("...")
按键 / 组合键press("enter") / press(["ctrl", "c"])press("enter") / press(["ctrl", "c"])
当前窗口 IDdesktop.get_current_window_id()desktop.getCurrentWindowId()
开启 / 停止实时流stream.start() / stream.stop()stream.start() / stream.stop()
获取流地址stream.get_url(auth_key=...)stream.getUrl({ authKey })
销毁沙箱desktop.kill()desktop.kill()

实时流与鉴权

  • stream.start(require_auth=True) / stream.start({ requireAuth: true }) 会为 VNC 流生成访问口令。

  • get_auth_key() / getAuthKey() 必须在启用 require_auth / requireAuth 后调用,否则 SDK 会抛出错误。

  • stream.get_url() 返回 noVNC 地址。只读观察可使用 Python view_only=True 或 TypeScript viewOnly: true

  • 同一时刻只能开启一个流。0.0.37 版本支持整桌面流,暂不支持指定单个窗口。

通过函数计算公网网关访问 /vnc.html/websockify 时,还需要沙箱的 X-Access-Tokenrequire_auth 生成的 auth_key 是 VNC 流自身的访问口令,两者是独立的两层鉴权。普通浏览器无法为页面和 WebSocket 任意附加请求头,面向最终用户提供实时查看时,建议由业务后端通过受控反向代理注入 X-Access-Token,不要把沙箱 Token 暴露到前端或公开日志。

安全与上线建议

  • 凭证隔离:模型 Key、账号密码和业务 Token 通过运行时环境变量注入,不要写入模板镜像。

  • 流访问控制:实时流开启 require_auth,只读演示场景使用 view_only,不要把带口令的 URL 写入公开日志。

  • 防提示注入:不要让 Agent 未经校验地把屏幕文字当作系统指令执行;提交、删除、支付等敏感操作应设置人工确认。

  • 资源与生命周期:为任务设置合理超时,并始终在 finally 中调用 kill()

  • 动作审计:记录必要的截图、鼠标坐标、按键序列和目标窗口,便于复现与追踪。

  • 最小权限:限制沙箱可访问的域名、可启动的应用和可写目录。

相关文档