项目背景与核心架构
本期视频主要介绍了一个名为 apple-sandbox 的开源工具,它旨在为 OpenAI Agents API 提供本地化的 self_hosted(自托管) 执行环境。与上一期使用的官方托管沙箱不同,该项目允许开发者在本地 Mac 基础设施上运行执行器,无需云账号、公网地址或 Docker。其核心原理是利用 Apple 开源的 container 工具,在 macOS 上为每个 Agent Session 启动独立的轻量级 Linux 虚拟机。这种架构提供了比 Docker 更高级别的隔离,因为 Apple container 为每个容器单独启动一个轻量级 Linux 虚拟机,而非共享内核。
整个系统架构分为四层:最底层是装有 Apple Silicon 芯片的 Mac,通过 container system start 启动服务;第二层是 Apple container 本身,负责从 OCI 镜像启动虚拟机;第三层是基于 Node.js 22 的精简执行器镜像,安装了 CA 证书和 codex npm 包;最顶层则是 apple-sandbox CLI,它负责创建工作目录、注入环境变量并调用 container 启动虚拟机后退出。这种设计使得 CLI 本身没有常驻进程,仅作为触发器存在。
“apple-sandbox 是一个用 Go 语言编写的命令行工具,没有常驻进程……它只做一件事情:把 OpenAI 的 codex exec-server 这个执行器跑进一个隔离的虚拟机里。”
数据持久化与生命周期管理
在文件交互方面,apple-sandbox 采用了一种高效的挂载机制。每个 Session 在本机的 sandboxes 目录下拥有独立的子目录,该目录被直接挂载为虚拟机内的 /workspace。这意味着 文件进出不需要任何上传下载接口,本机磁盘上的操作能实时反映在虚拟机中。这种设计简化了数据流,使得 Agent 生成的结果文件可以直接落盘到本机磁盘。
关于虚拟机的生命周期管理,apple-sandbox 提供了简洁的 CLI 命令集。主要命令包括 doctor(环境检查)、build(构建执行器镜像)、run(启动 Session)、logs(查看日志)以及 ls、stop 和 rm。特别值得注意的是 prune 命令,它允许用户按时间批量清理已停止的 Session。由于虚拟机本身是随时可销毁的状态,磁盘上的目录才是真正的状态存储。这种设计确保了资源的高效利用,避免了长期占用本地算力。
“每个 session 在本机的 sandboxes 目录下有一个自己的子目录,直接挂载成虚拟机里的 /workspace……本机磁盘上也能马上读到。”
自托管环境的连接机制:Application-Managed模式
apple-sandbox 的核心创新在于解决了 无公网地址 环境下与 OpenAI API 的协同工作问题。传统的自托管方案(如 Cloudflare Workers)通常依赖 webhook-managed 模式,即 OpenAI 通过带签名的 Webhook 通知用户启动容器。然而,个人 Mac 缺乏公网 IP,无法接收此类推送。
apple-sandbox 采用的是 application-managed 模式。在这种模式下,应用创建 Session 时直接获取 environment.id 和 remote_url,并 立即同步启动算力,无需等待 OpenAI 的通知。具体流程如下:
1. 创建 Session:应用使用普通 API Key 调用 Agents API,指定环境类型为 self_hosted。
2. 获取凭证:API 返回 Session ID、environment.id 和 remote_url。同时,开发者需在 OpenAI 平台创建受限 API Key(需具备 api.agents.environments.connect scope)。
3. 启动执行器:将受限 Key 设为环境变量 OPENAI_EXECUTOR_API_KEY,运行 apple-sandbox run。CLI 将三个关键参数注入虚拟机。
4. 主动连接:虚拟机内的 exec-server 使用受限 Key 主动向 remote_url 发起 WebSocket 连接,完成注册。
“self_hosted 环境也就咱们这种自己运行的沙箱环境,有两种同样都可以认为是正式的启动方式……另一种呢叫 application-managed:你的应用创建 session 的那一刻,就已经拿到了环境的 ID……直接同步把算力呢启动起来。”
状态流转与网络特性分析
在连接建立后,Session 的状态机经历了从 Created 到 Removed 的完整生命周期。执行器启动后进入 Registering 状态,若凭证错误则被 Rejected;注册成功后进入 Connected 状态。随后,OpenAI 下发命令时执行器进入 Executing 状态,完成后回到 Connected。若 WebSocket 断开,执行器会自动 Reconnecting。关键在于 OpenAI 从不反向连接用户机器,所有通信均为执行器主动出站。当 Session 彻底关闭时,exec-server 退出,容器进入 stopped 状态。
在网络安全性方面,目前 Apple container 的网络只有两种选择:完全内网或完全开放,缺乏域名级别的白名单机制。因此,当前版本的执行器拥有全开放的出站网络权限。虽然已知其需要访问 api.openai.com,但是否涉及其他地址尚未经过全面验证。因此,不建议拿它跑不受信任的任务。此外,目前仅提供了 CLI 工具,尚无 TypeScript 或 Python SDK封装。
“Apple container 的网络只有两种:完全内网或者完全开放,没有按域名放行的机制……所以不建议拿它跑不受信任的任务。”
端到端实战演示:从安装到任务执行
视频最后展示了完整的实操流程。首先需在 Apple Silicon Mac 上通过 Homebrew 安装 container,并下载 darwin_arm64 版本的 apple-sandbox二进制文件解压至 .local/bin。运行 apple-sandbox doctor 验证环境,包括 Hypervisor 支持、container服务状态等五项检查。
接着执行 apple-sandbox build 拉取 Node.js 镜像并安装依赖。随后,通过 API 创建 Session,请求体中指定 environment 类型为 self_hosted。API 响应中包含的 remote_url 指向 api.openai.com/connect。值得注意的是,self_hosted 类型不支持通过 API 字段内联传输文件(如 environment.files),必须依靠本地目录挂载。
在任务执行环节,用户在本地 sandboxes 目录下放入一个包含4行数据的 CSV 文件。通过 Agents API 提交事件,要求 Agent 使用 Python 读取该文件、验证数据并计算总和。Agent 在虚拟机内执行脚本,将结果写入 /workspace/outputs/summary.json。由于目录挂载机制,本机可直接通过 cat 命令读取到包含“总和75 verified: true”的结果文件,全程无需下载 Artifact。最后通过 prune 命令清理停止的容器。
“self_hosted 类型的文件进出只能靠你自己去挂载 API 并不支持……这是 Python 在虚拟机里执行,通过挂载写到本机磁盘上的文件。”
结论
apple-sandbox 成功在本地 Mac 上实现了 OpenAI Agents API 的自托管沙箱环境,通过 application-managed 模式解决了无公网 IP 下的启动难题。其核心优势在于利用 Apple container 提供虚拟机级隔离,并通过本地目录挂载实现高效的数据交互。尽管目前存在网络白名单缺失和 SDK 未完善等局限,但它为开发者提供了一种无需云端基础设施即可测试 Agent 工作流的可行方案。Session 的生命周期管理依赖于执行器退出后的容器状态推断,配合 prune 命令实现了自动化的资源清理。这一项目展示了在个人硬件上运行复杂 AI Agent 任务的潜力,尽管目前仍处于早期阶段,但已具备端到端的可用性。