第 10 章 第二部分:架构原理

Runtime 系统:沙箱的一切

三层抽象、Provider 家族、Runtime 家族、invoke 统一 RPC、Executor 体系、Client/Server 分离

Nexus Runtime 沙箱 Docker AGS RPC

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 ServerRemoteRuntime本地开发
gongfeng远端沙箱服务RemoteRuntime生产评测
ags腾讯云 AGS(多种模式)RemoteRuntime 或专用 Runtime云端弹性
android_websocketWebSocket Android 沙箱WebSocketAndroidRuntimeAndroid GUI
android_cloudtestCloudTest 真机CloudTestAndroidRuntime真机交互

AGS 是特例——它是唯一一个同时支持”通用模式”(返回 RemoteRuntime)和”原生模式”(返回 AGSBrowserRuntime / AGSCodeInterpreterRuntime / AGSOSWorldRuntime)的 Provider。三个正交维度:

  • provision_mode:control_plane / template(实例怎么拿到)
  • launch_mode:nexus_server / native(沙箱里跑什么)
  • interface_mode:nexus / raw(返回什么接口形态)

Runtime 家族

通用 Runtime

Runtime传输invokecall_toolWorker Venv
LocalRuntime进程内直接调用✅✅❌
RemoteRuntimeHTTP + 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=N header 控制等待时间
  • 大 payload 走 blob sideband(超过 1MB 的数据通过单独的 HTTP 端点传输)

专用 Runtime

AGS 原生模式和 Android 设备会返回专用 Runtime,只实现部分 Executor 子集:

  • AGSBrowserRuntime:只有 browser_* 方法
  • AGSCodeInterpreterRuntime:只有 run_command
  • WebSocketAndroidRuntime:只有 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文件大小能力
command3.7KB执行 shell 命令
file3.5KB文件上传/下载
terminal18KBtmux 终端会话管理
jupyter11KBIPython/Jupyter 会话
browser75KBPlaywright 浏览器自动化(最大)
gui0.2KBGUI 操作(Android 等设备)
mcp8.5KBMCP 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、packaging
  • server/:沙箱内运行——FastAPI Server、Worker、LLM Proxy、Venv Manager
  • models.py:两端共享的协议模型(InvokeRequest/Response)
  • executors/models/:Request/Response 的 Pydantic 模型(两端共享的协议契约)

这种分离的好处:Runtime 镜像不需要安装 Host 侧的依赖(如 rich、textual 等 CLI 工具)。

沙箱生态对比

Nexus 的 Runtime 系统不是唯一的选择。2026 年 AI Agent 领域出现了两个重要的沙箱基础设施:

维度Nexus 内置 ProviderDocker SandboxesOpenSandbox(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 支持框架级 Executor6+ 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-28E2B SDK 兼容(改 E2B_API_URL 环境变量即可迁移)
治理无Docker AI Governance(集中控制:执行策略/网络/凭证/MCP 工具)K8s 策略凭据保险库 + 出口网关
协议自定义 HTTP + Socket.IODocker CLI四层架构(SDKs/Specs/Runtime/Instances)+ credential vault(凭证不暴露给沙箱负载)+ opensandbox-mcp MCP ServerE2B 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.0Apache 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 + FICLONE ioctl)的 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.Core 1.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 的安全模型有直接参考价值:

  1. Hypervisor 层——独立内核,VM 删除即全清理(无残留风险)。跨平台 VMM(非 Firecracker)。

  2. 网络层——sandbox 间不可通信、不能访问 host localhost、allow/deny list 策略、原始 TCP/UDP/ICMP 阻断。

  3. Docker Engine 层——sandbox 内独立 Docker daemon,agent 的 docker build 不接触 host daemon。

  4. 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 记录未列版本范围,此处标为待核实。)

  5. 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 记录未列版本范围,本轮仍未获得一手佐证