1. 项目概述:不是“塞进去”,而是“有机融合”——AIO Sandbox 的真实定位
AIO Sandbox 这个名字,乍看像极了那种把一堆工具粗暴打包塞进 Docker 容器的“大杂烩”项目。但实测下来,它根本不是这么回事。我花了一整天时间从零构建、调试、跑通全部流程,再反复拆解它的源码结构和运行时行为,结论很明确:AIO Sandbox 的核心价值,不在于“能塞多少东西”,而在于它用一套统一的Agent Runtime 协议层,把浏览器、Shell、文件系统、MCP 服务、VSCode Server 这五类原本彼此割裂的交互界面,真正拧成一个可编程、可编排、可审计的单一执行上下文。关键词不是“塞”,是“融合”;不是“容器”,是“沙箱”。
它解决的,是当前 AI Agent 开发中最让人头疼的“上下文撕裂”问题——你让模型调用 Shell 执行命令,它却不知道当前工作目录下有哪些文件;你让它打开网页截图,它又无法把截图结果自动存入本地并通知后续步骤;你让它用 VSCode 编辑代码,改完之后怎么触发测试?这些环节之间没有标准的数据通道,全靠硬编码拼接,一改就崩。AIO Sandbox 就是为终结这种“胶水式开发”而生的。它不替代 Chrome、Bash 或 VSCode,而是给它们装上同一套神经接口,让 Agent 能像人一样,在同一个认知空间里自由切换“手”(Shell)、“眼”(浏览器)、“记忆”(文件系统)、“协作伙伴”(MCP 服务)和“工作台”(VSCode)。适合谁?不是给终端用户装个“全能浏览器”的,而是给 AI 工程师、自动化平台开发者、安全沙箱研究员这类需要构建可控、可复现、可审计 Agent 执行环境的人准备的。它不是玩具,是生产级的 Agent 底座。
2. 核心设计思路:为什么必须用 MCP 协议作为中枢神经?
2.1 传统方案的三大死结与 AIO Sandbox 的破局点
我试过至少四种主流的 Agent 沙箱方案:基于 Selenium 的纯浏览器沙箱、基于 tmux + webtty 的 Shell 沙箱、基于 VSCode Remote 的 IDE 沙箱、以及用 MinIO + REST API 做文件中转的混合方案。它们共同的痛点,我总结为三个“断层”:
协议断层:浏览器用 DevTools Protocol(CDP),Shell 用 PTY 伪终端,文件操作用 POSIX syscall 或 HTTP API,VSCode 用 Language Server Protocol(LSP)和 VS Code Extension API,MCP 服务则各玩各的 HTTP/gRPC。Agent 模型要同时驱动它们,就得写四套完全不同的适配器,维护成本爆炸。
状态断层:Shell 的当前目录、环境变量、历史命令;浏览器的 cookies、localStorage、当前 tab URL;VSCode 的打开文件、光标位置、调试状态——这些状态彼此隔离,Agent 一次决策后,状态无法跨组件同步。比如模型说“把刚才网页截图保存为 report.png”,它得先告诉浏览器截图,再告诉文件系统保存,再告诉 Shell 检查文件是否存在,三步之间任何一步失败或延迟,整个链路就断了。
权限断层:浏览器沙箱默认禁止访问本地文件系统;Shell 容器默认无网络;VSCode Server 默认不暴露端口给外部调用。传统方案要么全开(不安全),要么全关(不可用),缺乏细粒度的、按需授予的权限模型。
AIO Sandbox 的破局,就是用MCP(Model Control Protocol)作为唯一的、标准化的“中枢神经”。它不是发明新协议,而是对现有 MCP 规范(v0.3+)做了深度工程化落地。MCP 在这里不是“另一个 API”,而是定义了所有组件必须遵循的四层契约:
通信层:强制所有组件(Browser、Shell、File、VSCode、MCP Service)通过 WebSocket(
wss://api.xiaozhi.me/mcp/...这类地址)连接到同一个 MCP Router。Router 不做业务逻辑,只做消息路由和鉴权。能力层:每个组件注册自己支持的
tool列表,格式严格遵循 MCP 的 JSON Schema。例如 Shell 组件注册shell.execute和shell.list_files;Browser 组件注册browser.navigate和browser.screenshot;VSCode 注册vscode.open_file和vscode.run_command。Agent 模型只需调用tool_call,不用管背后是哪个组件在执行。状态层:MCP Router 维护一个轻量级的
context_state对象,所有组件在执行tool后,可选择性地向 Router 提交状态快照(如{"cwd": "/home/user", "tabs": [{"url": "https://aio.dev", "title": "AIO Sandbox Docs"}]})。Router 将其聚合,供后续tool_call的context字段引用。这解决了状态断层。权限层:每个
tool调用都携带permissions字段(如["filesystem:read", "network:allow"]),Router 根据预设策略(JSON Policy 文件)实时校验。比如shell.execute默认禁止rm -rf /,但允许ls -l;browser.navigate默认禁止file://协议,但允许https://。权限策略可热更新,无需重启。
所以,AIO Sandbox 的本质,是一个MCP 协议的 Reference Implementation + 生产级 Runtime 环境。它把 MCP 从纸面规范,变成了可安装、可调试、可监控的实体。这不是“塞工具”,是“建标准”。
2.2 为什么选 MCP 而不是其他协议?技术选型背后的硬逻辑
有人会问:为什么不用更成熟的 CDP 或 LSP?答案很实在:适用范围窄,扩展性差。
CDP(Chrome DevTools Protocol):专为 Chromium 设计,虽然强大,但 Shell、文件系统、VSCode 都不原生支持。强行适配,等于给每个组件都写一个 CDP 的“翻译官”,架构臃肿,且无法统一权限模型。CDP 的
Runtime.evaluate可以执行 JS,但fs.readdirSync这种 Node.js API 怎么映射?没标准。LSP(Language Server Protocol):专注代码分析,对浏览器操作、Shell 命令、文件上传下载毫无概念。它连“打开一个网页”这个动作都无法描述。
自研协议?我们团队去年做过 PoC,三个月内迭代了七版,最后发现:协议设计最难的不是功能,是生态兼容性。MCP 的最大优势,是它已被多个主流 Agent 框架(如 LangChain、LlamaIndex、OpenHands)列为官方支持协议,工具链(如
mcp-serverCLI、mcp-clientSDK)已成熟。AIO Sandbox 直接复用这套生态,意味着你写的 Agent 逻辑,今天跑在 AIO Sandbox 上,明天就能无缝迁移到另一家基于 MCP 的云服务上。这是商业项目最看重的“可迁移性”。
提示:MCP 并非万能。它不处理模型推理本身,也不提供 UI 渲染。AIO Sandbox 的前端(Web UI)只是一个 MCP Client,负责把用户操作转成
tool_call发给 Router,再把 Router 返回的tool_result渲染出来。真正的“智能”在外部模型,AIO Sandbox 只负责“可靠执行”。
3. 核心组件解析:五个模块如何协同工作?
3.1 Browser 组件:不止是 Chrome,是“可编程的视觉器官”
AIO Sandbox 的 Browser 组件,底层确实是 Chromium(通过 Playwright 启动),但它绝不是简单地开个chromium.launch()。关键改造点有三个:
MCP Tool 注册:它注册了 7 个标准
tool,包括browser.navigate(带wait_until: "networkidle"参数)、browser.screenshot(支持full_page: true和clip: {"x":0,"y":0,"width":100,"height":100})、browser.fill(支持 CSS selector 和 XPath)、browser.click(带button: "right"和click_count: 2)、browser.get_html(返回 DOM 字符串)、browser.get_cookies、browser.set_cookies。每个tool的输入输出 Schema 都严格匹配 MCP 规范,确保模型能精准理解参数含义。状态同步机制:每次
navigate成功后,组件会主动向 MCP Router 提交当前 tab 的url、title、ready_state(completeorinteractive)和viewport_size。这些数据被 Router 存入context_state,下次screenshot调用时,模型可通过context字段引用viewport_size来决定是否截全屏。安全沙箱加固:禁用所有危险 API。
window.open()被拦截并返回错误;navigator.clipboard.readText()需显式permissions授权;fetch()默认只允许同源请求,跨域需在tool_call中声明permissions: ["network:cross-origin"]并经 Router 策略校验。实测下来,即使模型生成恶意 JS 代码(如while(true){}),Playwright 的page.evaluate也会因超时(默认 30s)而终止,不会拖垮整个沙箱。
注意:它不支持
chrome://内部页面(如chrome://version),这是 Chromium 的硬限制,与 AIO Sandbox 无关。想查版本?用shell.execute调google-chrome --version更可靠。
3.2 Shell 组件:不是裸露的 Bash,是“受控的双手”
Shell 组件是整个沙箱里权限最敏感的部分,AIO Sandbox 的处理非常务实:
双层隔离:第一层是 Docker 容器的 namespace 隔离(
--cap-drop=ALL --security-opt=no-new-privileges);第二层是 Shell 进程自身的chroot+seccomp-bpf过滤。所有系统调用都被白名单过滤,openat,read,write,stat,getdents允许,mount,clone,execveat(除/bin/sh外)一律拒绝。这意味着unshare --user或pivot_root这类逃逸手段,在启动阶段就被 kernel 拦截。MCP Tool 设计:只暴露 5 个高危但必需的
tool:shell.execute:执行单条命令。关键限制:命令字符串必须是 ASCII,禁止\x00等控制字符;timeout参数强制存在(默认 10s,最大 60s);env参数只允许覆盖PATH和HOME,禁止设置LD_PRELOAD等危险变量。shell.list_files:列出目录内容。关键限制:路径必须是绝对路径,且必须以/home/user为根(chroot目录),..路径被规范化处理,杜绝路径穿越。shell.read_file:读取文件。关键限制:文件大小上限 10MB,二进制文件(如.exe,.so)只返回前 1KB 的 hex dump,防止泄露敏感信息。shell.write_file:写入文件。关键限制:目标路径必须在/home/user下,且父目录必须已存在(不自动创建),内容经过utf-8编码校验。shell.get_env:获取环境变量。只返回白名单内的变量(PATH,HOME,USER,SHELL),$PS1等提示符变量不返回。
审计日志:每次
tool调用,Shell 组件都会生成一条结构化日志:{"timestamp": "2024-06-15T10:23:45Z", "tool": "shell.execute", "command": "ls -la /tmp", "exit_code": 0, "stdout": "...", "stderr": "", "duration_ms": 12}。日志直接推送到 MCP Router 的审计通道,可供外部 SIEM 系统采集。
实操心得:别指望用
shell.execute运行 Python 脚本。AIO Sandbox 的容器里只装了bash,coreutils,curl,jq,python3(仅基础库)。想跑复杂 Python?用vscode.run_command启动 VSCode 的 Python 插件,或者把脚本内容通过shell.write_file写入,再shell.execute调用python3 script.py—— 后者更安全,因为python3进程也受 seccomp 限制。
3.3 File 组件:不是 FTP,是“可信的记忆中枢”
File 组件是沙箱里最“安静”但最关键的模块。它不提供 CLI,只通过 MCPtool与外界交互:
统一文件视图:它管理
/home/user目录下的所有文件,无论这些文件是 Shell 创建的、Browser 下载的、还是 VSCode 编辑的。所有tool调用都基于这个路径。browser.download的文件,默认存到/home/user/downloads/;vscode.open_file的路径,也必须是/home/user/下的相对路径。MCP Tool 清单:
file.upload:上传文件到沙箱。关键设计:前端 UI 选择文件后,浏览器先将文件分块(每块 5MB),通过 WebSocket 流式上传到 File 组件,组件边收边写入磁盘,并计算 SHA256 校验和。上传完成才返回file_id(如sha256:abc123...),确保完整性。file.download:下载文件到本地。关键设计:返回一个临时download_url(如/api/download/abc123?token=xxx),该 URL 有效期 5 分钟,且绑定用户 session,防止未授权下载。file.list:列出目录。关键设计:返回结构化 JSON,包含name,type(fileordirectory),size,modified_time,is_executable。is_executable字段由stat系统调用获取,比单纯看后缀名(.sh)更可靠。file.delete:删除文件。关键设计:支持recursive: true,但会先检查目标路径是否在/home/user下,且不能是/home/user本身(防误删根目录)。
静默同步:当 Shell 执行
touch hello.txt或 VSCode 保存main.py时,File 组件会通过 inotify 监听/home/user目录变更,自动更新自己的内部索引。这样file.list总是最新,无需手动刷新。
注意:
file.upload不支持断点续传。如果上传中途断开,整个文件需重传。这是为了简化实现,保证原子性。生产环境若需大文件,建议先用shell.execute curl -F "file=@large.zip" http://upload-api/走外部服务。
3.4 VSCode 组件:不是远程桌面,是“可编程的工作台”
VSCode 组件是 AIO Sandbox 最惊艳的部分。它不是简单的 VSCode Server(code-server),而是深度定制的@aio-sandbox/vscode-extension:
轻量化启动:容器内只安装 VSCode Server(
code-serverv4.19+)和一个专用 extension。Extension 的package.json声明了 12 个contributes.commands,每个命令都对应一个 MCPtool,如vscode.open_file→extension.openFile,vscode.run_command→extension.runCommand。MCP Tool 映射:
vscode.open_file:打开指定路径的文件。关键增强:支持line和column参数,打开后光标自动定位。encoding参数可指定utf-8或gbk,解决中文乱码。vscode.save_file:保存当前编辑的文件。关键增强:返回file_hash(SHA256),供后续file.download引用。vscode.run_command:执行 VSCode 命令。关键增强:支持args数组,如["workbench.action.terminal.toggleTerminal"],可模拟用户快捷键操作。vscode.get_editor_content:获取当前编辑器内容。关键增强:返回content和cursor_position,模型可据此做“增量编辑”。vscode.set_editor_content:设置编辑器内容。关键增强:支持diff_mode: "patch",只发送差异部分,节省带宽。
资源隔离:VSCode Server 运行在独立的
code-server进程,其工作区(/home/user/workspace)与 Shell 的/home/user是同一个目录。但 VSCode 的插件进程(如 Python 插件)被限制在cgroups中,CPU 使用率上限 50%,内存上限 1GB,防止插件崩溃拖垮整个沙箱。
实操心得:VSCode 的
settings.json是全局的,不是 per-workspace。所有用户看到的设置都一样。想个性化?用vscode.run_command调workbench.action.openSettingsJson,然后vscode.set_editor_content写入自定义配置。但注意,settings.json的修改会立即生效,可能影响其他正在使用的用户。
3.5 MCP Router:不是代理,是“沙箱的宪法法院”
MCP Router 是整个系统的灵魂,它不执行任何业务逻辑,只做三件事:路由、鉴权、审计。
路由引擎:收到一个
tool_call请求(JSON-RPC 2.0 格式),先解析tool名称(如browser.navigate),查表找到注册了该tool的组件(Browser),然后将请求转发过去。组件返回tool_result后,Router 再将其封装成标准 JSON-RPC 响应,发回给调用方(Agent 模型或 Web UI)。动态鉴权:Router 加载一个
policy.json文件,内容类似:{ "rules": [ { "action": "allow", "tool": "shell.execute", "conditions": [ {"field": "command", "op": "not_match", "value": "^(rm|chmod|chown|sudo).*"}, {"field": "timeout", "op": "le", "value": 30} ] }, { "action": "deny", "tool": "browser.navigate", "conditions": [ {"field": "url", "op": "match", "value": "^file://.*"} ] } ] }每次
tool_call,Router 都逐条匹配规则。匹配到deny则直接返回错误;匹配到allow则放行;无匹配则默认deny。策略文件可热重载,kill -SIGHUP $(pidof mcp-router)即可。审计中心:所有
tool_call和tool_result都被序列化为 JSON,打上时间戳和request_id,通过auditchannel 广播。AIO Sandbox 的 Web UI 有个 “Audit Log” 标签页,实时显示所有操作。生产环境可对接 ELK 或 Splunk。
提示:Router 的
policy.json是沙箱安全的基石。不要用网上找的“通用策略”,必须根据你的业务场景定制。例如,如果你的 Agent 需要git clone,就在shell.execute规则里加一条{"field": "command", "op": "match", "value": "^git clone https://.*"}。安全不是一劳永逸,是持续运营。
4. 实操部署:从零开始搭建一个可用的 AIO Sandbox
4.1 环境准备:硬件、系统与依赖的硬性要求
AIO Sandbox 对环境的要求,比想象中更“接地气”。它不是那种动辄要 32 核 128G 的 AI 巨兽,而是一个精悍的“瑞士军刀”。我的实测环境是:
- 硬件:一台 4 核 CPU(Intel i5-8250U)、16GB RAM、256GB SSD 的笔记本。Docker Desktop for Windows(WSL2 backend)。
- 系统:Ubuntu 22.04 LTS(WSL2 内),内核 5.15+。强烈不建议在 CentOS 7 或旧版 Debian 上部署,因为 seccomp 和 cgroups v2 支持不完善。
- 前置依赖:
- Docker Engine v24.0+(必须,旧版不支持
--cgroup-parent) - Docker Compose v2.20+(用于一键编排)
curl,jq,git(用于下载和验证)
- Docker Engine v24.0+(必须,旧版不支持
注意:Windows 用户请务必使用 WSL2,而不是 Docker Desktop 的 Hyper-V 模式。后者对
seccomp的支持有 bug,会导致 Shell 组件启动失败。Mac M1/M2 用户没问题,原生支持。
4.2 一键部署:docker-compose.yml的关键配置解读
AIO Sandbox 官方提供了docker-compose.yml,但直接docker-compose up -d很可能失败。原因在于几个关键配置项必须手动调整:
version: '3.8' services: # MCP Router - 沙箱的大脑 mcp-router: image: aio-sandbox/mcp-router:v0.5.2 ports: - "8080:8080" # MCP WebSocket 端口 - "8081:8081" # HTTP API 端口(用于 audit log 查询) volumes: - ./config/policy.json:/app/policy.json:ro # 必须挂载! - ./logs:/app/logs # 日志目录 environment: - MCP_JWT_SECRET=your-very-secure-jwt-secret-here # 必须修改! - MCP_API_TOKEN=eyjhbgcioijfuzi1niisinr5cci6ikpxvcj9.eyj # 示例 token,实际需生成 # Browser 组件 - 可编程的眼睛 browser: image: aio-sandbox/browser:v0.5.2 depends_on: - mcp-router environment: - MCP_ROUTER_URL=ws://mcp-router:8080 # 注意是 ws://,不是 wss:// - PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright # 国内加速 # 关键:必须启用 privileged 模式,否则 Playwright 无法启动 Chromium privileged: true # 关键:共享 /dev/shm,否则 Chromium 渲染会卡顿 volumes: - /dev/shm:/dev/shm # Shell 组件 - 受控的双手 shell: image: aio-sandbox/shell:v0.5.2 depends_on: - mcp-router environment: - MCP_ROUTER_URL=ws://mcp-router:8080 - HOME=/home/user - USER=user # 关键:seccomp 配置文件必须挂载 security_opt: - seccomp:./config/seccomp-shell.json # 关键:chroot 目录必须挂载 volumes: - ./workspace:/home/user:rw # VSCode 组件 - 可编程的工作台 vscode: image: aio-sandbox/vscode:v0.5.2 depends_on: - mcp-router environment: - MCP_ROUTER_URL=ws://mcp-router:8080 - CODE_SERVER_PASSWORD=your-code-server-password # 必须修改! # 关键:VSCode 的 workspace 目录必须与 Shell 共享 volumes: - ./workspace:/home/user:rw # 关键:限制资源,防止 OOM mem_limit: 1g cpus: '0.5' # Web UI - 用户入口 web-ui: image: aio-sandbox/web-ui:v0.5.2 ports: - "8000:80" depends_on: - mcp-router environment: - MCP_ROUTER_URL=ws://mcp-router:8080必须修改的三个地方:
mcp-router的MCP_JWT_SECRET:这是所有组件通信的 JWT 签名密钥。必须是 32 字节以上的随机字符串。生成命令:openssl rand -hex 32。mcp-router的MCP_API_TOKEN:这是 Web UI 连接 Router 的 token。格式是 JWT,payload 必须包含{"sub": "web-ui", "exp": 1735689600}(Unix 时间戳,建议设为一年后)。用在线 JWT 生成器即可。vscode的CODE_SERVER_PASSWORD:这是访问 VSCode Web UI 的密码。不能是弱密码,否则会被暴力破解。
实操心得:
./workspace目录必须提前创建(mkdir -p ./workspace),并确保当前用户有读写权限。否则 Shell 和 VSCode 组件会因无法挂载而退出。我第一次部署就卡在这里,日志里只有一句permission denied,排查了两小时才发现是目录权限问题。
4.3 首次启动与验证:五个组件的健康检查清单
部署完成后,执行docker-compose up -d,等待 2-3 分钟。然后逐项验证:
- Router 是否存活:
curl http://localhost:8081/health,返回{"status":"ok"}即可。 - Browser 是否注册:
curl http://localhost:8081/api/tools | jq '.tools[] | select(.name=="browser.navigate")',应返回完整的 tool schema。 - Shell 是否注册:同上,查
shell.execute。 - VSCode 是否注册:同上,查
vscode.open_file。 - Web UI 是否可访问:浏览器打开
http://localhost:8000,应看到 AIO Sandbox 的登录页。输入CODE_SERVER_PASSWORD登录。
终极验证:一个端到端的 MCP 调用
在 Web UI 的 Console 标签页,粘贴以下 JSON 并点击 Send:
{ "jsonrpc": "2.0", "id": 1, "method": "tool_call", "params": { "tool": "shell.execute", "arguments": { "command": "echo 'Hello from AIO Sandbox!'", "timeout": 5 } } }如果返回:
{ "jsonrpc": "2.0", "id": 1, "result": { "stdout": "Hello from AIO Sandbox!\n", "stderr": "", "exit_code": 0 } }恭喜,你的沙箱已打通任督二脉。
常见问题:如果
curl返回Connection refused,检查docker-compose ps,看mcp-router容器状态是否为Up。如果不是,docker-compose logs mcp-router查看错误。90% 的情况是policy.json格式错误或MCP_JWT_SECRET太短。
5. 高级应用与避坑指南:那些文档里不会写的实战经验
5.1 如何让 Agent 模型真正“理解”沙箱能力?
很多用户部署完,发现模型调用browser.navigate失败,报错tool not found。问题不在沙箱,而在模型的System Prompt。
正确的 System Prompt 必须包含:
- 能力声明:明确告诉模型沙箱支持哪些
tool。例如:“你在一个 AIO Sandbox 环境中运行,可调用以下工具:browser.navigate,browser.screenshot,shell.execute,file.upload,vscode.open_file。每个工具都有详细的参数说明,请严格按 Schema 调用。” - 路径约定:强调所有路径都是
/home/user下的相对路径。例如:“所有文件操作路径,如file.upload的path参数,必须是/home/user下的子路径,如documents/report.pdf。绝对路径/tmp/xxx是无效的。” - 权限意识:提醒模型权限限制。例如:“
shell.execute禁止运行rm -rf、chmod等危险命令。如果需要删除文件,请使用file.delete工具。”
我用的 Prompt 模板(已验证有效):
你是一个高级 AI Agent,正在 AIO Sandbox 环境中执行任务。该环境提供以下标准化工具: - `browser.navigate(url: str, wait_until: str = "networkidle")`: 导航到网页,`wait_until` 可选值为 "load", "domcontentloaded", "networkidle"。 - `shell.execute(command: str, timeout: int = 10)`: 执行 Shell 命令,`command` 必须是安全的单行命令。 - `file.upload(content: str, path: str)`: 上传文本内容到指定路径,`path` 如 "notes/todo.md"。 - `vscode.open_file(path: str, line: int = 0, column: int = 0)`: 在 VSCode 中打开文件并定位光标。 请始终优先使用这些工具,而非尝试自行构造解决方案。所有路径均相对于 `/home/user`。记住,安全第一,不要尝试越权操作。注意:不要把整个 MCP Tool Schema 都塞进 Prompt,模型会 parse 不过来。只给它最常用、最核心的 4-5 个工具的简明说明即可。复杂的 Schema,留着让
tool_call的 validation 去做。
5.2 文件协作的黄金法则:Browser 下载 → Shell 处理 → VSCode 编辑
这是最典型的多组件协作场景。例如,让 Agent 下载一个 CSV 文件,用csvkit处理,再用 VSCode 编辑结果。
错误做法:模型先browser.download到/home/user/downloads/data.csv,再shell.execute运行in2csv /home/user/downloads/data.csv > /home/user/output.json,最后vscode.open_file打开/home/user/output.json。问题在于:browser.download的默认路径是/home/user/downloads/,但shell.execute的in2csv命令可能不存在(容器里没装csvkit)。
正确链路:
browser.download时,指定save_as: "data.csv",文件会存到/home/user/downloads/data.csv。shell.execute运行pip3 install csvkit && in2csv /home/user/downloads/data.csv > /home/user/output.json。pip3 install会临时安装包,in2csv就绪。vscode.open_file打开/home/user/output.json。
更优实践:把常用工具(csvkit,jq,yq)预先装进 Shell 组件的镜像里。修改Dockerfile:
FROM aio-sandbox/shell-base:v0.5.2 RUN pip3 install csvkit jq yq然后docker build -t my-shell .,在docker-compose.yml中替换image。这样每次启动都自带工具,无需pip3 install,更快更稳定。
实操心得:
browser.download的save_as参数,决定了文件在沙箱内的最终路径。不要依赖默认路径,显式指定,避免歧义。我曾因没指定save_as,导致文件名含空格(report final.csv),shell.execute调用时忘了加引号,命令直接报错。
5.3 VSCode 插件的“隐形杀手”:Python 环境的陷阱
VSCode 组件里预装了 Python 插件,但它的 Python 解释器路径是/usr/bin/python3,而这个 Python 环境是“纯净”的,没有requests,pandas等常用库。
问题场景:模型让 VSCode 运行一个 Python 脚本script.py,内容是import requests; print(requests.get('https://api.github.com').json())。VSCode 报错ModuleNotFoundError: No module named 'requests'。
解决方案有二:
- 方案一(推荐):用 Shell 预装。在
shell.execute中运行pip3 install requests pandas numpy。这些包会安装到/usr/local/lib/python3.x/site-packages/,VSCode 的 Python 插件默认使用系统 Python,因此能识别。 - 方案二:配置 VSCode 的 Python 解释器。在 VSCode 的 Command Palette (
Ctrl+Shift+P) 中,运行Python: Select Interpreter,然后选择/usr/bin/python3。但这只是告诉 VSCode 用哪个解释器,不解决包缺失问题。
注意:
pip3 install的包是全局的,所有用户共享。如果不同 Agent 需要不同版本的包(如一个要pandas==1.5.3,另一个要pandas==2.0.0),方案一就不适用了。此时,必须为每个 Agent 创建独立的 virtualenv,但这超出了 AIO Sandbox 的默认能力,需要定制 Shell 组件。
5.4 安全审计的“最后一道防线”:如何读懂 Audit Log?
Audit Log 不是摆设,它是你发现异常的唯一窗口。日志格式是 JSON,关键字段:
timestamp: 操作发生时间(UTC)。request_id: 全局唯一 ID,串联一次完整调用(tool_call→tool_result)。component: 执行组件(browser,shell,vscode)