Run SDK 发布:为智能体提供安全评估

Vercel Blog 2026-08-26T06:19:59.884501

智能体(agent)越来越多地会编写 TypeScript 程序来协调工具、处理返回结果。一旦这些程序接触到真实应用,有些步骤需要身份认证,有些则必须经过人工审批。如果直接用 eval 执行这类代码,代码会获得与所在应用同等的权限,包括访问密钥和内部服务,而且无法在这些边界处可靠地暂停。今天,我们正式发布 Run SDK——这个包可以执行不受信任的 JavaScript 和 TypeScript,同时不会让代码直接访问你的应用或系统。应用只需暴露少量职责单一的宿主函数(host functions),并能在需要身份认证或人工审批时中断执行。审批完成后,程序从中断处继续运行,无需重复已完成的工作。

面向宿主的精简接口

Run SDK 会在工作线程(worker thread)中创建一个全新的 QuickJS 上下文,用来执行 JavaScript 或去除...类型标注的 TypeScript。它在一个 worker 线程内运行,无法直接访问 Node.js 或网络。应用通过 hostFunctions 暴露选定的操作。这些就是普通的函数,在沙箱内会成为可调用的全局对象:例如,生成的程序知道 store.listOrders()。数据库客户端及其凭据仍保留在应用里。调用通过序列化跨越沙箱边界。宿主函数可以返回 promise,所以现有的服务客户端可以直接放在这个接口后面,不必传入沙箱。你可以在 playground 里试试。那里运行的代码只能访问页面上的宿主函数。

代码模式的实际应用

Run SDK 正是驱动 AI SDK 中代码模式工具执行的内部模块。给智能体一个程序,工作的单元就变了。模型的一次响应既可以描述要发起的调用,也能描述连接这些调用的逻辑:两个请求并发执行,发票筛选逻辑保留在程序中。只有有用的结果返回给应用。这特别适合跨多个内部服务协作的智能体。研究类智能体可以先组合搜索结果再回答;支持类智能体则可以检查账户,而无需把完整的账单响应塞回上下文。

宿主函数最适合对应你产品里的具体操作,比如“退款”。暴露 orders.refund(id) 这样的接口,应用就能在一个明确的入口处校验用户身份和订单信息。如果换成一个通用的 request 函数,权限边界就变得很难理清。

对人机协同和认证的原生支持

读取发票和发起退款是两回事。当生成的代码碰到敏感操作时,宿主函数可以中断执行:

当中断发生时,结果里会带上一个签名令牌(signed token)。应用可以把这个令牌连同审批请求一起保存下来,等审批结果出来后再用它恢复执行。恢复时程序会重放一遍,但已经完成的宿主函数调用会直接采用之前记录的结果,中断前做完的工作不会重复执行。被中断的那个函数收到审批结果后,从停下的地方继续往下走。

这个机制同样适用于需要等待认证的场景。等待过程由应用自己掌控,工作节点(worker)不必一直保持存活。

在限制内运行

沙箱还得防住两类情况:永远循环不结束的代码,以及产生超大规模结果的代码。createRunner() 可以设置共享的限制:

限制也可以按单次运行单独设置。默认值覆盖了 QuickJS 堆(heap)以及跨宿主边界传递的数据量,应用可以根据自身负载收紧这些限制。

每次调用都会获得一个全新的 QuickJS 上下文。动态求值(dynamic evaluation)被禁用,内置原型也做了加固。这个边界只作用于生成的程序;宿主函数仍然是受信任的应用代码,需要自行完成常规的授权检查。

Run SDK 定位的是应用内部的 JavaScript 计算。如果工作负载需要操作系统能力、安装软件包或者进程级隔离,应该改用 Vercel Sandbox。

把执行层拆出来

这套运行时最初是 just-bash 里的 js-exec 模块,底层由 QuickJS 支撑。它让 agent 可以用 TypeScript 操作 shell 的虚拟文件系统和命令集。

我们把这一层单独抽取出来,做成了 Run SDK,同时把原来基于 Node 形态的运行环境,替换成由应用自定义的宿主函数(host functions)。这套底层机制最早在 eve 中得到验证,用来让智能体生成的 TypeScript 代码直接调用真实工具。如今它驱动着 AI SDK 里的代码模式:AI SDK 现有的工具会被映射为宿主函数,而 Run SDK 负责它们的沙箱执行。

开始使用

Run SDK 支持 Node.js 22.13+ 和 Bun。你需要在本地开发机上安装 pnpm 或其他包管理器。更多细节可以查看文档和 API 参考。

阅读更多

查看原文