CubeSandboxv0.3.0发布,引入快照、克隆与回滚三组SDK接口,实现沙箱状态管理。快照基于写时复制引擎与增量内存机制,将恢复时间压缩至毫秒级;克隆可从运行中沙箱秒级派生隔离副本;回滚支持原地恢复历史状态。同时新增GoSDK与Web控制台,完善AIAgent在高并发与强化学习场景下的运行时复用与故障隔离能力。
在主流的AI Agent架构中,沙箱服务一直扮演着“安全运行时”的角色,专门负责代码执行和外部工具调用。最近,CubeSandbox迎来了v0.3.0版本,这次更新不只是常规的功能迭代——它是一次关键的架构升级,目标非常明确:解决AI Agent在高并发、长链路和强化学习场景下,一直头疼的运行时复用与故障隔离问题。
这次版本更新,有21位贡献者合入了65个commits。下面,我们先从整体层面看看,v0.3.0在基础设施上到底做了哪些升级。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
在深入讨论最核心的快照能力之前,有必要先看看v0.3.0在基础设施层面的几项重大改进。相比上一版,这一版主要从三个维度完成了自我迭代:
在这些基建更新中,最引人注目的,是围绕Sandbox核心状态管理而设计的“快照、回滚与克隆”体系。
这一版引入的三组SDK接口——snapshot、clone、rollback——构成了完整的Sandbox状态管理能力。
1)快照(snapshot)—— 把当前状态存档
把正在运行中的沙箱的内存、状态、磁盘整体dump到持久化盘,形成独立的快照文件。生命周期与源沙箱解耦:源沙箱销毁后,快照仍然可用;快照ID还能直接当模板,用来批量启动新沙箱。
2)克隆(clone)—— 一个沙箱裂变成N个
一行调用,从一个running中的源沙箱派生出N个完全独立的副本。这里有几个核心特性:
它内置了concurrency=C并发控制和“任一失败自动清理”机制,大批量场景下不会留下孤儿沙箱。
3)回滚(rollback)—— 一行回到过去某一刻
沙箱可原地恢复到之前某次快照的状态,让内存状态和文件系统完全还原。回滚后,sandbox_id不变,沙箱对象不变,不需要重连,不需要重建。
您的浏览器不支持video标签
Cube v0.3.0——快照、克隆、回滚三件套,百毫秒级回滚、秒级裂变出几十个分身
在传统Web服务里,容器启动后通常是无状态的,用完即扔。但AI Agent完全不是这个模型——Agent是被“养”出来的。由此引出两个最常见的痛点:
第一,“养好”的环境怎么复制?并发任务多了需要分身,团队来了新人也要从头养。从零起步重新跑一遍setup脚本,既慢,也根本无法精确还原内存里的上下文、加载好的模型权重和热起来的缓存。靠snapshot → clone,半小时 × N变成毫秒 × N,每个副本都是真正“满级”的Agent环境。

第二,环境被搞坏了怎么办?Agent干活难免出错——装错依赖、误删文件、跑出死循环。传统做法只能销毁容器,从镜像重建,重新pip install,几分钟就这么没了。Rollback让“出错恢复”这件事从分钟级降到百毫秒级,且sandbox_id不变,Agent接着跑。

1)Agentic RL训练 / SWE-Bench评测
# 准备基线环境
base = Sandbox.create(template=TEMPLATE_ID)
base.run_code("# 安装依赖、下载数据集...")
snap = base.create_snapshot()
# 一键派生 100 个独立实例,并发创建
clones = Sandbox.create(template=snap.snapshot_id).clone(n=100, concurrency=10)
2)多策略并行探索
3)Agent试错-重试循环
checkpoint = sb.create_snapshot()
sb.run_code("# 尝试步骤A...")
if 判断失败:
sb.rollback(checkpoint.snapshot_id) # 回到 A 之前
sb.run_code("# 换一种方式重试...") # 继续前进
4)长期环境留存与复用
在传统虚拟化中,快照是一项非常沉重的运维操作。CubeSandbox的快照系统在后端存储层全面采用reflink机制进行数据管理,结合写时复制语义,实现了高效的快照创建与克隆能力。

基于底层的快照技术,我们在API层面包装了克隆/回滚语义。

开发者可以在沙箱运行到关键节点时打一个checkpoint,之后无论环境被改成什么样,一行sb.rollback(checkpoint_id)就能原地还原到那一刻——sandbox_id保持不变,沙箱对象可以接着用:
from cubesandbox import Sandbox
from env import TEMPLATE_ID
# Step 1: 在 v0 状态创建一个基础快照
with Sandbox.create(template=TEMPLATE_ID) as src:
src.run_code("open('/tmp/v.txt','w').write('v0')")
base = src.create_snapshot()
base_id = base.snapshot_id
print(f"base snapshot (v0): {base_id}")
# Step 2: 从基础快照拉起一个新沙箱
sb = Sandbox.create(template=base_id)
print(f"derived sandbox: {sb.sandbox_id}")
# Step 3: 写入 v1,打一个 checkpoint
sb.run_code("open('/tmp/v.txt','w').write('v1')")
checkpoint = sb.create_snapshot()
checkpoint_id = checkpoint.snapshot_id
print(f"checkpoint (v1): {checkpoint_id}")
# Step 4: 写入 v2,确认已生效
sb.run_code("open('/tmp/v.txt','w').write('v2')")
before = sb.run_code("print(open('/tmp/v.txt').read())").logs.stdout
before = before[0].strip() if before else ""
print(f"before rollback: {before!r}")
assert before == "v2"
# Step 5: 回滚到 v1 这个 checkpoint
sb.rollback(checkpoint_id)
print(f"rolled back to checkpoint {checkpoint_id}")
# Step 6: 验证状态已恢复为 v1(sandbox_id 保持不变)
after = sb.run_code("print(open('/tmp/v.txt').read())").logs.stdout
after = after[0].strip() if after else ""
print(f"after rollback: {after!r}")
assert after == "v1", f"expected 'v1', got {after!r}"
print("OK: rollback restored state to checkpoint (v1)")
# Cleanup
sb.kill()
Sandbox.delete_snapshot(checkpoint_id)
Sandbox.delete_snapshot(base_id)
print("snapshots deleted")
在强化学习或多路径决策中,可以通过clone接口从同一个源沙箱一键派生出多个环境,每个环境物理隔离、互不干扰,又都继承了源沙箱的全部运行时状态。下面的示例克隆N份后,逐一校验每个实例都继承了源沙箱写入的标记文件:
import os
from cubesandbox import Sandbox
from env import TEMPLATE_ID
N = int(os.environ.get("FORK_N", "10"))
CONCURRENCY = int(os.environ.get("FORK_CONCURRENCY", "5"))
src = Sandbox.create(template=TEMPLATE_ID)
src.run_code("open('/tmp/origin.txt','w').write('I am from sandbox a')")
print(f"src sandbox: {src.sandbox_id}")
# ★ 并发克隆 —— SDK 内部把 Sandbox.create fan-out 出去
clones = src.clone(n=N, concurrency=CONCURRENCY)
print(f"cloned {len(clones)} sandboxes (concurrency={CONCURRENCY})")
# 验证每个 clone 都继承了源沙箱的状态标记
expect = "I am from sandbox a"
ok = 0
for i, sb in enumerate(clones):
r = sb.run_code("print(open('/tmp/origin.txt').read())")
marker = r.logs.stdout[0].strip() if r.logs.stdout else ""
if marker == expect:
ok += 1
print(f" clone[{i:>2}] {sb.sandbox_id} marker={marker!r}")
print(f"\n{ok}/{N} clones inherited the origin marker")
assert ok == N, "some clones failed to inherit state"
# Cleanup
src.kill()
for sb in clones:
sb.kill()
print("all sandboxes killed")
需要注意的是,虽然CubeSandbox深度兼容E2B协议,但E2B的原生API中并没有这两组接口。Cube开发团队通过cubesandbox SDK在应用层完成了这些能力的桥接,开发者可以在不修改E2B兼容代码的前提下,无缝解锁这些高级状态管理原语。
除了SDK层的snapshot / rollback / clone API,本次我们还同步开源了一套基于CubeSandbox的OpenClaw Web管理(预览版)——把这一版的核心能力做成了点几下鼠标就能完成的可视化体验:实时查看每个沙箱的存档时间线、一键回到过去某个checkpoint、瞬间裂变多个OpenClaw、批量管理沙箱生命周期。原来需要写脚本调SDK才能玩转的“时光机”和“分身术”,现在在浏览器里点几下就能跑通。

接下来的版本里,我们会把“沙箱安全”这件事再往上推一层——从今天的“隔离Agent在哪里跑”,升级到“管控Agent能碰到什么”:
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述