E2B on Azure VM
自己运营开源 Runtime 与 Firecracker;控制命令、文件、环境和回收。
我用独立 Device VM 模拟端侧,把文档工具、多轮模型对话、临时代码执行和可恢复工作区放在四个并列纵向框中。四条接口独立选择,不串联,也不同时扇出执行。ACA Sandboxes 使用真实原生 SDK,演示可信命令、文件校验、Disk 停止/恢复及快照恢复;不把第三条 Session Pool 换名当作第四条。
自己运营开源 Runtime 与 Firecracker;控制命令、文件、环境和回收。
托管 Agent 容器、模型与平台对话历史;重点是 Agent,而非通用执行器。
池化临时执行;本 Demo 使用 PythonLTS,状态在当前会话内复用。
独立 SandboxGroups,真实工作区、文件、Disk 生命周期与快照恢复;不是第三条池的别名。
这里只播放协议步骤,不创建任务、不冒充运行日志。真实执行请回到 Device 页面。
| 维度 | E2B on VM | Foundry Hosted Agent | Dynamic Sessions | ACA Sandboxes |
|---|---|---|---|---|
| 核心定位 | 自运营的通用隔离执行基础设施 | 托管 Agent 应用、推理与编排 | 按 identifier 路由的临时执行会话 | 可编程、可恢复的隔离工作区 |
| 当前实现 | 真实开源 Embed;base 模板 | 真实 planning-agent 容器;GPT-4.1-mini | PythonLTS 内置解释器;非自定义容器 | eastus2 原生 SandboxGroups;SDK 0.1.0b4;可信工具、文件 SHA-256、Disk 停止/恢复、快照/restore 与回收 |
| SDK / 使用入口 | 官方 e2b;create → commands/files → kill | AIProjectClient + Responses;conversation → 多轮回复 | 原生 REST;executions / files / session;池自动分配 | azure-containerapps-sandbox;begin_create_sandbox → exec/files → suspend/resume/delete |
| 控制资源 / 数据面 | 自己的 VM / upstream API 和 client-proxy | Foundry account/project/agent version / Agent Responses | Microsoft.App/sessionPools / dynamicsessions.io | Microsoft.App/sandboxGroups / management.azuredevcompute.io;不调用旧 sessionPools 路径 |
| 状态边界 | 本 Demo 完成后 Kill;Blob 保留结果,端侧保存状态。上游其他能力另测 | conversation 是历史;compute session 是容器与文件系统。默认空闲 15 分钟,文档支持保存至 30 天;不承诺任意 Python 内存全量恢复 | 当前 identifier 中保留 Python globals/文件;删除或 cooldown 后销毁,无原生持久卷 | 本 Demo 验证 Disk 恢复与快照 restore 后文件保留;不宣称已验证内存/进程恢复。官方 memory 快照与卷能力需另外验证 |
| 运行环境 / 自定义 | Linux 模板、命令/文件;KVM/Firecracker 运维归自己。base 不保证 Jupyter | 自己的 Agent OCI 容器与协议;模型、工具、治理交给平台 | 内置运行时免镜像;另有自定义容器池,但它采用 Dedicated/E16 计费,不能套用本 Demo 的解释器价格 | OCI 转磁盘镜像,快照克隆;XS 至 3XL:0.25–16 vCPU、0.5–32 GiB、20–320 GiB 磁盘 |
| 网络与安全责任 | API ACL、密钥、补丁、模板、宿主机容量与灾备由自己负责 | Entra 与 Agent 身份;工具访问还需逐项授权。托管 Agent 不是任意不可信代码执行 API | Hyper-V 隔离;本池禁止出站。自定义容器可暴露协议,不代表任意任务天然安全 | 组级角色、端口管理、域名/CIDR egress 策略和 VNet;最小权限与外部状态保护仍由应用负责 |
| 适用与不适用 | 要 E2B 生态、模板控制、命令观测与基础设施掌控;不适合只想零运维、低利用率的临时脚本 | 多轮业务 Agent 与模型编排;不宜拿模型首字速度代表 sandbox CPU 性能 | 一次性 Python 分析/工具调用、快速上手;不是跨天保存工作区的方案 | 跨任务工作区、Agent 开发环境、可暂停任务;若只是一次短 Python,生命周期/镜像管理可能过重 |
我先按“业务 Agent”与“执行工具”拆开选型。本演示每个任务四选一,不串联四个云方案。若另行设计组合工作流,Foundry 也可调用 E2B、Sessions 或 Sandboxes 做工具执行,但会累加两边成本,不能把 Hosted Agent 计算会话等同于独立的 ACA SandboxGroups。
真实链路:Device → 同源 HTTPS BFF → Python Sandbox SDK → ACA Sandboxes 数据面。使用本机 Azure CLI 或独立 Device VM 托管身份;服务端保管原生 ID,仅向浏览器返回设备绑定句柄。任务 API 为 /api/sandboxes/tasks,负责可信执行、文件校验、Disk 生命周期、快照恢复、回传和回收,不复用第三条的 identifier 状态机。
环境由独立 Terraform root 部署 Microsoft.App/sandboxGroups 与组范围 Container Apps SandboxGroup Data Owner。代码位于 device-app/aca_sandbox_connector.py,使用 azure-containerapps-sandbox==0.1.0b4。组是预创建的管理边界;每个任务的工作区与自建快照在演示后删除,端侧文件与便签另行保存。
| 路线 | 官方能力 / 性能因素 | 本 Demo 的容量与边界 | 应该测什么 |
|---|---|---|---|
| E2B VM | Firecracker 与模板缓存能降低启动开销,但不引用 E2B SaaS 的宣传数字来保证这台 Azure VM | D8s_v5:8 vCPU / 32 GiB;业务 worker 为 4。控制平面、缓存和 microVM 共享宿主机;不是无限并发 | create、envd readiness、命令、文件和完整回传;缓存命中/未命中;KVM、磁盘、CPU 排队 |
| Foundry | 按会话启动/恢复托管 Agent;端到端还包含模型推理、Token 数、模型配额、工具和 polling | Agent 1 vCPU / 2 GiB;模型 GlobalStandard capacity 10 不是 10 个并发的保证 | 冷会话、热会话、resume、模型 TTFT、总完成时间、Token/s;流式与非流式分别测 |
| Dynamic Sessions | 文档称预热池分配为毫秒/亚秒;这是池就绪条件下的分配,不是整个 Python 请求的 SLA | 池 maxConcurrentSessions=5,Device worker=3。网络、Entra、解释器、文件上传下载仍有开销 | 新 identifier 首次执行、同 identifier 再执行、文件、DELETE;池耗尽时排队/429与重试 |
| ACA Sandboxes | 文档称预热分配与恢复亚秒;自定义 OCI 转换、快照大小、卷和网络路径会改变实测 | 已进行原生 SDK 的单次文件/生命周期观测;未进行容量压测,不以文档“数千”当作订阅保障 | 镜像冷/热、create、exec、Disk stop/resume、快照 restore;memory 与卷一致性另外测试 |
我从同一操作端串行发起请求,每条取三个独立分配样本;E2B 与 Sessions 都执行 sum(range(100000)),Foundry 做一次短模型回复。首次 = 分配/会话创建 + 第一次执行;热请求 = 同一运行会话内再次调用。它不是跨产品同等工作负载排名。
读取时间与测量边界。
| 路线 | 样本数 | 首次中位数 | 热请求中位数 | 首次最小–最大 |
|---|
单次 SDK 流程记录:分配 2.11 秒,首次执行 0.38 秒,再次执行 0.35 秒,Disk 停止 7.49 秒,恢复 2.46 秒,创建快照 2.47 秒,从快照恢复新工作区 0.71 秒。这里的工作量是文件与生命周期验证,不是前三条相同的小算术;不从一个样本推导中位数、p95、吞吐或 SLA,也不宣称内存/进程已恢复。
这些是客户端墙钟时间,包含 DNS/TLS、SDK 身份解析和 Foundry 500ms 轮询;不包含 Device 业务队列、完整文档导出和 IndexedDB 回传,也没有强制清空平台缓存。原始记录可查看 测量 JSON。三次样本只报告中位数和范围,不推导 p95/p99、吞吐或稳定性。
T端到端 = 端侧调度 + 认证/网络 + 排队 + 分配/恢复 + 执行/模型 + 文件回传 + 本地提交。稳态所需并发约为 到达率 × 平均驻留时间,但尾延迟和突发需额外余量。E2B 的有效并发取 worker、可用 CPU/内存、磁盘吞吐和网络中的最小约束;Sessions 本应用至多三个 worker,不能因平台支持数千就声称 Demo 支持数千。
正式比较时统一数据、文件大小与计算量,至少各 100 个样本,分冷/热/恢复,按 1→3→5 并发逐级测,记录 p50/p95、成功率、429、吞吐与每成功任务成本;Foundry 单独固定模型、输入/输出 Token 与工具数。建议本 Demo 的验收目标是“接入与状态可见、文件一致、明确回收”,而非在未压测前承诺亚秒业务完成。
载入官方价格快照。
内置 Sessions 按每个已分配会话向上计入小时。 新建 20,000 个各运行一分钟的会话,仍是 20,000 会话小时;若每个会话连续做 100 个一分钟任务,则每会话约 100 分钟,按两小时计费。显式 DELETE 能限制尾时长,但不能把第一小时按一分钟折算。默认 cooldown=300 秒会延长分配时长,跨过小时边界时会增加一个计费小时。
Sandbox 在 running 期间按分配的 CPU/内存秒数计费,stopped 不收 CPU/内存费用,但镜像、快照、卷、网络和日志并不因此免费。Foundry Hosted Agent 的官方零售 meter 为 $0.0994/vCPU-hour、$0.0118/GiB-hour,另加模型 Token;这里使用真实 Hosted meter,不借用 ACA 费率,也不把 Foundry-native prompt/workflow 的“无额外费”套给 Hosted。实际活跃容器小时未填时,计算器明确保留待确认项。
| 路径 | 已知组件/月(不是完整账单) | 还需加入 |
|---|---|---|
| E2B VM | OS/数据盘、NAT 固定小时与数据、公网 IP、私有终结点、DNS、Blob、日志与运维;若工具调用模型,再加 Token | |
| Foundry | ACR、文件/状态存储、监控、工具/知识;计算按本 Agent 的 1 CPU / 2 GiB,活跃时长需从实际 meter 对账 | |
| Dynamic Sessions | 共享 Device、日志/网络、可选模型;本池内置环境不收自己的 ACR 镜像费用。自定义容器另算 Dedicated/E16 | |
| ACA Sandboxes | 镜像、快照、卷、网络、日志和可选模型。金额是工作量估算,不是本次真实测试的账单 |
H × VM小时价;每成功任务 = (固定+附加+运维+变量费用) / 成功任务数。全天运行并非“无状态就不计费”;释放计算必须 VM deallocate,不只是停止进程。NAT、盘、IP 等仍可能收费。Σ每分配会话 max(1, ceil((批次任务数×T+尾时长)/3600)) × 会话小时价。计算器分别处理完整批次和最后不足 K 的批次;不把不同设备共享会话,复用必须保持同一授权工作区。(N×T + 批次数×额外运行秒) × (CPU×CPU秒价 + GiB×内存秒价);额外秒数可覆盖分配/恢复/空闲。任务间暂停的等待时间不计 running 秒;snapshot/volume 保留费用另外算。活跃容器小时×(1×CPU小时价+2×GiB小时价) + 累计输入Token×输入价 + 累计输出Token×输出价 + 工具/存储等。默认 900 秒 idle tail 可能大于短回复执行时间;不能只按模型执行秒数估算活跃容器时长。N×T / 月秒数 所需平均并发不超过实际容量;失败与重试会提高每成功任务费用。例如同样 20,000 次、每次运行 60 秒,Hosted 1 CPU/2 GiB 的计算若无尾时长为约 $41,加本例 Token $28,共 $69 已知组件;若每次新建计算会话并一直等到默认 900 秒空闲回收,则按活跃时长估算计算约 $656,加 Token 共 $684。它们是两种复用/回收假设,不是当前账单;Hosted 的小时单价本身不代表已证明像 Sessions 一样每次向上取整小时。
只要内置 Python,Sessions 最省集成工作;但大量“每任务新 identifier”应仔细算小时最小粒度。Sandbox 可暂停的秒级计算更有吸引力,但有镜像、状态和接入成本。低利用率不宜只为了一个脚本全天开 D8s VM。
同一授权会话连续做多个工具步骤能摊薄 Sessions 首小时;跨任务保留完整工作区更适合 Sandbox。E2B 的固定机器在高利用率才可能摊薄成本,还需计入运维与单机故障风险,不只比较 CPU 单价。
选择 Foundry 是为了模型编排、身份、托管和治理;优化累计历史 Token、工具次数、模型和 idle timeout。不能用更便宜的 Python 执行费用证明它可以替代模型 Agent。
我会按资源组和 meter 每日对账,分开记录 Device 共享底座、路由计算、Token、存储与网络,配置预算提醒和显式回收。历史保留的 Azure 资源也会计费,但不计入这里的目标架构组件小计;本页面不代表整个订阅账单。
快照不是实时价格。原始选择条件、meter ID、地区、单位与生效日在 价格与资源证据 JSON,可用 Azure Retail Prices API 复核。模型选择普通 GlobalStandard 输入/输出,不混入 Batch、cached input、微调托管或 Windows 365 Agent 单价。
| 组件 | meter | 原始计价单位 | USD/单位 | 单价生效日 |
|---|
我把服务基础环境与演示应用分开:各云模块有自己的 Terraform root 和 state,可以单独 init / plan / apply,也能由统一入口按选择顺序部署。基础环境部署不要求先运行 Device,更不会把 Foundry 绑定到一台必须存在的 E2B VM。
| 模块 | 代码 / Terraform | 部署职责 | 边界 |
|---|---|---|---|
| E2B VM | cloud-service / infra/e2b-vm | 开源 Runtime、真实 KVM、控制平面、存储与网关 | --base-only 不探测 Device 网页;端侧可另部署 |
| Foundry | foundry-agent / infra/foundry | 账户、项目、模型、ACR、身份;容器 Agent 可单独发布 | VM consumer 身份可选;基础环境不强制查找 E2B VM |
| ACA Dynamic Sessions | infra/aca-sessions / infra/modules/aca-sessions | 独立会话池基础环境、操作员角色 | 不需要 Device、Foundry 或 E2B;新 root 可独立部署 |
| ACA Sandboxes | infra/aca-sandboxes / device-app/aca_sandbox_connector.py | 独立 SandboxGroups、组角色与原生 SDK 任务 | --base-only 只创建组;Device 任务按需创建工作区,完成演示后清理 |
| Device | device-app / infra/agent-lab | 独立 VM、ACR 镜像与 BFF;消费已部署云端配置 | 现有环境保留兼容池;新环境可使用外部 Sessions,避免重复创建 |
| 自有域名 | infra/dns | 在现有 stat200.net 中管理选定 A 记录 | 不接管 zone、不改变授权或端口;必须明确审批,不随 all 自动启用 |
# 只部署一个云基础环境,示例:Foundry .venv/bin/python scripts/deploy_environment.py --modules foundry --base-only # Sessions / Sandboxes / E2B 各自可选 .venv/bin/python scripts/deploy_environment.py --modules aca-sessions --base-only .venv/bin/python scripts/deploy_environment.py --modules aca-sandboxes --base-only .venv/bin/python scripts/deploy_environment.py --modules e2b --base-only # 统一基础环境:四个云 root,不发布 Device 或 Hosted Agent 容器 .venv/bin/python scripts/deploy_environment.py --modules all --base-only # 只生成并保存计划,不 apply .venv/bin/python scripts/deploy_environment.py --modules all --base-only --plan-only
去掉 --base-only 可发布选中模块的应用;Device 托管网页仍需已部署的云端身份校验与 Foundry 配置,不把“云基础环境独立”误说成当前 BFF 已支持任意单服务身份模式。Terraform state、密钥与计划留在私有位置,公开 environment 清单只包含非秘密配置。
已批准的自有域名配置为 device.stat200.net 与 runtime.stat200.net。DNS 指向原 VM IP;Caddy 管理受信任 TLS 证书;Runtime 业务接口为 HTTPS 7444,SDK/代理/原生管理仍受原操作员 CIDR 限制。域名变更不覆盖组织访问策略,也不关闭证书验证。
# 审批后管理现有 DNS zone 的两个应用记录 .venv/bin/python scripts/deploy_environment.py --modules dns --organization-approved # 准备并应用 Runtime TLS/CORS 与 Device URL 配置 .venv/bin/python scripts/configure_domain.py --approved --apply
切换域名意味着浏览器 origin 改变:旧域名的 localStorage / IndexedDB 不会自动复制到新域名。原来的设备数据仍属于原 origin;不能因旧地址被组织限制就代理读取它。新域名使用自己的演示状态,服务器授权凭据和归属校验保持原规则。
.venv/bin/python scripts/build_offline_report.py # 输出 docs/agent-runtime-lab-offline.html
离线版将 CSS、SVG/JavaScript、价格与性能 JSON 全部内嵌到一个文件。双击即可筛选四方案、播放流程、修改成本参数和查看证据,不依赖网页域名、CDN、本地服务器或 Azure 登录。它展示保存的技术资料与测量快照,不读取实时部署状态。
cloud-service/sandbox.py位于 Azure VM 的业务控制平面,使用官方 e2b SDK 调用本机上游 API 和 client-proxy。浏览器不拿 Team Key,也不直接执行沙箱进程。
device-app/foundry_connector.py位于 Device 的 Python 连接器。真正本机运行时,它使用 Azure CLI 身份直连 Foundry;网页托管到 VM 时,相同连接器在 VM 的 Device BFF 中运行,改用托管身份。
foundry-agent/main.py位于真实 Hosted Agent 容器。Responses 协议库接收请求与历史,项目 SDK 使用平台注入的 Agent 身份调用模型。它不集成 E2B SDK。
device-app/aca_sandbox_connector.py 集成 azure-containerapps-sandbox==0.1.0b4。本机运行使用 Azure CLI,托管 Device VM 使用托管身份。浏览器只持设备访问凭据与任务句柄,不拿 Azure Token 或原生工作区 ID。
这里验证磁盘状态和文件,不宣称 Python 内存变量、进程、GPU 或网络连接原样恢复。原生数据面使用 2026-02-01-preview,ARM 组部署使用 2026-07-01,两个版本不能混称。入口为 /api/sandboxes/tasks 的提交、查询、取消与 artifact;错误明确呈现,不回退到其他云方案。
| 链路 | 协议 | 认证 | 秘密留在哪里 |
|---|---|---|---|
| 浏览器 → E2B 业务控制平面 | HTTPS 7444;JSON / multipart;轮询 | 设备访问码换取 24 小时 HMAC-SHA256 Bearer;不是 JWT | 浏览器只持业务令牌;不能取得 E2B Team Key |
| VM 控制平面 → E2B API | 官方 SDK;loopback HTTP 3000 | X-API-Key:本部署种子 Team Key | VM 的私有控制平面配置 |
| VM 控制平面 → envd | 官方 SDK / Connect RPC;client-proxy 3002 | SDK 的逐沙箱访问令牌和路由头 | 控制平面 SDK;不下发浏览器 |
| 外部操作员 → E2B SDK / 原生管理 | HTTPS 7443 / 8443 / 9443 | Team Key / 沙箱令牌 / Secure Cookie;精确操作员 CIDR | 操作员环境;不是 Device 访问码 |
| 浏览器 → 本机 Foundry 连接器 | 同源 loopback HTTP 8081;JSON | 进程 nonce + 设备 ID;来源检查 | Azure 令牌不进浏览器;只由本机 SDK 获取 |
| 浏览器 → 托管 Device BFF | 同源 HTTPS;JSON | 设备 Bearer,BFF 向控制平面验证角色和归属 | 不共享控制平面的 E2B Key 或 HMAC 签名密钥 |
| Device 连接器 → Foundry | HTTPS Responses;后台请求、轮询与取消 | Entra OAuth;本机 AzureCliCredential 或 VM ManagedIdentityCredential | 连接器内存中的 SDK;无浏览器 API Key |
| Hosted Agent → 模型 | 项目 OpenAI-compatible Responses API | 平台创建的 Agent 身份 | Foundry 容器/平台;不是项目拉镜像身份 |
| Device VM → ACA 会话池 | 原生 HTTPS REST:executions / files / session | Entra audience https://dynamicsessions.io;池范围 Session Executor | 托管身份令牌与私有 identifier 仅在连接器内;浏览器只拿设备绑定句柄 |
| Terraform → ACA SandboxGroups | ARM HTTPS management.azure.com;创建组与角色 | 部署身份需要组创建和角色分配权限;应用身份只授予组范围 SandboxGroup Data Owner | Terraform 私有 state/配置;不向浏览器分发部署身份 |
| Device SDK → ACA Sandboxes | HTTPS management.azuredevcompute.io;SDK 按区域解析数据端点 | 原生 SDK 使用 Entra;本机 CLI 或 VM 托管身份;组范围 Data Owner。不得借用 Sessions identifier 或接口 | 令牌留在连接器;设备句柄、原生工作区与快照归属分开保管 |
| VM 控制平面 → Azure Blob | HTTPS;私有终结点与 DNS | 容器范围托管身份授权 | 不使用存储账户密钥或匿名 Blob |
图中的业务委派不等于实现 A2A 标准。当前 Device 契约是明确的 HTTP JSON / multipart;Foundry 容器使用 Responses 2.0.0,不把两条链路混称为同一个 SDK 或协议。
沙箱是任务级临时环境;业务审计和文件副本在 Blob,最终使用状态在设备。
conversation 是历史标识,不是计算 session ID;服务未返回 session ID 时不会编造。平台默认闲置计算回收不等于删除历史,也不是 E2B 的 Kill。
切换菜单不会删除已有提醒、便签或文件。Foundry 路线当前演示文本规划/多轮记忆,不伪造 Word 下载;E2B 未配置模型时明确使用文档摘录/模板,不把沙箱真实运行说成模型推理。
.venv/bin/python scripts/deploy_vm.py --test
Terraform 管理单机 VM、上游开源 Runtime、私有 Blob、Caddy 和独立应用。生产多节点/持久队列不在 Demo 范围。
.venv/bin/python scripts/deploy_foundry.py
Terraform 创建独立账户/项目、模型、ACR 和项目范围角色;发布脚本远程构建 amd64 镜像并注册真实 Hosted Agent 版本,等待 active,不改成 Prompt Agent。
az login .venv/bin/python scripts/run_device.py
打开 localhost:8081,在菜单选择方案。本机连接器直连 Foundry;E2B 仍走 VM 控制平面。托管网页需要更新 VM 应用包后使用托管身份。
Device 页面显示实时业务事件与请求状态;E2B 原生 Dashboard 管理 Sandbox/Template,业务后台管理 Device/Session;Foundry 项目通过 Azure Foundry 门户管理 Agent 版本、模型与追踪。
Device VM 只是端侧逻辑的模拟机器,物理上仍在 Azure,不能称为真正离线手机。它只运行独立的 device-app 容器与 HTTPS 网关,不持 E2B Team Key,也不运行 Firecracker。E2B SDK 留在 Runtime VM;Foundry SDK 和 ACA REST 连接器位于 Device VM。
ACA 连接器代码:device-app/aca_connector.py;共享身份边界:device-app/runtime_identity.py。不把原生 REST 错称为 E2B SDK。Device VM 与本机两种运行方式使用同一份应用容器/源码。
池禁止出站网络;300 秒空闲回收仅作删除失败时的兜底。它不是普通 Container App,也不是 Foundry Hosted Agent。
参考环境的分文件结构:provider、variables、network、virtual-machine、session-pool、iam、outputs,以及 00-init / 01-plan / 02-apply。基础设施在同一 Terraform root 创建。
.venv/bin/python scripts/deploy_lab.py
应用源码仍在独立 device-app;ACR 构建 amd64 镜像并固定摘要,Terraform VM 扩展只部署镜像和配置。不复制安全豁免标签,也不通过 shell 跟踪输出秘密。