章节导航 第 10 章 / 共 21 章
Runtime 系统:沙箱的一切
三层抽象、Provider 家族、Runtime 家族、invoke 统一 RPC、Executor 体系、Client/Server 分离
Runtime 系统是 Nexus 最复杂的部分
如果说注册系统是骨架,Runtime 系统就是心脏。它回答一个核心问题:Agent 的动作在哪里执行,以及怎么执行。
Runtime 系统占了 Nexus 代码的约 40%——nexus/runtime/ 目录有 91 个文件。
三层抽象
ExecutionContext
│ ctx.get_runtime('main')
▼
RuntimeProvider
│ provider.acquire('main')
▼
Runtime
│ runtime.invoke() / runtime.run_command() / runtime.browser_goto()
▼
实际环境(Docker 容器 / 远端沙箱 / 本地进程 / Android 设备)
ExecutionContext(消费者)
只管”我要一个 Runtime”,不关心它从哪来。同名 Runtime 只获取一次,退出时统一释放。
RuntimeProvider(工厂)
决定”环境怎么来”——启动容器、申请沙箱、连接设备。每种基础设施一个 Provider。
Runtime(客户端接口)
对上层暴露统一的操作接口。Runtime 继承了 ExecutorMixin,提供类型化的便捷方法(run_command、upload_file、browser_goto 等)。
Provider 家族
| Provider | 底层环境 | 返回的 Runtime | 适合场景 |
|---|---|---|---|
local | 当前 Python 进程 | LocalRuntime | 本地调试 |
docker | 本地 Docker + Nexus Server | RemoteRuntime | 本地开发 |
gongfeng | 远端沙箱服务 | RemoteRuntime | 生产评测 |
ags | 腾讯云 AGS(多种模式) | RemoteRuntime 或专用 Runtime | 云端弹性 |
android_websocket | WebSocket Android 沙箱 | WebSocketAndroidRuntime | Android GUI |
android_cloudtest | CloudTest 真机 | CloudTestAndroidRuntime | 真机交互 |
AGS 是特例——它是唯一一个同时支持”通用模式”(返回 RemoteRuntime)和”原生模式”(返回 AGSBrowserRuntime / AGSCodeInterpreterRuntime / AGSOSWorldRuntime)的 Provider。三个正交维度:
provision_mode:control_plane / template(实例怎么拿到)launch_mode:nexus_server / native(沙箱里跑什么)interface_mode:nexus / raw(返回什么接口形态)
Runtime 家族
通用 Runtime
| Runtime | 传输 | invoke | call_tool | Worker Venv |
|---|---|---|---|---|
LocalRuntime | 进程内直接调用 | ✅ | ✅ | ❌ |
RemoteRuntime | HTTP + Socket.IO | ✅ | ✅ | ✅ |
LocalRuntime 只有 49 行——resolve 函数、unpack 参数、直接调用。适合调试。
RemoteRuntime 统一了旧版 HttpRuntime 和 SocketIoRuntime(553 行):
- HTTP 做 RPC(
POST /api/v1/invoke) - Socket.IO 做实时事件流(日志、Span、invoke 完成通知)
- HTTP long-poll:
Prefer: wait=Nheader 控制等待时间 - 大 payload 走 blob sideband(超过 1MB 的数据通过单独的 HTTP 端点传输)
专用 Runtime
AGS 原生模式和 Android 设备会返回专用 Runtime,只实现部分 Executor 子集:
AGSBrowserRuntime:只有browser_*方法AGSCodeInterpreterRuntime:只有run_commandWebSocketAndroidRuntime:只有gui_*方法
invoke():统一 RPC 原语
v1.0 之前有三个独立的 RPC 接口:call_function、call_tool、call_executor。v1.0 统一为一个 invoke()。
# 三种调用方式
await runtime.invoke(InvokeRequest.build(my_func, arg1, arg2)) # 完全控制
await runtime.invoke('mod.sub::func', arg1, arg2) # import path
await runtime.invoke(my_func, arg1, arg2) # 函数对象
wire format(InvokeRequest):
class InvokeRequest(BaseModel):
request_id: str | None
import_path: str # 'module.path::func_name'
payload: str # base64(pickle.dumps((args, kwargs)))
payload_ref: str | None # 大 payload 的 blob ID
venv_id: str | None # Worker Venv 路由
trace_context: RemoteTraceContext | None # 分布式追踪
关键设计:参数通过 pickle 序列化(不是 JSON),这意味着可以传递任意 Python 对象。但函数通过 import_path 定位(不是 dill 序列化),这避免了 dill 的安全和兼容性问题。
Executor 体系
Runtime Server 提供 7 类 Executor:
| Executor | 文件大小 | 能力 |
|---|---|---|
command | 3.7KB | 执行 shell 命令 |
file | 3.5KB | 文件上传/下载 |
terminal | 18KB | tmux 终端会话管理 |
jupyter | 11KB | IPython/Jupyter 会话 |
browser | 75KB | Playwright 浏览器自动化(最大) |
gui | 0.2KB | GUI 操作(Android 等设备) |
mcp | 8.5KB | MCP Server 代理管理 |
所有 Executor 遵循统一的 Request/Response 模型:
class ExecutorRequest(BaseModel, Generic[ResponseT]):
executor_name: ClassVar[str] # 自动路由到对应 Executor
response_type: ClassVar[type] # 关联的 Response 类型
class RunCommandRequest(ExecutorRequest[RunCommandResponse]):
executor_name = 'run_command'
command: str
cwd: str | None
timeout: float = 180
ExecutorMixin 的便捷方法(如 runtime.run_command())构造 Request、调用 call_executor、反序列化 Response——全部类型安全。
Client/Server 分离
Nexus 1.0 的一个重要重构:将 Runtime 通信层从单体 protocol/ 拆分为 client/ 和 server/。
核心原则:按部署边界切分。
client/:Host 侧运行——RemoteRuntime、LocalRuntime、packagingserver/:沙箱内运行——FastAPI Server、Worker、LLM Proxy、Venv Managermodels.py:两端共享的协议模型(InvokeRequest/Response)executors/models/:Request/Response 的 Pydantic 模型(两端共享的协议契约)
这种分离的好处:Runtime 镜像不需要安装 Host 侧的依赖(如 rich、textual 等 CLI 工具)。
沙箱生态对比
Nexus 的 Runtime 系统不是唯一的选择。2026 年 AI Agent 领域出现了两个重要的沙箱基础设施:
| 维度 | Nexus 内置 Provider | Docker Sandboxes | OpenSandbox(opensandbox-group) | Tencent CubeSandbox |
|---|---|---|---|---|
| 定位 | 评测框架 | AI Coding Agent 安全环境 | 通用沙箱平台(CNCF Landscape 收录,2026-06) | AI Agent 代码执行沙箱(RustVMM + KVM,E2B SDK 兼容) |
| 隔离级别 | 容器(共享内核) | microVM(独立内核,自建跨平台 VMM——非 Firecracker,macOS Hypervisor.framework / Windows WHP / Linux KVM) | gVisor/Kata/Firecracker(可选) | 硬件级 microVM(自研 RustVMM,非 Firecracker)+ eBPF 网络隔离(CubeVS) |
| 调度模型 | 单实例 | 单实例 | Pool CRD 预热 + BatchSandbox O(1) | 自研调度器(CubeMaster/Cubelet),单节点上千沙箱 |
| 批量交付 | 手动 | 手动 | 1000 实例 3.5 秒 | 冷启动 ~60ms(平均),内存 <5MB |
| Agent 支持 | 框架级 Executor | 6+ Agent(Claude Code/Copilot/Codex/Gemini/Kiro/Agent,Devin 已入列官方文档) | 官方 README 的 Examples 表(2026-10-06 抓取)列 4 类用例——Coding agents / Code execution and data analysis / Browser and desktop automation / Agent evaluation;Features 表另有一行「Local to cluster」点名 resource pools 与 batch creation 支持 agent evaluation 与 RL training 负载。最新发布 1.1.0(2026-09-21),1.1.1-rc.1 于 2026-09-28 | E2B SDK 兼容(改 E2B_API_URL 环境变量即可迁移) |
| 治理 | 无 | Docker AI Governance(集中控制:执行策略/网络/凭证/MCP 工具) | K8s 策略 | 凭据保险库 + 出口网关 |
| 协议 | 自定义 HTTP + Socket.IO | Docker CLI | 四层架构(SDKs/Specs/Runtime/Instances)+ credential vault(凭证不暴露给沙箱负载)+ opensandbox-mcp MCP Server | E2B API 兼容 |
| 配置管理 | 无版本化 | Sandbox Kits——版本化蓝图(预装工具/环境变量/文件路径/网络域/凭证规则);产品侧 2026-07-01 GA,规范侧独立仓库 docker/sandbox-kit-spec 现处 v3.0.0-m.8(2026-10-02) | 无 | 模板(template) |
| 状态持久化 | 无(Worker Venv 可复用,环境状态不保留) | 无官方 checkpoint(沙箱为一次性设计,删除即重建) | 无(需自建) | CubeCoW 快照/克隆/回滚(XFS reflink + FICLONE,增量脏页追踪)+ AutoPause/Resume(空闲零资源挂起、请求到达透明唤醒,百毫秒级)+ 跨机暂停恢复(Preview,S3 快照后端) |
| 许可 | Apache 2.0 | 商业产品 | Apache 2.0 | Apache 2.0 |
Nexus 的定位是”评测框架”而非”沙箱基础设施”——沙箱层应可插拔对接。Docker Sandboxes 的 microVM 隔离提供更强的安全边界,OpenSandbox 的 K8s 池化调度提供更高的批量交付效率。
Docker Sandboxes 放弃 Firecracker 的原因值得注意:Firecracker 为 Linux/KVM 设计,无 macOS/Windows 原生支持。自建跨平台 VMM 使用 OS 原生 hypervisor,单一代码库三平台,零转换层。这对 Nexus 在不同平台选择沙箱方案有参考价值——如果需要 microVM 隔离但不想绑定 Linux/KVM,跨平台 VMM 是更灵活的选择。
腾讯 CubeSandbox 代表了”性能优先”的另一个技术路线:同样放弃 Firecracker,但走的是自研 RustVMM + KVM 的硬件级 microVM,配合自研 eBPF 网络隔离(CubeVS)和自研调度器(CubeMaster/Cubelet),在隔离、速度、密度三个维度同时逼近极限。其 E2B SDK 兼容策略(改 E2B_API_URL 环境变量即可零成本迁移)尤其值得关注——它通过”蹭生态”的方式降低了存量 E2B 用户的迁移门槛。对 Nexus 的启示:如果评测场景需要高频创建/销毁沙箱(如 RL 训练的逐 episode 环境重建),CubeSandbox 的 ~60ms 冷启动 + 单节点上千沙箱密度是比 Docker 容器更优的性能选项。
v0.5.0(2026-07-03)后官方另有三项与评测/RL 直接相关的能力:
- AutoPause/Resume——空闲沙箱自动快照挂起(零资源消耗),下次请求透明恢复,百毫秒级唤醒。长跑评测的空转成本可大幅下降。
- 快照 · 克隆 · 回滚——基于 CubeCoW(XFS reflink +
FICLONEioctl)的 Copy-on-Write 引擎与增量脏页追踪,百毫秒级检查点,可从同一检查点分叉出多条探索分支——这正是 RL rollout 需要的形态。 - 跨机暂停与恢复(Preview)——配合 S3 快照后端,已暂停的沙箱可在集群内任意兼容节点恢复,节点维护或故障不再困住长跑任务。
性能细分(官方口径):50 并发创建平均 67ms / P95 90ms / P99 137ms,单台 96 核可跑 2000+ 沙箱。部署上有一个硬约束:普通云 CVM 需装其 PVM 宿主内核(基于页表的嵌套虚拟化,不依赖把 Intel VT-x/AMD-V 暴露给 guest),且仅 x86_64,ARM64 需原生 KVM 物理机。
v0.7.1(2026-09-11)与 v0.7.2(2026-09-24)改写了上面三处口径:
- 外部挂载也能快照了——v0.7.1 起,快照 / 恢复 / 回滚 / 克隆覆盖 Host Mount 与 Volume Plugin(#1654、#1656),带外部挂载的沙箱不再被排除在检查点体系之外。同版本另有控制面高可用(独立 template-center 使 CubeMaster 可多副本)与同桶跨机快照恢复改用对象存储服务端拷贝(#1663)。
- 跨机恢复进入秒级——v0.7.2 把跨机恢复的读路径改为整对象本地缓存 + 小读合并 + 并发预算收敛,官方口径为默认 MinIO 配置下跨机恢复 / 从快照创建 1 秒内达成 running。上文的”Preview”应按下述版本限定理解。
- 密度口径需带版本——v0.7.2 新增空闲 guest 内存自动回收,节点内存占用随沙箱真实用量动态回落。“2000+ 沙箱 / 96 核”应理解为内存回收开启后的密度,脱离版本引用会高估旧版的实际密度。
- v0.7.2 另新增 JuiceFS 卷插件:沙箱可挂载 JuiceFS 作为持久卷,具备完整 POSIX 语义。这与 Nexus 的
/nix volume(一个卷挂给任意镜像)是同一形态,只是换到了 microVM 侧且带快照——该形态不再是 Nexus 独有,详见文末分析段。
⚠️ 上述四条均取自
TencentCloud/CubeSandbox官方 release notes 正文(2026-10-06 复核版本与日期;v0.7.2 仍为最新稳定条目)。
把 OpenSandbox 的 RL training 负载定位与 CubeSandbox 的快照/分叉能力放在一起看,可以读出一个方向:沙箱生态正从”跑一次就扔”整体转向”可 checkpoint 的长生命周期环境”。(此为本书基于上述官方材料的分析推论,非厂商原话。)
但支撑这个结论的对照关系在 2026-09 之后变了。原先的读法是:Nexus 的 /nix volume 天然支持 checkpoint 跨镜像复用,而外部挂载的沙箱做不到快照——这是一条 Nexus 的独有优势。现在这条优势的后半段不成立:CubeSandbox v0.7.1(2026-09-11)起 Host Mount 与 Volume Plugin 已能快照 / 恢复 / 回滚 / 克隆,v0.7.2(2026-09-24)又给出了带完整 POSIX 语义的 JuiceFS 卷插件——“共享只读卷 + 快照”正从 Nexus 的自研技巧下沉为沙箱层的通用能力。
因此选型时该计价的对象要换一格:不是”能 checkpoint”(这条正在变成标配),而是”自包含、零网络依赖”——/nix 卷不依赖任何外部存储服务即可挂给任意 x86_64 Linux 镜像,JuiceFS 插件走的是分布式文件系统路径,二者在离线/边缘场景下的可用性并不等价。(此段为本书分析推论 📌。)同一结论同步写入 Ch11 的 Checkpoint 一节,两处须一起读。
⚠️ 事实核查注:提案将 CubeSandbox 开源时间标为 2026-08-04、冷启动标为 “P95 78.3ms”,但多源交叉验证显示 CubeSandbox 于 2026 年 4 月已开源(GitHub TencentCloud/CubeSandbox),冷启动以”平均 ~60ms”表述为主,P95 78.3ms 未在权威源得到确认,故本章采用”~60ms(平均)“并淡化具体开源日期。OpenSandbox 的 CNCF Landscape 收录时间章节原记为 2026-06,与提案的 2026-08-04 不一致,沿用章节原值并补充其”统一 Docker/gVisor/Kata/Firecracker API 抽象”定位。
池化调度与批量交付
大规模 Agent 评测场景(如 SWE-bench 全量)需要数百个并发沙箱。传统 K8s 调度通过 etcd 写入,1000 个实例需要约 76 秒。OpenSandbox 的 Pool CRD 预热池化 + BatchSandbox CRD O(1) 调度将 1000 实例交付时间压缩到约 0.92 秒(5000 实例仅需 10 秒)。
Nexus 的 AGS Provider 支持云端弹性,但当前没有公开的池化调度机制。如果需要运行大规模评测,可能需要对接 OpenSandbox 的 K8s 运行时,或自建类似的预热池化方案。
安全隔离等级对比
Client/Server 分离提供了基本的部署边界,但隔离的安全强度取决于底层运行时:
| 隔离级别 | 实现 | 内核共享 | 攻击面 | 适用场景 |
|---|---|---|---|---|
| 进程隔离 | LocalRuntime | 共享 | 最广 | 本地调试 |
| 容器隔离 | Docker Provider | 共享 | 中等 | 开发/标准评测 |
| microVM 隔离 | Docker Sandboxes / gVisor | 独立 | 最窄 | 不可信代码执行 |
RUNTIME Tool 在容器内执行已经有基本隔离,但对于不可信代码(如 Agent 生成的代码、MCP 工具的输出),容器隔离不够——共享内核意味着内核级漏洞可以逃逸。MCP 配置篡改攻击(CVE-2026-30615,Windsurf 1.9544.26 的 prompt injection 导致本地 MCP 配置被改写并自动注册恶意 server,CVSS v3.1 8.0 / HIGH,2026-04-15 披露)进一步强化了这一需求:当 Agent 调用不可信的 MCP 工具时,microVM 或 gVisor 是更安全的选择。
2026 年 2 月,Microsoft 披露 Semantic Kernel 的两个漏洞,CVSS v3.1 均为 9.9 / CRITICAL:
- CVE-2026-25592(2026-02-06,.NET SDK):
SessionsPythonPlugin存在任意文件写,修复于Microsoft.SemanticKernel.Core1.71.0;缓解措施是对DownloadFileAsync/UploadFileAsync的localFilePath做 allowlist 校验。 - CVE-2026-26030(2026-02-19,Python SDK):
InMemoryVectorStore的 filter 功能存在远程代码执行,修复于python-1.39.4;workaround 是生产环境不要用InMemoryVectorStore。
两者成因都不是 prompt injection,而是框架对传入参数缺少校验:前者未校验文件读写插件的本地路径,后者未在向量库过滤器上做安全约束。
⚠️ 更正说明(2026-09-15):本节此前写作”2026 年 5 月…两个 RCE 漏洞…Prompt Injection 可升级为 Host 级代码执行”。经 NVD 官方记录核实,时间与漏洞类型均有误,“prompt injection 升级”这一攻击链在官方成因描述中无支撑。此处保留原始表述供对照。
修正后的论断反而更贴合本章主题:漏洞既不在模型侧,也不在被调工具侧,而在框架把 LLM 输出转成系统调用的那一段胶水代码。它与 CVE-2026-30615 构成真正的双维度安全叙事——(1) Agent 框架内部工具调用的隔离需求;(2) 外部协议工具(MCP)的执行边界。
参考:Docker Sandboxes 五层纵深防御
Docker Sandboxes(Docker Desktop 4.58+ 起提供 microVM 版本;sbx CLI 最近一次发布为 v0.47.0(2026-10-05),核于 2026-10-06)实现了五层安全隔离,对 Nexus 设计 AGS Provider 的安全模型有直接参考价值:
Hypervisor 层——独立内核,VM 删除即全清理(无残留风险)。跨平台 VMM(非 Firecracker)。
网络层——sandbox 间不可通信、不能访问 host localhost、allow/deny list 策略、原始 TCP/UDP/ICMP 阻断。
Docker Engine 层——sandbox 内独立 Docker daemon,agent 的
docker build不接触 host daemon。Workspace 层——direct mount 默认读写 / —clone 只读挂载 + 私有克隆。clone 模式解决了”agent 可以修改
.git/hooks/等触发代码执行的文件”的安全风险。⚠️ 但这一层在 2026 年已被实际绕过:CVE-2026-18171(CVSS v4.0 5.7 / MEDIUM,2026-08-12 披露)。按 NVD 原文,Docker Sandboxes (sbx) 只把宿主挂载的只读意图应用到客机内的容器 bind,底层 virtio-fs 的宿主侧授权却以”无访问模式”加入共享允许列表,目录在其共享导出路径上仍可写——沙箱内的非特权代码推导出该路径后,就能写入运维本以只读方式挂载的宿主目录。教训是:挂载层防护必须按”同一宿主路径的所有可达路径”审计,而不是按挂载点逐个审计。Nexus 若做 workspace 只读保护,应先枚举容器内所有宿主目录导出点。(受影响版本区间 0.35.0–0.37.1、修复于 0.38.0 一说来自二手披露报道,NVD 记录未列版本范围,此处标为待核实。)
Credential Proxy——VM 不持有 API 密钥,通过 host HTTPS proxy 注入凭证,TLS 终止在 host 侧完成。
两起修复连起来看:Docker Sandboxes 0.42.0(2026-09-07)的 Bug Fixes 中另有一条——“Fixed a vulnerability where a sandboxed process could get the daemon to open a host D-Bus transport and execute an arbitrary command on the host.” 连同上面的 CVE-2026-18171,构成一个明确的信号:microVM 的隔离边界仍在被持续打穿与修补。本章”容器隔离不够”的结论不变,但论据应从”Docker 是标杆、照抄即可”改为”连 Docker 自家的 microVM 都在持续修逃逸——选型时要看的是厂商的响应速度与历史,而不是某一层的宣传语”。
实测 354 页 Astro 博客构建中 sandbox 比宿主更快(1:28.58 vs 1:44.62)——microVM 的开销在实际工作负载中可忽略。
本轮未采纳与待核实(2026-10-06)
| 项 | 处置 | 原因 |
|---|---|---|
opensandbox-group/fast-sandbox(K8s 高性能沙箱管理系统)作为池化方向的观察对象 | 未采纳 | 提案置信度为低:仅凭仓库自述与 push 时间(2026-09 起活跃、早期项目),未读代码与文档,不足以进入选型结论 |
| Sandbox Kits 规范 v3 的具体破坏性变更范围 | 未采纳 | 本轮只复核了 docker/sandbox-kit-spec 的版本号与日期(v3.0.0-m.8 / 2026-10-02),未读 spec 正文;章内因此只写”规范仍在里程碑迭代”,不写”v3 改了什么” |
| 四个 CVE(CVE-2026-30615 / CVE-2026-25592 / CVE-2026-26030 / CVE-2026-18171) | 未复检 | 沿用 2026-09-15 已核实状态 |
| Docker Sandboxes “受影响版本区间 0.35.0–0.37.1、修复于 0.38.0” | 维持待核实 | 该说法来自二手披露报道,NVD 记录未列版本范围,本轮仍未获得一手佐证 |