1. 项目速览:一个容器装下 Agent 的全部工具链
先说结论:AIO Sandbox 是个很有意思的开源项目,它把浏览器、Shell、文件系统、MCP Server、VSCode 这些 Agent 日常要用的东西,全部塞进了一个 Docker 容器里。你通过浏览器访问这个容器,就同时拥有了一套可视化操作环境、一套命令行环境、一套文件管理环境,还有一套可以与各种 AI 模型对接的 MCP 接口。
我最初关注这个项目,是因为开发 Agent 应用时工具链太碎了。写一段需要操作浏览器的自动化脚本,要单独跑 Playwright 服务;要让模型访问本地文件,得自己写工具函数;想在容器里改代码,又得挂载一堆插件进去。如果你也遇到过这种“环境割裂”的问题——浏览器操作、Shell 命令、文件读写分属三个不同的工具,那这个项目值得你花几分钟看看。
它适合三类人:一类是做 Agent 开发、想快速搭一套标准化运行环境的;一类是研究 MCP 协议接入、想找一个现成 Server 做测试的;还有一类就是单纯想把“浏览器 + 终端 + 编辑器”整合到一个容器里,做远程开发或在线实验平台的。
我先简单说下它的核心能力,再展开讲实现细节和实操经验。整个项目本质上是把几类成熟工具用容器编排的方式粘合在一起,但这层“粘合”做得是否顺手,直接决定了你实际使用时的体验。
2. 为什么需要“All in One”的 Agent 沙箱
2.1 传统 Agent 开发环境的三个痛点
我在实际开发 Agent 应用时,最头疼的从来不是模型能力,而是环境。模型要执行一个任务,可能需要同时调用浏览器、执行脚本、读取文件,传统做法是分别起服务再手动拼装。
第一个痛点是服务太多。跑一个带浏览器操作能力的 Agent,至少需要浏览器自动化服务、后端逻辑服务、工具调用服务三个进程,每个都要单独配置、单独维护,一旦某个服务崩了,整个链路就要排查半天。
第二个痛点是权限和隔离不好控制。如果 Agent 要执行 Shell 命令,你总不能让它在宿主机上乱跑吧?出了事怎么界定责任?但放在容器里就清晰多了——给它一个单独的容器,再怎么折腾也不会影响宿主机。这也是“沙箱”这个概念的原始需求。
第三个痛点是联调效率低。Agent 需要与人协作时会变得很复杂——比如我写了一个需要视觉验证的爬虫,Agent 操作浏览器时要能看到当前的页面状态,而不仅仅是拿 DOM 文本。传统方案里,要么自己搭个截图回传机制,要么用人机交互工具人工介入,都很别扭。
2.2 AIO Sandbox 的整合思路
AIO Sandbox 的思路很直接:既然 Agent 环境要的这几样东西都是成熟工具,为什么不直接把它们装进同一个容器,然后用一套身份认证、一套端口管理体系串起来?
它选择的组件组合是:容器里跑一个 Chromium 浏览器实例,通过 CDP 协议对外暴露控制能力;跑一个 Shell 环境,通过 WebSocket 提供交互式终端;跑一个文件管理器,通过 HTTP 接口访问容器内目录;跑一个 MCP Server,用于向 AI 模型暴露上述工具的标准化接口;再跑一个 VSCode Web,提供在线代码编辑能力。
这套组合的价值不在于每个组件本身有多新,而在于它们被放在了同一个网络命名空间和进程生命周期里。Agent 调用浏览器打开一个页面,同时用 Shell 执行一条命令,这两个操作之间没有任何网络延迟和跨容器通信的障碍。对于需要高频工具切换的 Agent 任务,“低摩擦”比“单点性能”更重要。
2.3 和“单独部署再拼装”相比的取舍
有人可能会问:我 Docker Compose 起三个容器,分别跑浏览器工具、终端工具、文件工具,不也能实现类似效果吗?能,但有几个现实差异。
同一容器内服务之间走 localhost 通信,端口冲突概率低,也省掉了 Compose 里网络配置的心智负担。更重要的是进程保活和生命周期管理——在一个容器里,无论哪个子进程崩溃,都可以由同一个 init 进程拉起,状态联动性更一致。
缺点是隔离性减弱了。如果容器被攻破,攻击者能同时拿到浏览器、Shell、文件系统三个入口,而非单一服务入口。但同时,这也意味着你给 Agent 的权限边界足够清晰——它只能在这个容器内任意操作,容器就是你给它的全世界。
项目本身也提供了一些安全措施,比如通过 token 鉴权、强制所有 Web 访问走 HTTPS、默认关闭远程调试等。在容器网络隔离的基础上,这些措施足够应对大多数开发场景。
3. 核心组件拆解:浏览器、Shell、文件、MCP、VSCode 各自怎么工作
3.1 浏览器:基于 Chromium 的 CDP 控制
AIO Sandbox 内置的浏览器是 Chromium,以 headless 模式运行,通过 CDP(Chrome DevTools Protocol)对外提供控制接口。CDP 是 Chrome/Chromium 提供的一套调试协议,支持页面导航、DOM 操作、截图、网络监听等几乎所有浏览器能力。
之所以选 CDP 而不是 Selenium 或 Playwright 独立的 driver,是因为 CDP 是浏览器原生的调试协议,少一层封装意味着更低的资源开销和更直接的页面状态控制。AIO Sandbox 把它封装成了两类入口:一类是给 AI 模型通过 MCP 调用的工具接口,另一类是给开发者直接通过代码访问的 REST/WS 接口。
提示:如果你是第一次接触 CDP,可以直接在浏览器里访问 http://容器地址:9222/json ,能看到所有打开的页面和他们对应的 WebSocket 调试地址。AI Agent 就是通过这个地址实现远程控制浏览器的。
3.2 Shell:基于 ttyd 的交互式终端
Shell 用的是 ttyd,一个把终端命令跑在浏览器里的工具。它的核心是让用户在浏览器里获得一个接近原生 SSH 的体验——支持颜色显示、键盘快捷键、自动补全这些,底层是通过 WebSocket 和容器内的 PTY(伪终端)通信。
这个组件对 Agent 的价值是提供了标准化的命令执行通道。Agent 通过 MCP 接口调用execute_command,底层就是往这个 ttyd 进程写命令、读输出。因为用的是 PTY 模式,很多对终端交互有要求的命令(比如需要确认输入、有 ANSI 转义符输出)都能正常处理。
3.3 文件:基于 webdav 的文件管理
文件系统模块用的底层是 WebDAV 协议,配合一个浏览器端的文件管理器界面。WebDAV 是在 HTTP 基础上的文件操作扩展,可以用 PUT 上传文件、GET 下载文件、PROPFIND 列目录。
选择 WebDAV 是明智的做法——它足够通用,支持各类客户端挂载,比如在 Windows 上映射网络驱动器、在 macOS 上直接连接,还便于 Agent 通过 HTTP 调用文件接口,不依赖某个特定生态。在容器里设置一个共享目录/workspace,宿主机再把这个目录挂载进来,就能完成容器与宿主机之间的文件交换。
3.4 MCP Server:Agent 与容器的连接桥
这部分是 AIO Sandbox 最核心的一点。MCP(Model Context Protocol)是模型上下文协议,它定义了 AI 模型“如何使用外部工具”的标准化格式。AIO Sandbox 实现了一个 MCP Server,把前三个组件(浏览器、Shell、文件)都封装成了 MCP 工具。
这意味着任何支持 MCP 客户端的 AI 应用——比如 Claude Desktop、或者你用 Python/TS 写的自定义 Agent——都可以通过同一个协议入口,调用容器里的浏览器、终端和文件系统。你用 MCP 的方式连接上它之后,模型就能自己操作浏览器、执行命令、读写文件了。
MCP Server 负责做参数映射和结果格式化。比如模型要“打开某个 URL 并截图”,MCP 客户端把这句话发给 AIO Sandbox,它解析成 CDP 的 Page.navigate 和 Page.captureScreenshot 指令,然后把截图以数据 URI 的形式返回。整个链路在几十毫秒内完成,模型感觉不到等待。
3.5 VSCode:基于 code-server 的在线 IDE
为了让你和 Agent 能在同一环境里改代码,项目内置了 code-server,也就是在浏览器里运行的 VSCode。你可以用它打开/workspace目录下的任何项目,装插件、跑调试、看 git 变更都没问题。
关键是 VSCode 和 Agent 编辑的文件是同一份。Agent 通过文件接口改了一个文件,你在 VSCode 里立刻能看到变化,不用刷新、不用重新同步。这种协作模式对调试 Agent 任务非常有用——模型改代码,你来 review,效率提升明显。
4. 实操部署:从零拉起一个可用的 AIO Sandbox
4.1 准备工作与环境要求
部署 AIO Sandbox 只需要一台能跑 Docker 的设备,我实测用的是 4 核 8G 的云主机,跑起来资源占用大约在 2 核 3G 左右,所以门槛不算高。如果本地开发,Docker Desktop 20.10+ 也可以,但要注意 Windows 下需要启用 WSL2 后端。
需要准备的东西:
- Docker 和 Docker Compose 插件(目前部分新版本已经包含了 Compose v2 能力)
- 一个可访问的域名或 IP(如果要在公网访问,建议先配置好防火墙规则)
- 想要挂载进容器的工作目录,比如
/data/workspace
AIO Sandbox 的镜像发布在 GitHub Container Registry 上,部署文件是一个 docker-compose.yml,内容不长,核心是环境变量配置。
4.2 关键配置项详解
部署文件里最重要的几个参数分别是:
services: aio-sandbox: image: ghcr.io/xxxx/aio-sandbox:latest ports: - "8080:80" environment: - TOKEN=your_secret_token - WORKSPACE=/workspace - DOMAIN=sandbox.example.com volumes: - /data/workspace:/workspaceTOKEN是访问所有 Web 界面的鉴权凭证,建议用强随机字符串,不要在文档源码里用默认值。DOMAIN用于生成 HTTPS 证书和 WebSocket 的合法域名,如果你没有独立域名,用 IP 直连也可以,但会把 WebSocket 访问变成未加密连接,建议局域网内测试时用。WORKSPACE控制容器内的工作目录路径,和宿主机挂载路径配合,决定文件系统的视角。
注意:
DOMAIN参数如果填了域名,AIO Sandbox 会自动调用 Let's Encrypt 申请证书,因此需要提前把域名的 A 记录解析到服务器 IP 上。如果只是内网测试,可以不填这个参数然后用 HTTP 访问。
4.3 启动后的访问路径一览
启动成功后,访问http://服务器IP:8080,会要求你输入 TOKEN 鉴权。进去后是一个简单的导航页,包含几个入口:
/vscode/—— 在线 VSCode,直接打开工作区目录/shell/—— Web 终端,执行容器内命令/files/—— 文件管理器,可视化浏览上传下载/mcp/—— MCP Server 的接入信息页/browser/—— 浏览器调试页面
有个小经验值得分享:/shell/的终端里默认用户是非 root 的,如果某些命令需要 root 权限(比如安装软件包),可以用sudo -i切换,容器内的 sudo 配置已默认开启。但在给 Agent 用时,不建议日常就在 root 下运行,否则 Agent 误操作rm -rf /能把环境彻底搞坏。
4.4 验证 MCP 连接是否正常
启动之后最重要的一步,是验证 MCP Server 是否能被外部 AI 客户端发现。打开/mcp/页面,页面会显示一个 WebSocket 地址,格式通常为:
wss://你的域名/mcp/?token=你的TOKEN关键参数说明:路径固定为/mcp/,查询参数token是鉴权标识。以支持 MCP 的客户端为例,连接时只需要填这个地址,不用额外配置 Header。以 Python 为例,用官方 SDK 连接测试的代码如下:
import anyio from mcp import ClientSession, StdioServerParameters # 如果是远程连接,使用 WebSocket 客户端,代码示意: from mcp.client.streamable_http import streamablehttp_client async def test(): async with streamablehttp_client("wss://你的域名/mcp/?token=你的TOKEN") as (read, write): async with ClientSession(read, write) as session: tools = await session.list_tools() print("发现工具数量:", len(tools.tools)) for t in tools.tools: print("工具:", t.name) anyio.run(test)连接成功后会列出所有可用的工具,大致包括浏览器控制、Shell 命令执行、文件读写等几类,每类下又有细分操作。我实测下来工具列表数量大约在 20 个左右——覆盖度相当可观,但这取决于具体镜像版本,不必死记。
5. 实战接入:让 AI Agent 操作浏览器、终端和文件
5.1 用 MCP 驱动的浏览器自动化任务
接入 MCP 后,AI Agent 就有了“视觉 + 操作”能力。以网页自动化为例,让 Agent 调研一个网站的产品列表,它会自动调用浏览器工具,导航到目标页面、等待渲染完成、截取可视区域画面,再从中提取商品信息。
这个流程里最实用的是截图工具。它返回的不是普通图片,而是带坐标信息的页面快照。AI 可以通过视觉识别发现页面上有哪些按钮、哪些输入框、滚动条位置如何,然后基于这些信息决策下一步操作——点哪个按钮、填哪个表单。这是传统爬虫脚本做不到的,因为传统爬虫只能做确定的 DOM 操作,而 AI 能应对页面改版和动态渲染。
小技巧:调用截图工具时,建议把图片质量设低一点(有参数可以配置),因为图像处理本身需要先展示给视觉模型,质量太高反而拖慢响应速度。设置一个合理的质量阈值,在识别率和性能之间取平衡。
5.2 终端工具的多种调用姿势
Shell 类工具除了简单的execute_command,还支持带交互的命令执行。比如你写一段需要等待用户输入的脚本,Agent 会启动一个带输入的会话,在等待时保持会话开启,直到收到用户响应。
这解决了一个实际问题:很多 Shell 命令不是一次执行就能结束的,比如交互式安装向导,或者需要持续输出的tail -f。传统工具调用只执行一次、拿一次结果就结束了,而 AIO Sandbox 的终端工具支持“持续会话”——通过一个 session_id 保持连接,可以多次读写同一进程的输入输出。
实用场景举例:Agent 在容器里跑一个长时间的数据处理任务,它会启动命令、等待任务输出、在出错时按日志自动修改参数、重新执行。整个流程不需要人去干预。
5.3 文件工具在 Agent 工作流中的位置
文件类工具在整个 Agent 工作流中承担的角色是“持久化记忆”。Agent 跑完一个任务后,把结果写到/workspace/output.md;下一个会话开始时,用文件工具读取这个文件作为上下文。这样不仅解决了跨会话的信息传递,也方便人来 review 它的每一个产物。
另外,文件工具对“Agent 生成代码”的场景尤其关键。AI 写了一段 Flask 服务代码,通过文件工具写入容器,然后用 Shell 工具启动它,再用浏览器工具访问 localhost 端口验证效果——整个过程在同一容器内闭环完成。
5.4 自定义工具扩展:不只是内置的
AIO Sandbox 的 MCP Server 还支持自定义工具注册。如果你需要让 Agent 访问容器内的某个私有 API、或者调用某个特定的内部脚本,可以在 MCP Server 的配置目录里新增一个工具定义文件。格式是 JSON,声明工具名、参数 schema、以及执行时的内部指令映射。
做一个简单自定义工具的思路:在容器中创建/workspace/tools/my_tool.sh,然后再写一个 JSON 配置文件描述它的入参出参,重启容器后这个新工具就会出现在 MCP 工具列表里。这种方式很适合把公司内部的运维脚本暴露给 Agent,让 AI 直接调用已有的自动化能力,而不是重新写一套。
6. 常见问题与排障速查
6.1 浏览器无法启动或有白屏
最常见的原因是容器内缺少 GPU 或系统级依赖,headless Chromium 在部分精简镜像里启动会失败。对策是检查日志,注意有无 “GPU process” 或 “dbus” 相关的报错;如果是因为缺少依赖,需要进入容器执行 apt 安装命令。另外,如果是通过 SSH 隧道访问,注意浏览器内嵌的页面可能因为本地端口跳转而无法加载,这时需要用容器内直接映射的端口方式访问调试端口。
6.2 MCP 连接显示握手失败
这类问题通常出在 WebSocket 路径或鉴权参数上。优先检查token是否正确,是否包含了 URL 编码的特殊字符。然后检查反向代理配置——如果域名是通过 Nginx 或 Caddy 转发的,需要确保 WebSocket 的 Upgrade 头被正确转发。我遇到过不少次是因为 Nginx 默认没加proxy_set_header Upgrade $http_upgrade;导致连接握手上断。
6.3 Shell 命令执行结果与浏览器显示不同
这个现象多半是环境变量差异导致的。通过 Web 终端执行的命令和通过 MCP 执行的命令可能不在同一个 shell 会话、PATH 不同。解决方法是,在 MCP 工具调用时显式指定绝对路径,或者用一个.env文件统一环境变量,在两类入口中都 source 它。
6.4 VSCode 插件装不上或工作区打不开
code-server 的插件安装走的是 OpenVSX 市场,国内网络环境下载可能比较慢或超时。解决办法是手动下载 .vsix 文件,然后用命令从本地安装:
code-server --install-extension /path/to/extension.vsix至于工作区打不开,检查一下/workspace目录是否存在并且有权限。如果跑在 SELinux 开启的宿主机上,还可能需要给挂载目录补一个权限标签。
6.5 容器内时间与宿主机不同步
如果要在 AIO Sandbox 里做计划任务或依赖时间戳的 Agent 操作,时间不同步是个很隐蔽的坑。在 Docker Compose 里给容器加一行配置,把宿主机的时区文件挂载进去即可:
environment: - TZ=Asia/Shanghai volumes: - /etc/localtime:/etc/localtime:ro修改完成后,重启容器,再执行date验证,输出应该和宿主机一致。
可以把问题汇总成一套速查表:
| 症状 | 可能原因 | 快速排查手段 |
|---|---|---|
| 浏览器白屏 | Chromium 依赖缺失 | 查看容器日志,检查 GPU/dbus 报错 |
| MCP 握手失败 | WebSocket 反向代理配置错误 | 检查 Nginx 的 Upgrade 转发头 |
| Shell 结果不一致 | 环境变量不同 | 统一用绝对路径或 .env 文件 |
| VSCode 插件装不上 | 市场连接超时 | 手动安装 .vsix 文件 |
| 文件管理器无法上传 | 挂载目录名不匹配 | 对比容器内外路径配置 |
| 端口占用冲突 | 宿主机 8080 被占用 | 修改映射端口或换一个服务端口 |
7. 进阶用法与经验体会
7.1 用多实例做 Agent 评测隔离
我实际用得比较多的场景是把 AIO Sandbox 当评测环境用。传统评测方式是在同一台机器上跑多组 Agent,互相干扰;有了 AIO Sandbox,每个评测任务开一个独立容器,代码、数据、工具实例完全隔离。
编排上可以用 Docker Compose 的副本特性,把一组沙箱实例批量拉起来,预先挂载各自的测试数据集目录,然后通过统一的 MCP 入口把测试脚本灌进每个容器。评测完成后,只需要把结果文件从容器里拷出,整体流程干净利落。
7.2 直接作为远程开发测试环境
如果你需要在多台设备上保持一致的开发环境,可以把 AIO Sandbox 部署在一台常开的机器上,平时只需要浏览器就能连上 VSCode、终端、文件系统,没有本地环境配置的负担。
我的实测感受是,code-server 的性能表现可以接受——虽然打开大项目时比本地 VSCode 慢一点,但日常编码流畅度足够,特别是配合浏览器自动保存和文件自动同步功能,体验已经很接近本地了。如果碰上网速波动,用/shell/加上 tmux 管理会话,比直接网页编辑更稳定。
7.3 最后的建议
按照我个人的使用习惯,有几点希望后来者注意:一是 TOKEN 换得勤一点,尤其在公网上使用的时候,哪怕是测试环境也比裸奔强;二是把工作目录挂载到宿主机并能定时做快照备份,方便回滚;三是在给 Agent 用的场景里,要给 Shell 工具加一层白名单机制——比如禁止执行rm -rf、禁止写系统目录,容器虽然隔离了宿主机风险,但还不能完全防止 Agent 把自己的工作环境玩坏。
这个项目后续能扩展的方向也不少:比如在容器里直接内置一个 Agent 运行框架,让 MCP Server 不再只是“工具桥”,而成为一个完整的“Agent 宿主”;或者把容器的镜像做成更适合 ARM 架构的版本,在树莓派这类设备上跑轻量版沙箱。社区里已经有人在往这些方向探索了,我做出来的几个组合用法也只是众多可能性里的几种。