返回 文章 apply CMS 文章

Vercel 发布 Run SDK:为智能体提供安全评估执行环境

Run SDK 让智能体生成的代码在沙箱中运行,仅通过宿主函数与真实应用交互,并支持中断以进行身份验证或人工审批。

Run SDKVercel智能体安全执行
成长分 / 100 80 综合收获、行动、留存与影响

Vercel 发布 Run SDK:为智能体提供安全评估执行环境
为什么值得读了解如何安全执行智能体生成的代码,避免直接访问应用机密和内部服务。

掌握 Run SDK 的核心机制:宿主函数、中断恢复、资源限制。

关键洞察
  1. Run SDK 在工作线程内的 QuickJS 上下文中执行代码,无直接 Node.js 或网络访问路径。
  2. 应用通过 hostFunctions 暴露选定操作,调用通过序列化跨越沙箱边界。
  3. 宿主函数可以中断执行以进行身份验证或人工审批,恢复时重放程序但复用已完成调用的结果。
转成行动

深入阅读

正文与原文对照

原文保真覆盖:全文原文字符:7068

智能体越来越多地编写 TypeScript 程序来协调工具并处理其结果。一旦这些程序接触到真实应用,某些步骤需要身份验证,而另一些则需要人工审批。

eval 执行该代码

会赋予它与周围应用相同的访问权限,包括其机密信息和内部服务,并且无法在这些边界处持久地暂停。

今天,我们发布 Run SDK,这是一个用于执行不受信任的 JavaScript 和 TypeScript 的包,而不会让它直接访问你的应用或系统。应用暴露范围狭窄的宿主函数,并可以中断执行以进行身份验证或人在回路中的审批。程序在做出决定后恢复,而不会重复已完成的工作。

pnpm add run

复制标题链接面向宿主的小型接口

Run SDK 在工作线程内的全新 QuickJS 上下文中求值 JavaScript 或去除了类型的 TypeScript,没有通往 Node.js 或网络的直接路径。

应用通过 hostFunctions 暴露选定的操作

。这些是常规函数,在沙箱内成为可调用的全局变量:

import { run } from 'run';
const result = await run({ source: ` const orders = await store.listOrders("customer_123"); const total = orders.reduce((sum, order) => sum + order.amount, 0); return { count: orders.length, total }; `, hostFunctions: { store: { listOrders: async (customerId: string) => { return database.orders.findMany({ customerId }); }, }, },});
if (result.status === 'completed') { console.log(result.value);}

在这里,生成的程序知道 store.listOrders()

。数据库客户端及其凭据保留在应用程序中。

调用通过序列化跨越沙箱边界。宿主函数可以返回一个 promise,因此现有的服务客户端可以位于此接口之后,而无需传入沙箱。

你可以在演练场中尝试这一点。你在那里运行的代码只能访问页面上的宿主函数。

复制标题链接实践中的代码模式

Run SDK 是驱动 AI SDK 中代码模式工具执行的内部模块。给智能体一个程序会改变工作单元。一次模型响应就可以描述这些调用以及连接它们的逻辑:

const result = await run({ source: const accountId = "account_123"; const [account, invoices] = await Promise.all([ crm.getAccount(accountId), billing.listInvoices(accountId), ]); const overdue = invoices.filter(invoice => invoice.status === "overdue"); return { account: account.name, overdue }; , hostFunctions: { crm: { getAccount }, billing: { listInvoices }, },});

这两个请求会并发发生,而发票过滤则保留在程序本地。只有有用的结果会返回给应用程序。

这非常适合跨多个内部服务工作的智能体。研究型智能体可以在回答之前合并搜索结果。支持型智能体可以检查账户,而无需将整个账单响应放回其上下文中。

同一个包也可以驱动代码解释器,或驱动接受客户自定义转换的产品功能。在这两种情况下,应用程序都决定可用的数据和操作。

当宿主函数映射到你的产品中的操作时,它们的效果最好,例如为订单退款。暴露 orders.refund(id)

为应用程序提供了一个明确的位置来检查用户和订单。通用的请求函数会让这种权限更难推理。

复制标题链接对人在回路和身份验证的原生支持

读取发票与发起退款不同。当生成的代码触及敏感操作时,宿主函数可以中断执行:

import { getHostFunctionContext } from 'run';
const hostFunctions = { documents: { publish: async (draftId: string) => { const context = getHostFunctionContext(); if (context.resume === undefined) { context.interrupt({ kind: 'approval', message: `Publish ${draftId}?`, }); } if (context.resume.resolution !== true) { return { published: false }; } return publishDraft(draftId); }, },};

当运行被中断时,结果中会包含一个已签名的令牌,应用程序可以将其与审批请求一起保存,并在决策到达时用它来恢复运行。

恢复会重放程序,但已完成的宿主函数调用会使用其记录的结果。中断前已完成的宿主函数工作不会再次运行。被中断的函数会收到审批结果,并从那里继续执行。

当工作流必须等待身份验证时,此机制同样适用。等待期由应用程序负责;工作进程无需保持存活。

复制标题链接在限制内运行

沙箱仍需考虑会无限循环或产生超大结果的代码。createRunner()

设置共享限制:

import { createRunner } from 'run';
const runner = createRunner({ limits: { timeoutMs: 10_000, memoryLimitBytes: 32 * 1024 * 1024, },});

限制也可以按每次运行进行设置。默认值覆盖 QuickJS 堆以及跨越宿主边界的值;应用程序可以根据自身工作负载收紧这些限制。

每次调用都会获得一个新的 QuickJS 上下文。动态求值被禁用,内置原型被加固。这一边界适用于生成程序,而宿主函数仍属于受信任的应用程序代码,必须执行其常规的授权检查。

Run SDK 旨在用于应用程序内部的 JavaScript 计算。需要操作系统、包安装或进程级隔离的工作负载应改用 Vercel Sandbox。

复制标题链接提取执行层

该运行时的第一个版本位于 just-bash 中,名为

js-exec

,由 QuickJS 提供支持。它让智能体能够针对 shell 的虚拟文件系统和命令集编写 TypeScript。我们将该层提取到 Run SDK 中,并用应用程序定义的宿主函数替换了 Node 形态的环境。我们在 eve 中测试了底层机制,用它针对真实工具运行智能体生成的 TypeScript。它现在为

AI SDK 中的代码模式提供支持,其中现有的 AI SDK 工具被映射为宿主函数,而 Run SDK 负责它们的沙箱化执行。

复制标题链接快速开始

Run SDK 支持 Node.js 22.13+ 和 Bun。你需要在本地开发机器上安装 pnpm 或其他包管理器。

pnpm add run

查看文档API 参考