模型 / 数据集
e2b-dev/desktop avatar
e2b-dev/desktop

e2b-dev/desktop:给 LLM 一个可被鼠标键盘操作的隔离桌面

E2B Desktop Sandbox for LLMs. E2B Sandbox with desktop graphical environment that you can connect to any LLM for secure computer use.

1,485 个 Star183 个 ForkPythonApache-2.0

秒懂

它是什么?
这个仓库提供的是 E2B 的桌面沙箱模板与示例,SDK 源码已迁至 E2B 主仓库。它解决的是「让模型看到屏幕并操作图形界面」这件事,代价是必须依赖 E2B 的托管 API 与 API Key。
适合谁用?
适合已经在用 E2B Sandbox、需要给模型一个能点鼠标、能看屏幕的图形环境做原型验证的团队,尤其是想跑 open-computer-use 或 Surf 这类示例的人。不适合想要纯本地、无外部服务依赖,或需要同时串流多个窗口的场景,因为 README 明确写了同一时间只能有一个流。
能商用吗?
可以。Apache-2.0 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
还在维护吗?
在维护。仓库最近一次提交在 2 天前。
用什么语言写的?
主要是 Python(依据 GitHub 的语言统计)。

以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。

开源项目深度解析

它要解决的不是「模型会不会用电脑」,而是「模型在哪台电脑上试错」

让模型操作图形界面,最麻烦的部分从来不是推理,而是执行环境。模型点错一个按钮,可能删掉真实用户的文件;模型打开一个恶意网页,可能把宿主机的凭据读走。E2B Desktop Sandbox 针对的正是这一段:README 把它描述为「open source secure virtual desktop ready for Computer Use」,每个 sandbox 之间相互隔离,并且可以按需安装任意依赖。

目标读者很明确:正在做 computer use 类 agent 的开发者。仓库里给出的两个下游项目能说明定位,open-computer-use 是「100% open source LLMs」的实现,Surf 是一个基于 E2B Desktop Sandbox 的 OpenAI Computer Use Agent,跑在 Next.js 上。也就是说,这个仓库本身不打算做完整的 agent,它提供的是被 agent 操作的那一层,包括屏幕串流、鼠标键盘原语和窗口枚举。

一个需要先说清楚的事实:README 顶部的提示写明,@e2b/desktop 和 e2b-desktop 的 SDK 源码已经迁到 E2B 主仓库的 packages/desktop-js 与 packages/desktop-python 下,本仓库保留的是 sandbox 模板和示例。所以如果你要提 SDK 的 issue 或 PR,去的是另一个仓库。这一点会直接影响你评估维护活跃度时的判断对象。

从 Sandbox.create 到 stream.start:一次会话的完整数据流

整个机制可以按 README 的示例顺序拆开。第一步是 Sandbox.create(),得到一个隔离的桌面环境;第二步是 desktop.launch('google-chrome'),README 注明也可以是 vscode、firefox 等;第三步是 desktop.wait(10000),示例里的注释直接写着「Wait 10s for the application to open」。这三步的顺序不是装饰,因为后面的串流对时序敏感。

串流是核心。desktop.stream.start() 可以不带参数,此时串流整个桌面;也可以传 window_id,此时只串流某个窗口。窗口 ID 有两个来源,desktop.get_current_window_id() 拿当前活动窗口,desktop.get_application_windows("Firefox") 拿某个应用的所有窗口并返回一个列表。串流地址通过 desktop.stream.get_url() 得到,如果 start 时带了 require_auth=True,还需要先取 desktop.stream.get_auth_key(),再把 auth_key 传给 get_url。get_url(view_only=True) 会关闭用户交互,README 的说法是「disable user interaction」。

控制层是一组坐标级原语,不是语义级操作。README 列出的包括 double_click、left_click、right_click、middle_click,其中后两者可以带 x、y 坐标;scroll(10) 正数向上、负数向下;move_mouse(100, 200) 移动到坐标;drag((100, 100), (200, 200)) 拖拽;以及 mouse_press("left") 与 mouse_release("left") 这一对底层按下与释放。这套 API 的粒度意味着,模型必须自己从屏幕内容推断该点哪里,SDK 不替它做元素识别。

安装与最小可运行代码:两个包名,一个环境变量

前置条件是 E2B 的 API Key。README 让你在 E2B 注册后拿到 key,并设置环境变量 E2B_API_KEY。这个 key 是整套东西的入口,没有它 Sandbox.create() 无从谈起。

Python 侧安装命令是 pip install e2b-desktop,导入路径是 e2b_desktop,即 from e2b_desktop import Sandbox。JavaScript 侧是 npm install @e2b/desktop,导入语句是 import { Sandbox } from '@e2b/desktop'。注意 Python 的包名 e2b-desktop 与导入名 e2b_desktop 之间的下划线与连字符差异,这是常见的踩坑点。

最小的串流流程在 README 里写得很直白:create、launch、wait、stream.start、stream.get_auth_key、stream.get_url,最后在任务结束时不忘记 desktop.kill()(示例里这一行是注释掉的,说明它由使用者决定何时执行)。JavaScript 版本多了一层 await,因为 launch、wait、stream.start、getCurrentWindowId 都是异步的。如果你只想要一个能看的画面,可以跳过 require_auth,直接 desktop.stream.start() 加 desktop.stream.get_url();但一旦这个 URL 会离开你的机器,就该把 require_auth=True 加上。

同一时间只有一个流,这是设计约束而不是配置项

README 在示例代码里用注释强调了一次,在「Streaming specific application」小节又用警告框强调了一次:Creating multiple streams at the same time is not supported。想切换串流对象,必须先 stop 当前流再起新的。这一条会改变你的架构,如果你打算做多窗口并列的监控面板,这个 SDK 直接不支持,你得在客户端自己把多个 sandbox 的画面拼起来,而不是在一个 sandbox 里开多个流。

第二个失败模式同样写在警告框里:串流一个指定 window_id 的应用时,如果该应用还没打开,会直接抛错;并且应用一旦关闭,流也会随之关闭。这把 launch、wait 的时序问题从「体验问题」升级成了「错误处理问题」。示例里 wait(10000) 这个十秒是硬编码的,README 没有说明如何判断应用真正就绪,所以更稳妥的做法是用 get_application_windows 轮询确认窗口出现,再调 stream.start。

第三点是认证的默认值。require_auth 不是默认开启的,README 的「Streaming desktop's screen」示例里就是无认证的 stream.start()。串流 URL 一旦泄露,等于把整个桌面交出去。这一点在文档里没有被特别强调,但它是这套 API 里风险最集中的地方。

和直接用 E2B Sandbox 的差别在哪

最直接的替代方案是 E2B Sandbox 本身。README 第一句就说明,Desktop Sandbox 是「built on top of E2B Sandbox」。两者的区别在于抽象层:普通 E2B Sandbox 面向的是代码执行,你给它一段程序,它给你输出;Desktop Sandbox 面向的是图形界面,你给它坐标和按键,它给你一块屏幕。如果你的 agent 只需要跑脚本、读写文件、调 API,用普通 Sandbox 更省事,也不需要处理串流和窗口 ID 这些概念。

另一个方向是自建虚拟机加 VNC 或类似方案。区别在于控制粒度:自建方案通常给你一个完整的远程桌面协议,你能拿到剪贴板、文件传输、多显示器,但要让模型驱动它,你还得自己写一层把「点击坐标」映射到协议调用的胶水代码。E2B Desktop Sandbox 把这层胶水做成了 left_click(x=100, y=200) 这样的方法,代价是它只暴露了 README 列出的那些原语,键盘输入在给出的片段里没有出现完整的 API 示例,README 在 JavaScript 鼠标控制部分被截断,所以这部分能力需要你自己去 SDK 文档里确认。

还有一条路是用 open-computer-use 或 Surf 这样的现成项目。它们是这个仓库的下游,README 用链接的方式列出。如果你要的是能直接跑的 agent,从这两个入手比自己从 SDK 拼更快;如果你要的是理解底层怎么工作,或者要接自己的模型,那还是回到 SDK。

维护成本与许可:SDK 在别处,模板在这里

维护成本要分两块看。SDK 那块已经不在这个仓库了,README 明确指向 E2B 主仓库的 packages/desktop-js 和 packages/desktop-python。这意味着你在这个仓库里看到的问题列表和提交历史,反映的是模板和示例的状态,不是 SDK 的状态。评估长期维护时,把两个仓库分开看,别把模板仓库的动静当成 SDK 的动静。

版本号的形态也值得注意。最近发布记录里同时存在 @e2b/desktop-python@2.4.2、@e2b/desktop@2.3.1 和 @e2b/desktop-python@2.4.1,Python 包和 JS 包的版本并不对齐,而且 2026-06-08 那天两个包同时发版,说明它们有协同发布的习惯但版本号独立演进。跨语言维护同一套 agent 逻辑时,这会造成 API 表面上的细微差异,比如 Python 的 get_current_window_id 对应 JS 的 getCurrentWindowId,命名风格不同,参数形态也不同(Python 用 window_id=,JS 用 { windowId })。

许可证是 Apache-2.0,允许商用与修改,需要保留版权与许可声明,具体条款以仓库里的 LICENSE 文件为准,这里不构成法律意见。真正需要留意的是服务侧:SDK 是开源的,但 Sandbox.create() 走的是 E2B 的托管服务,需要 API Key,运行成本与可用性取决于 E2B 的服务条款和定价,这部分不在 Apache-2.0 的覆盖范围内。如果你的场景要求完全自托管,需要先确认 E2B 是否提供对应的部署方式,README 没有给出这方面的说明。

上手前该验证的三件事

第一,确认你的目标应用能在沙箱里被 launch 并稳定出现在 get_application_windows 的返回列表里。README 的警告说得很清楚,串流未打开的窗口会报错,而示例里的 wait(10000) 只是一个固定等待,不保证成功。拿一个你真正要操作的应用跑一遍这个序列,比读文档更能说明问题。

第二,确认单流限制对你的产品形态是否致命。如果你的界面需要同时展示两个应用的画面,或者需要在任务中途切换观察对象,你必须把 stop 与 start 的切换逻辑写进状态机,并且接受切换期间画面会中断。这一点没有绕过的办法,它是 README 写明的限制。

第三,确认认证策略。如果串流 URL 会经过浏览器、日志或第三方前端,require_auth=True 配合 get_auth_key() 应该是默认选择,而不是可选项。README 的无认证示例适合本地调试,不适合放到任何能被外部访问的位置。另外,键盘输入相关的 API 在给出的 README 片段里没有完整出现,如果你的任务需要大量文本输入,先去 SDK 文档确认这块的接口再决定是否采用。

编辑结论

适合已经在用 E2B Sandbox、需要给模型一个能点鼠标、能看屏幕的图形环境做原型验证的团队,尤其是想跑 open-computer-use 或 Surf 这类示例的人。不适合想要纯本地、无外部服务依赖,或需要同时串流多个窗口的场景,因为 README 明确写了同一时间只能有一个流。上手前先确认三件事:E2B_API_KEY 是否可用、e2b-desktop 的 Python 包与 @e2b/desktop 的 JS 包版本是否对得上,以及你的目标应用是否能在 launch 之后稳定出现在 get_application_windows 的返回值里,因为串流一个尚未打开的窗口会直接报错。

官方来源

  1. e2b-dev/desktop on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
社区笔记

社区笔记