AI News HubLIVE
站内改写4 分钟阅读

我们为自主代理构建了沙盒基础设施

NeoSigma公司构建了一套沙盒基础设施,为自主代理提供安全、隔离且功能完整的执行环境,使其能够像在真实开发环境中一样工作,同时确保每一操作都受控、可重现且可丢弃。

来源Hacker News AI作者: AdityaBilawar

代理的能力取决于它能够安全行动的环境。为了让代理自主运作,它们需要一种验证自身工作的方法。代理可以拥有丰富的动作空间和完美的奖励信号,但如果没有真实的执行环境,这些能力在很大程度上仍然是理论上的。随着模型能力越来越强,它们被委托从事越来越重要的工作:修改数据库、运行任意代码、部署基础设施以及与生产API交互。拥有完整的运行时工作空间,代理可以验证自己的成果并迭代直到成功。

挑战在于构建一个与开发者本地环境无异的工作空间,同时安全隔离代理所做的一切后果。沙盒提供了一个隔离的执行环境,代理可以在此安全地运行代码、与服务交互并从失败中恢复。一个设计良好的沙盒为代理提供了一个真正的乐园,同时确保每个动作都是隔离的、可重现的和可丢弃的。

一个出色的执行环境应具备以下核心特性:控制平面——以最小延迟保持执行就绪;执行平面——一台真正的机器,而非一个Shell;安全与网络平面——隔离能力而不限制其发挥;数据平面——生产规模的确定性状态。每个设计决策最终都是为了这些核心原则之间的帕累托前沿进行优化。

在本文中,我们将介绍为代理执行、探索和从经验中学习的工作空间提供动力的核心基础设施。我们讨论如何将工作空间配备与真实环境相同的能力,包括真实的文件系统、Docker、网络、代表性数据和生产工具,同时确保每次运行保持隔离、可重现和可丢弃。

控制平面 代理是交互式系统,花费在准备执行环境上的每一秒都是用户等待的时间。启动微型虚拟机、配置存储、克隆仓库、初始化服务、加载工具和执行健康检查很容易占据请求的关键路径。如果每次交互都需要从头创建沙盒,即使是最有能力的模型也会很快感觉响应迟缓。最明显的解决方案是避免按需创建沙盒。控制平面协调执行环境的生命周期,确保以最小延迟将正确的沙盒预配、初始化并分配给代理。它还维护一个预先预配的执行环境池,随时可以接受工作。调度器不是为每个请求启动新沙盒,而是尝试将代理连接到现有的预热沙盒。只有在预热池耗尽或工作负载需要尚未可用的资源或配置时才会发生冷启动。预热沙盒远不止是一个正在运行的虚拟机。当它进入池中时,操作系统已启动,Docker正在运行,仓库已克隆,依赖项已安装,代理运行时已初始化,支持服务(包括MCP服务器)也已可用。从代理的角度来看,执行几乎立即开始,因为昂贵的初始化工作已经完成。维护该池从根本上是一个调度问题,而非配置问题。持有过少的预热沙盒会增加冷启动延迟,而过多则浪费计算资源。调度器持续预测需求,提前配置新沙盒,并通过LRU风格的驱逐策略回收未使用的容量。最优池大小取决于工作负载模式、仓库特征、依赖图、用户行为和资源需求。最大的延迟改进并非来自加快每个配置步骤,而是来自完全避免不必要的配置工作。其中最有影响力的优化来自意图预测。由于用户交互在请求提交之前就开始了,控制平面可以在用户仍在编写提示时开始准备沙盒。通过将初始化与用户思考时间重叠,许多潜在的冷启动变成了简单的连接,减少了感知延迟,而无需改变执行环境本身。当预热沙盒不可用时,回退路径仍然是确定性的。基础镜像从版本化的快照中恢复,根据工作负载分配CPU、内存和存储,然后初始化、健康检查,最后交给代理。快速路径和回退路径产生等效的执行环境,仅在于请求到达前已完成的工作量不同。

执行平面 沙盒的低延迟只有在其环境行为与代理最终目标环境相似时才有价值。一个省略服务、简化文件系统或用模拟代替生产工具的执行环境可能更快配置,但它从根本上改变了代理的行为,这是无用的。在人工环境中成功的轨迹在转移到真实基础设施时常常失败。因此,我们的目标是保真而非简约。每个沙盒都设计得尽可能接近开发者工作站。代理在一个完整的环境中操作,包括可写文件系统、已克隆的仓库、项目配置、开发工具、Docker、MCP服务器以及在生产开发中会遇到的相同支持服务。目标很简单:如果一个任务在沙盒内成功,那么它在针对客户实际环境执行时也应成功。这种理念的一个后果是将容器化工作负载视为一等公民。现代软件开发很少由主机上运行的单个进程组成。应用程序依赖数据库、缓存、消息队列、后台工作线程和其他服务,这些通常通过Docker Compose或类似工具编排。支持这些工作流需要的不仅仅是Docker CLI,还需要沙盒内部运行一个功能正常的Docker守护进程。代理不是推理更改是否有效,而是可以直接通过构建和运行已修改的应用程序来验证其行为。提供这种保真度不可避免地会扩大执行面。运行嵌套容器、暴露Docker守护进程和支持任意开发工具都会引入额外的安全考虑。我们没有限制这些功能,而是通过本文后面描述的安全架构来隔离它们。目标不是降低代理的能力,而是确保这些能力保持在安全隔离的状态。最终,执行平面的存在是为了消除评估与部署之间的差距。代理应该在与其软件最终运行环境相同的环境中开发、测试和调试。沙盒越接近现实,代理就越可靠。

安全与网络平面 执行平面有意赋予代理广泛的能力。它们可以执行任意代码、与Docker交互、修改仓库、访问代表性数据以及与外部服务通信。这些能力使代理有用,但也使沙盒安全与传统应用安全根本不同。目标不是阻止执行,而是确保执行完全隔离。没有任何单一的安全边界足够。沙盒同时执行不受信任的、模型生成的代码,同时与客户基础设施和凭据交互。防止权限提升、秘密泄露、横向移动和数据泄露需要多个独立的隔离层,而非单个周界。最安全的秘密是代理永远无法访问的秘密。这一原则塑造了整个凭据架构。任何暴露给执行环境的凭据——无论是通过环境变量、挂载的文件还是进程内存——如果攻击者通过提示注入或模型操纵控制了代理,最终都可能被泄露。短期凭据减少了暴露,但并未消除潜在风险。如果代理可以读取秘密,它就可以泄露它。相反,凭据必须完全位于沙盒外部。需要身份验证的请求通过一个凭据注入代理路由,该代理在转发请求之前立即附加适当的凭据。代理发出普通网络请求,从不观察底层秘密,而代理成为唯一负责凭据管理的组件。秘密从未成为执行环境的一部分,从而消除了一整类泄露攻击。此外,针对未授权主机的提示注入请求无法通过我们严格的出口许可列表。保护沙盒需要控制两个方向的流量。入站流量被严格限制,仅允许必要的服务,而出站流量则通过许可列表控制,只允许访问经过批准的外部端点。这种多层架构确保了即使沙盒被攻破,攻击者也无法轻易横向移动或泄露数据。

数据平面 每个执行都从已知状态开始,每个动作都可恢复。相同输入应产生相同环境,从而使失败可调试、评估可重复,成功轨迹可重用。数据平面负责管理沙盒的持久状态,确保快照的一致性和环境的可重现性。通过版本化的镜像和状态快照,我们可以将沙盒回滚到任何先前的点,这对于调试和迭代至关重要。