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 Sandbox | Browser Use Sandbox |
| 环境形态 | 完整 Linux 桌面 | 无桌面,仅浏览器实例 |
| 操作对象 | 任意桌面 GUI 应用 | 仅浏览器页面 |
| 控制方式 | 截图 + 鼠标坐标 + 键盘 | CDP over WebSocket |
| SDK | e2b-desktop / @e2b/desktop | e2b / @e2b/code-interpreter + Puppeteer/Playwright |
| 实时查看 | SDK 内置实时流 | browser 模板提供实时查看入口 |
| 适合任务 | 桌面级、视觉级操作 | 网页采集、表单和轻量 E2E |
准备工作
按照 Desktop 模板示例 构建模板,例如
my-desktop-template。配置与模板同地域的
E2B_API_KEY、E2B_API_URL和E2B_DOMAIN。安装对应语言的 Desktop SDK。
Python(e2b-desktop 2.4.1):
uv venv .venv --python 3.12
source .venv/bin/activate
uv pip install e2b-desktop==2.4.1 python-dotenvNode.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常用能力速查
| 能力 | Python | TypeScript |
| 创建沙箱 | 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"]) |
| 当前窗口 ID | desktop.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 地址。只读观察可使用 Pythonview_only=True或 TypeScriptviewOnly: true。同一时刻只能开启一个流。0.0.37 版本支持整桌面流,暂不支持指定单个窗口。
通过函数计算公网网关访问 /vnc.html 和 /websockify 时,还需要沙箱的 X-Access-Token。require_auth 生成的 auth_key 是 VNC 流自身的访问口令,两者是独立的两层鉴权。普通浏览器无法为页面和 WebSocket 任意附加请求头,面向最终用户提供实时查看时,建议由业务后端通过受控反向代理注入 X-Access-Token,不要把沙箱 Token 暴露到前端或公开日志。
安全与上线建议
凭证隔离:模型 Key、账号密码和业务 Token 通过运行时环境变量注入,不要写入模板镜像。
流访问控制:实时流开启
require_auth,只读演示场景使用view_only,不要把带口令的 URL 写入公开日志。防提示注入:不要让 Agent 未经校验地把屏幕文字当作系统指令执行;提交、删除、支付等敏感操作应设置人工确认。
资源与生命周期:为任务设置合理超时,并始终在
finally中调用kill()。动作审计:记录必要的截图、鼠标坐标、按键序列和目标窗口,便于复现与追踪。
最小权限:限制沙箱可访问的域名、可启动的应用和可写目录。