摘要

一句话总结

Cursor 为 macOS、Linux 和 Windows 平台构建了智能体沙盒环境,通过在受控环境中执行终端命令并在必要时才请求权限,成功平衡了安全性与易用性,并将用户中断次数减少了 40%。

关键要点

  • 解决核心痛点:自动批准智能体命令存在高风险,而频繁的手动批准会导致用户产生“批准疲劳”。
  • 显著成效:沙盒化智能体比未沙盒化智能体的中断次数减少了 40%;目前在支持的平台上,有三分之一的请求在沙盒中运行,并已成功接入 NVIDIA 等企业客户。
  • macOS 实现方案:放弃了 App Sandbox、容器和虚拟机,最终选择使用 Seatbelt (sandbox-exec)。通过动态生成的策略语言,结合工作区设置和 .cursorignore,精细限制系统调用和文件读写。
  • Linux 实现方案:结合使用 Landlock(强制文件系统限制)和 seccomp(拦截不安全系统调用),通过覆盖文件系统(overlay filesystem)隐藏被忽略的文件。
  • Windows 实现方案:目前将 Linux 沙盒运行在 WSL2 内部,同时正与微软合作以获取未来构建原生沙盒所需的底层支持。
  • 赋予智能体“沙盒意识”:更新了 Shell 工具的描述,向智能体明确沙盒的限制条件以及请求提升权限的方法。
  • 优化反馈机制:针对智能体盲目重试失败命令的问题,系统现在会明确显示导致失败的沙盒限制,并在特定情况下建议智能体提升权限,从而大幅提升了故障恢复能力。

风险与不足(Risks/Gaps)

  • 智能体原生风险:如果缺乏限制,出错的智能体可能会删除数据库、发布损坏的代码或泄露机密信息。
  • macOS 技术隐患:App Sandbox 方案可能让智能体生成或修改的二进制文件继承信任,带来新的滥用风险;而最终采用的 Seatbelt 技术虽被 Chrome 等应用广泛使用,但实际上已于 2016 年被官方弃用。
  • Linux 性能瓶颈与限制:寻找并重新挂载被忽略的文件是 Linux 沙盒中最耗时的部分;此外,Linux 在 seccomp-bpf 上下文中无法轻松获取文件路径,导致无法像 macOS 那样延迟过滤文件系统操作。
  • Windows 原生支持缺失:现有的 Windows 沙盒底层机制大多为浏览器量身定制,不支持通用的开发者工具,导致目前难以构建等效的原生 Windows 沙盒。
  • 智能体行为缺陷:在早期测试中发现,智能体在遇到权限拦截时,容易陷入不断重试相同命令的死循环(该问题后续通过优化报错提示得以缓解)。

正文

编程智能体在运行终端命令以探索环境和修改代码方面正变得越来越强大。如果用户选择自动批准这些命令,就能解锁能力更强的智能体,但这也意味着风险的增加。一个出错的智能体可能会删除数据库、发布损坏的代码或泄露机密信息。

要求人类批准每一条命令可以降低这种风险,但这通常只是权宜之计。随着批准请求的不断积累,用户会逐渐失去耐心,不再仔细检查。当工程师并行运行多个智能体,并需要在不同的批准提示之间切换上下文时,情况会变得更糟。最终会导致“批准疲劳”,这完全破坏了设置批准机制的初衷。

在过去的三个月里,我们通过在 macOS、Linux 和 Windows 上推出智能体沙盒(Agent Sandboxing)解决了这个问题。沙盒内的智能体可以在受控环境中自由运行,只有在需要跳出沙盒(通常是为了访问互联网)时才会请求批准。

这极大地减少了对用户的打扰。与未沙盒化的智能体相比,沙盒化智能体的中断次数减少了 40%,为用户节省了数小时的手动审查和批准时间。

沙盒的设计目标

我们开展沙盒工作的初衷是在消除中断的同时提高安全性。我们希望为智能体提供足够的自由度以保证其工作效率,同时拒绝那些可能带来风险的权限。

要实现这种平衡比看起来更难。许多终端命令都需要意想不到的权限,即使是基础的测试或构建步骤也不例外。一个设计粗糙的沙盒会直接拦截这些操作,从而破坏智能体的工作流。设计一个好用的沙盒,本质上是在每个操作系统设定的参数范围内,在安全性和易用性之间寻找最佳的权衡。

各平台的具体实现

我们提供了一个统一的沙盒 API,但在不同平台上的实现方式各不相同。macOS、Linux 和 Windows 提供了不同的沙盒底层机制,这直接决定了我们的设计选择。

  • macOS: 我们评估了四种沙盒方案:App Sandbox、容器、虚拟机和 Seatbelt。App Sandbox 是为 Mac App Store 设计的,它要求 Cursor 对智能体可能执行的每一个二进制文件进行签名,这会增加极大的复杂性,并可能让智能体生成或修改的二进制文件继承 Cursor 的信任,从而带来新的滥用风险。容器方案会将我们限制在 Linux 二进制文件上,而虚拟机的启动延迟和内存开销是不可接受的。 最终我们选择了通过 sandbox-exec 访问的 Seatbelt。虽然它在 2007 年推出并在 2016 年被弃用,但 Chrome 等关键的第三方应用仍在使用它。它允许命令在特定的沙盒配置文件下运行,从而限制整个子进程树的行为。该配置文件通过一种特殊的策略语言,精细地限制系统调用以及对特定文件和目录的读写。我们会根据工作区级别的设置、管理员级别的设置以及用户的 .cursorignore 文件,在运行时动态生成这一策略。
  • Linux: Linux 的情况既简单又复杂。内核通过 Landlock 和 seccomp 提供了所需的底层机制,但需要用户空间将它们组合成一个可用的沙盒。虽然有几个开源项目有效地结合了这些机制,但没有一个支持 .cursorignore 等功能。 我们决定直接使用 Landlock 和 seccomp。Seccomp 用于拦截不安全的系统调用,而 Landlock 则强制执行文件系统限制,使被忽略的文件对沙盒进程完全不可见。我们将用户工作区映射到一个覆盖文件系统(overlay filesystem)中,并用无法读取或修改的 Landlocked 副本覆盖被忽略的文件。寻找并重新挂载这些文件是 Linux 沙盒中最耗时的部分。如果能像 macOS 那样延迟过滤文件系统操作会简单得多,但 Linux 在 seccomp-bpf 上下文中无法轻松获取文件路径。
  • Windows: 在 Windows 上,我们将 Linux 沙盒运行在 WSL2 内部。构建一个等效的原生 Windows 沙盒要困难得多,因为现有的沙盒底层机制大多是为浏览器量身定制的,不支持通用的开发者工具。我们正在与微软合作,以确保未来能获得必要的底层支持。

教导智能体如何使用沙盒

只有当智能体能够预判哪些命令在沙盒内会成功,并识别出何时需要提升权限时,沙盒才能真正发挥作用。为了让模型具备“沙盒意识”,我们需要对智能体的运行框架进行修改。

  1. 更新工具描述: 我们首先更新了 Shell 工具的描述,向智能体解释沙盒的限制:命令是否具有文件系统、git 或网络访问权限(基于用户设置),以及智能体在需要时应如何请求提升权限。为了得到一个令人满意的基础框架,我们进行了大量的手动测试:执行常见的操作流程,观察与预期不符的地方,微调提示词,然后再次运行测试。
  2. 评估与修复缺陷: 随后,我们使用内部基准测试(Cursor Bench)评估了这些更改的影响,对比了启用和未启用沙盒的智能体表现。我们很快发现了一个常见的故障模式:智能体会不断重试相同的终端命令,却不知道去更改权限。
  3. 优化反馈机制: 为了解决这个问题,我们更新了 Shell 工具结果的渲染方式。现在,系统会明确显示导致命令失败的沙盒限制,并在特定情况下建议智能体提升权限。上线这些提示后,智能体从沙盒相关故障中恢复的能力大幅提升,离线评估的性能也得到了显著改善。

不过,离线评估只能反映部分情况。为了进一步确保沙盒不会降低用户体验,我们在生产环境中进行了缓慢的灰度发布。来自内部和外部的反馈给了我们正式发布该功能的信心。目前,在支持的平台上,有三分之一的请求都在沙盒中运行,我们还成功接入了 NVIDIA 等众多企业客户。

随着智能体从单纯的生成代码向操作生产系统跨越,提供执行边界变得至关重要。我们目前的实现正是朝着这个方向迈出的一步。展望未来,我们对基于环境约束训练的“沙盒原生智能体”充满期待。这些智能体将获得直接编写脚本和程序的自由,而不再仅仅局限于调用工具。


如果您有兴趣致力于解决与编程未来相关的深层技术问题,请联系 hiring@cursor.com 作者:Ani Betts, Yash Gaitonde & Alex Haugland

相关文档

关联主题