OpenDsec 自托管沙箱支持运行态分叉
OpenDsec 是采用 AGPL 许可的自托管沙箱,面向强化学习 rollout 和需要执行代码的代理,支持复制包含内存的环境状态。演示展示了创建 Firecracker 微虚拟机并分叉四份,作者报告完整创建 API 调用耗时约 0.16 秒。
AI 深度解读
OpenDsec 想解决的是 AI 编程背后的执行环境问题:几千个智能体同时装包、跑测试、访问网络,训练中断时一起暂停,需要探索不同路径时,直接复制当前进程和内存。作者给出的方案,是一套部署在自有机器上的沙箱基础设施。
它最有意思的能力是带内存分叉,以及按训练任务暂停整批沙箱。不过,文中的速度和规模数据来自作者自有裸金属机器;项目仍处于 0.x,能跑通演示与适合团队长期运维,还隔着需要验证的一段路。
为什么复制镜像,还不够支持智能体探索
从同一个镜像启动两个环境,只能保证初始文件相同。已经导入的 Python 模块、正在运行的进程、打开的端口,都得重新准备。智能体走到某一步后想尝试不同策略,重复初始化会增加等待,也未必能准确重建当时的状态。
OpenDsec 的 fork(count=N) 会短暂暂停源沙箱,再生成包含内存状态的副本。作者称,源环境暂停约 10 ms;同节点副本共享内存页,跨节点副本直接从源节点拉取快照。
带内存分叉保存的是执行到一半的现场,而不只是启动环境的配方。
下面是原文完整的客户端示例:创建 Firecracker microVM,执行得到 42,再分叉出四份副本,最后停止全部环境。
import asyncio, time
from opendsec import DSecClient, DSecRunArgs
async def main():
async with DSecClient() as client:
t = time.perf_counter()
sb = await client.run_sandbox(DSecRunArgs(backend="microvm", image="root/py:3.12"))
print(f"ready in {time.perf_counter() - t:.2f}s (whole API call: placement + boot)")
print((await sb.run_shell("python3 -c 'print(6*7)'")).stdout.strip())
t = time.perf_counter()
forks = await sb.fork(count=4) # 包含内存状态的副本
print(f"forked 4 in {time.perf_counter() - t:.2f}s")
await asyncio.gather(*(s.stop() for s in [sb, *forks]))
asyncio.run(main())
重点看 fork(count=4):四份副本继承当前状态。这个例子没有展示复杂应用分叉后的行为,不能据此推断已有数据库连接或其他外部会话也能无缝复制。
录像剪掉了六分钟构建安装过程,后续按真实速度播放。其中 0.16 s 是客户端测得的完整 API 调用时间,包含调度放置、启动,以及虚拟机内 agent 就绪。
快到什么程度,要先分清测量对象
作者给出的 microVM 指标包括:启动约 0.1 s,从内存快照创建约 55 ms,从暂停状态恢复约 50 ms。这几个数字对应不同路径,不能混成一个「启动耗时」。
分叉也受底层文件系统影响。作者测得 XFS 上约 0.1 s,因为可以通过 reflink 复制内存文件;ext4 需要复制文件内容,约为 1 s。reflink 可以理解为先共享文件数据,后续修改时再处理差异。
规模测试同样需要连着条件读:一台 384 线程节点在 37 s 内承接了 5120 个 microVM 的突发创建;双节点集群一次承接 8192 个容器,没有失败。原文没有提供这些环境运行实际业务代码时的吞吐、延迟和资源占用。
这些是作者实测,但不是跨环境承诺。
面向训练抢占,OpenDsec 还支持一次暂停同一任务下的全部沙箱,把内存推入 swap,之后恢复。这能保留训练任务的执行现场;不过,原文没有给出整批暂停与恢复的耗时,也没有交代对应的存储压力。
自托管的价值,在于统一执行入口和运维控制
OpenDsec 参考了 DeepSeek Elastic Compute(DSec)论文,包括无状态 apiserver、嵌套项目与配额、汇总调度状态的 watcher,以及 power-of-k 放置策略。调度器从候选节点中选择位置,最终是否接纳,仍由节点判断。
它是独立项目,与 DeepSeek 无关联,也不包含 DeepSeek 的代码。网络策略采用默认拒绝,通过 nftables 和 DNS proxy 实现;镜像支持 NFS、CephFS、JuiceFS 等共享文件系统,没有沿用论文中的 3FS。
同一套 API 覆盖 Firecracker microVM、容器和完整 QEMU VM,统一提供 Exec、文件、进程、PTY 和 HTTP 访问。运维方面,作者列出了组件间 mTLS、Raft 复制的 IAM、Prometheus 指标与告警、分阶段升级及自动回滚、离线安装,并称组件重启升级不会影响运行中的沙箱。
已有 E2B 客户端也有迁移入口:修改 E2B_API_URL、E2B_SANDBOX_URL、E2B_API_KEY 三个环境变量。作者称 E2B 官方 Python 和 JS SDK 检查已通过,但没有展开检查范围。
部署要求 Linux x86_64、systemd、cgroup v2。microVM 还需要 /dev/kvm,否则只能使用容器。作者只验证了 Ubuntu 24.04,其他发行版、真实 GPU、多节点 Kubernetes 均未测试。
安装流程使用 make、git、python3-venv 和 go1.27.3.linux-amd64.tar.gz,由 deploy/quickstart.sh 构建组件、校验固定哈希后下载 Firecracker 与 guest kernel、配置 CA 和 systemd 服务,并导入 Docker Hub 的 python:3.12。Python SDK 通过 .venv/bin/pip install ./sdk/python 安装,加载 /root/opendsec-ops/demo.env 后运行 sdk/python/examples/quickstart.py;卸载命令是 deploy/quickstart.sh --uninstall。
我的判断
我认可它把「执行代码」当作独立基础设施来做,尤其是带内存分叉和任务级暂停。这两项能力直接对应智能体探索分支、训练被抢占的问题,比单纯缩短容器启动时间更贴近作者的需求。
但普通团队是否需要整套系统,要看实际负载。只想让 AI 跑一次测试,常规容器或托管沙箱可能已经够用;需要大量并发、保留执行现场,并且必须自行掌控机器时,OpenDsec 才更有吸引力。这是需求匹配判断,原文没有提供成本对照数据。
原文提到了 Firecracker、gVisor 与容器的比较,却没有展开隔离、内存和兼容性的测量结果,不能据此判断谁全面占优。
还要把成熟度和许可证算进去:0.x 的接口可能在 1.0 前变化,且没有托管版。服务端采用 AGPL-3.0;Python SDK、Go client 和 API 定义采用 Apache-2.0。作者说明,仅调用 OpenDsec 的程序不受 AGPL 约束,闭源修改另有商业许可。
能拿来做什么
- 如果已有基于 E2B JS SDK 的代码执行流程,可以先修改三个环境变量,在测试环境核对实际用到的执行、文件和 HTTP 能力,确认兼容范围。
- 如果智能体需要从同一执行状态探索多条路径,可以用
fork(count=N)做小规模验证,重点观察进程、端口和外部连接的行为。 - 如果准备部署,先检查
/dev/kvm、cgroup v2 和文件系统,再测团队自己的初始化、分叉与测试任务耗时,避免直接套用作者的裸金属数据。 - 如果训练任务经常被抢占,可以验证整批暂停、swap 占用与恢复时间,确认保存现场的收益能覆盖存储和运维成本。