起因:一次误删与一个坏掉的包管理器
关于 Agent 沙箱的讨论,常常从架构图开始,但这一个是从事故开始的。一位开发者在自己的机器上直接运行编码 Agent,结果经历了一次误删,以及一个被弄坏的包管理器。这类经历在开发者社区里并不罕见,多数人的反应是加一条「不要动这个目录」的提示词,少数人的反应是去把隔离层真正做出来。stoat 属于后者。
它被描述为单个 Go 二进制,作用是让编码 Agent 能够自主驱动带快照的 QEMU 虚拟机。项目的许可协议是 AGPL-3.0,托管在 GitHub 上。
为什么现成的方案不够
作者的判断是,容器在这个场景里不够用,原因不在于隔离强度,而在于能力缺口。当客户机需要 systemd、内核模块或回环网络时,容器方案会失效;更根本的是,容器与宿主机共享内核,隔离边界并不独立。
传统虚拟机方案的问题在另一个方向:VirtualBox 与 VMware 并没有暴露一套 Agent 可以调用的接口,它们默认操作者是人,坐在图形界面前面点击。对一个需要通过工具调用来操作的 Agent 来说,这类软件等于不存在。
于是剩下的路径就是直接驱动 QEMU。QEMU 本身能力完整,但没有为 Agent 设计的使用界面,因此需要一层薄薄的包装:把虚拟机的定义、启动、操作与回滚,整理成 Agent 能调用的结构化工具。
stoat 怎么做:TOML 定义、每台一个 MCP、快照回滚
具体设计可以拆成三层。
定义层使用 TOML 描述虚拟机,把镜像、资源与配置写成声明式文件。启动方式接近容器工具的手感:stoat create dev --image debian-13 创建一台名为 dev 的虚拟机,stoat up dev 把它拉起来。
接入层为每台客户机单独挂一个 MCP 服务器,再通过 stoat mcp install claude-code 之类的命令把工具注册进编码 Agent。Agent 因此获得一组面向客户机内部的操作能力:执行命令、读写文件、安装软件包、管理端口与服务、查看日志、以及打快照与恢复快照。这里的分工很关键——不是让 Agent 直接拿到宿主机的 shell,而是给它一台机器的操作面板。
回滚层提供 stoat snapshot 与 stoat restore。作者把快照列为两个必备能力之一,理由是 Agent 会走到坏状态:装了一半的依赖、改错的配置文件、被覆盖的系统目录。有快照意味着这些坏状态可以被退回,而不是让整台开发机进入需要重装的状态。
权限分级:从 none 到 exec
另一个必备能力是每台虚拟机的访问等级。stoat 给每台客户机设定从 none 到 exec 的访问级别,可以让一台机器完全交给 Agent,同时把另一台设为只读。
这个设计针对的是一个很实际的滑坡:把虚拟机交给 Agent 与把全部虚拟机交给 Agent,是两件风险量级完全不同的事。在单机多虚拟机的场景里,如果没有分级,Agent 拿到任意一台的入口就等于拿到所有机器的入口。按机器设定权限,让「给 Agent 一台机器」这句话保持它字面上的意思。
边界:Linux 与 KVM 前提,macOS 与 Windows 的远程退路
项目对自身限制的说明相对直接。本地虚拟机需要 Linux 环境并启用 KVM,也就是说,在 macOS 与 Windows 上无法以同样的方式在本地运行。
对这两个平台,项目给出的替代路径是速度较慢且需要付费的远程 GCE 方案。此外,GCP 与 AWS 的连接器、以及 macOS 与 Windows 的原生二进制被列为计划中的工作。这意味着当前版本更适合已有 Linux 开发环境、且对隔离有明确要求的团队。
放进沙箱选型的地图
把 stoat 放回当前的 Agent 沙箱地图,能看清它占据的位置。
容器方案的优势是启动快、生态成熟、与现有 CI 流程衔接顺畅,代价是共享内核,隔离强度有限,且在需要内核级能力时失效。gVisor 这类用户态内核方案拦截系统调用而不直通宿主内核,不需要 KVM,启动开销较小,更适合 CPU 密集且互不信任的编码 Agent 场景,但对某些系统调用兼容性有限。Kata Containers 走轻量虚拟机路线,每个 Pod 独立内核,支持硬件强制边界与机密计算,适合多租户与不可信负载,代价是启动开销更高、运维复杂度更大。直接驱动 QEMU 的方案,例如 stoat,把控制权与快照能力做得更彻底,代价是需要自己维护虚拟机生命周期。
这条光谱上的取舍可以用一句话概括:隔离越强、控制越细,启动与运维成本越高。选型的实际依据不是谁更安全,而是任务需要多强的隔离、能容忍多长的启动时间、以及团队愿意承担多少运维。
中立思辨
需要辩证看待几件事。其一,AGPL-3.0 许可对商业使用有明确约束,如果计划把它嵌进对外提供的服务,需要先评估合规义务,这一点在选型时容易被忽略。其二,项目当前的平台限制是实质性的:只能在 Linux 加 KVM 上本地运行,等于把相当一部分开发者排除在直接使用之外,远程方案虽然可用,但引入了延迟与数据出境两个新问题。其三,单个 Go 二进制的形态降低了部署门槛,但也意味着功能边界相对收敛,例如多机编排、资源配额与审计日志这类企业级能力,需要额外补齐。其四,快照能解决状态回滚,却解决不了数据泄露:如果 Agent 在客户机内访问了真实凭证或敏感数据,回滚不会撤销已经发生的读取。其五,权限分级的设计方向正确,但实际效果取决于默认值——如果默认是 exec,分级就只是可选项而非防线。其六,这类工具的出现反映了一个更宏观的趋势:Agent 的执行环境正在从「共享宿主机」走向「一任务一机器」,而这一转变的成本最终会体现在基础设施账单上。
趋势研判
短期看,这类工具的主要用户是重度使用编码 Agent 的个人开发者与小团队,因为他们同时具备痛点与动手能力;中期看,关键变量是编排层能否标准化——如果「给 Agent 分配一台机器」这件事能被 Kubernetes 这类既有平台原生表达,专用工具的空间会被压缩,目前已经能看到相关的沙箱自定义资源在推进;长期看,Agent 执行环境的形态会分化:轻量任务继续跑在容器里,需要内核能力或强隔离的任务跑在虚拟机里,而连接两者的调度策略会成为新的工程课题。
对准备把 Agent 放进隔离环境的团队,一个务实的起点是先回答三个问题:任务是否需要内核级能力,失败后希望恢复到什么粒度,以及谁来审批对真实凭证的访问。前两个问题决定用容器还是虚拟机,第三个问题决定这套隔离是否真的减少了风险。