Executor执行内核揭秘:QuickJS WASM沙箱如何安全运行LLM生成的代码 📅 发布时间:2026/8/24 9:24:04 👁 浏览次数: Executor执行内核揭秘QuickJS WASM沙箱如何安全运行LLM生成的代码【免费下载链接】executorThe missing integration layer for AI agents. Let them call any OpenAPI / MCP / GraphQL / custom js functions in secure environment.项目地址: https://gitcode.com/gh_mirrors/executor14/executorExecutor 是一款面向 AI Agent 的开源集成层The missing integration layer for AI agents让 Claude Code、Cursor、ChatGPT 等任意 MCP 客户端都能安全调用 OpenAPI、MCP、GraphQL 与自定义函数。而它最引人瞩目的技术底座就是执行内核中基于QuickJS WASM 沙箱的安全代码执行引擎——LLM 生成的 TypeScript 代码被隔离编译成 WASM 后运行即使代码失控也触碰不到宿主机的一丝一毫。本文带你逐层拆解这套沙箱的 5 大安全机制与完整执行流水线 为什么 AI Agent 需要安全沙箱现代 AI Agent 的工作模式正在从逐个调用固定工具演进为Code ModeLLM 直接写一段 TypeScript/JavaScript 代码在里面自由组合调用几十个已注册的工具。灵活是灵活但危险也来了⚠️代码是 LLM 生成的天然不可信可能写死循环、内存爆炸、甚至尝试require(fs)读取密钥⚠️直连宿主机执行比如直接eval等于把服务器交了出去⚠️资源无上限时一段while(true)就能拖垮整个服务。Executor 的答案是把模型生成的代码放进一个由 WASM 构建的独立 JavaScript 解释器里运行——这个解释器就是 QuickJS 的 WASM 移植版。沙箱里跑的每一行代码都是由 WASM 模块内部的 QuickJS 引擎逐条解释的与宿主机的 V8 引擎完全无关。Executor 执行内核三层可插拔架构Executor 的执行内核位于packages/kernel/与packages/core/execution/分为清晰的三层层级包路径职责契约层packages/kernel/core/定义CodeExecutor契约、工具代理、TS 类型剥离、代码恢复等共享原语引擎层packages/core/execution/执行引擎engine.ts编排工具桥接、暂停/恢复、审批流运行时层packages/kernel/runtime-*具体沙箱实现QuickJS WASM、Deno 子进程、workerd 动态 Worker 等这种契约先行的设计意味着沙箱是可以替换的运行时路径隔离方式适用宿主QuickJS WASMpackages/kernel/runtime-quickjs/WASM 解释器内隔离所有宿主含 Cloudflare WorkersDeno 子进程packages/kernel/runtime-deno-subprocess/独立 OS 进程本地 CLI / 桌面端动态 Workerpackages/kernel/runtime-dynamic-worker/workerd Worker 线程Cloudflareworkerd 子进程packages/kernel/runtime-workerd-subprocess/独立进程需要 workerd API 的场景其中 QuickJS WASM 运行时README的定位非常直白Runs untrusted TypeScript/JavaScript in a WASM-backed interpreter with configurable timeout, memory limit, and stack size — safe enough to execute LLM-generated code that calls your registered tools.在 WASM 支持的解释器中运行不可信的 TS/JS可配置超时、内存与栈大小——足以安全执行调用你注册工具的 LLM 生成代码。QuickJS WASM 沙箱的 5 大安全机制核心实现全部集中在 packages/kernel/runtime-quickjs/src/index.ts值得新手重点关注的有 5 个机制1. 全新运行时一次执行一次销毁每次执行都会QuickJS.newRuntime()创建一个全新的 WASM 运行时和上下文执行完毕立即dispose()销毁。沙箱的初始全局环境里只有 QuickJS 自带的标准对象没有process没有require没有宿主对象fetch被显式替换为直接抛错的函数fetch is disabled in QuickJS executor。2. 三重资源配额超时 内存 栈深度沙箱给 LLM 代码套上了三重枷锁任何一项越界都会立即终止执行配额默认值作用timeoutMs墙钟超时5 分钟整体执行时长上限memoryLimitBytes内存上限64 MBVM 可分配内存上限maxStackSizeBytes栈深度1 MB防止无限递归更妙的是超时的实现方式宿主通过setInterruptHandler注册了一个协作式抢占钩子每次 JS 执行到检查点都会被询问该停了吗。这意味着哪怕 LLM 写了一个同步死循环宿主机也能把它精准掐断——而宿主进程对自己的主线程是无法做到这一点的见 sealed-bundle.ts 中的注释解释。3. 类型剥离 代码恢复LLM 写的脏代码也能跑LLM 最爱输出两类半成品代码Executor 在送入沙箱前分别处理类型剥离strip-types.tsQuickJS 只认纯 JavaScript而模型输出的常带: number之类的 TS 注解。Executor 用 Sucrase 做纯语法级类型剥离as T、泛型、interface 统统去掉成本低且零语义改动代码恢复code-recovery.ts模型经常把代码塞在 Markdown 的 围栏里或写成export default async () {...}的形式。恢复器会用 Babel 解析 AST自动剥掉围栏、解包export default把任意形态的代码修复成一段可直接 await 的执行体。4. 唯一的合法出口tools惰性代理沙箱里没有网络、没有文件系统那 LLM 代码如何调用外部工具答案是宿主注入的唯一桥梁——tools代理对象// LLM 生成的代码可以在沙箱内这样写 const pets await tools.petstore.findPetsByStatus({ status: available });tools是一个基于Proxy的惰性路径代理tools.petstore.findPetsByStatus这样的点路径不会真的展开成对象而是在调用那一刻把完整路径petstore.findPetsByStatus和参数序列化后通过宿主函数__executor_invokeTool回传给 Executor 引擎走完权限策略校验、凭据注入之后才真正发起 API 请求结果再以 JSON 字符串的形式送回沙箱。换句话说沙箱代码永远只能点名调用已注册的工具任何未注册路径的调用都无从抵达真实世界——这是最小权限原则在沙箱边界上的完美落地。5. 暂停与恢复人机审批流的暂停键有些工具需要人来把关OAuth 授权、危险操作审批、表单填写。当 LLM 代码在沙箱里调用这类工具时执行引擎engine.ts 的executeWithPause会将沙箱执行 fork 为后台 Fiber生成全局唯一的exec_xxx执行 ID挂起并返回PausedExecution把审批请求呈现给 UI用户批准后通过resume接口注入响应沙箱代码从原处继续跑直至完成或下一次暂停。CLI 用户同样能体验这一流程executor resume --execution-id exec_123LLM 代码执行的 6 步流水线把以上机制串起来一段 LLM 代码从生成到出结果的完整旅程是代码恢复剥离 Markdown 围栏、解包export defaultcode-recovery.ts类型剥离Sucrase 转成纯 JavaScriptstrip-types.ts源码包装注入tools代理、桥接版console日志回传宿主、emit()输出通道并禁用fetch创建沙箱全新 QuickJS 运行时套用超时/内存/栈三重配额与中断钩子异步调度宿主循环执行 WASM 内的 microtask 队列同时监控截止线——工具派发期间暂停计时DeadlineTracker避免一次慢 API 调用挤占整体预算结果回收读回result返回值、logsconsole 输出、outputemit 产物随即销毁运行时。整条链路对宿主机零侵入执行结果是一个纯粹的{ result, logs, output }数据结构。不止 QuickJS一个契约驱动的运行时生态因为CodeExecutor只是一个两行接口execute(code, toolInvoker)Executor 的执行内核实际上是一个运行时生态本地 CLI / 桌面端可以选择 Deno 子进程这种操作系统级隔离Cloudflare 部署则因平台禁止运行时代码生成ban V8 codegen必须走 QuickJS WASM——而 QuickJS 恰好是WASM 里再跑一个 JS 引擎天然绕开该限制甚至还有一个刻意更小的原语sealed-bundlesealed-bundle.ts不带工具桥、不走计量计费专门用来在同一个沙箱里跑系统自带的校验渲染与用户执行路径物理隔离。自己动手3 分钟体验 Executor 沙箱想亲手验证LLM 代码在沙箱里作恶会怎样本地跑起来只需 Node.js 20npm install -g executor # 安装 Executor CLI executor install # 安装常驻后台服务 executor web # 浏览器打开 Web UI添加集成并连接 Agent在 Web UI 的执行面板里粘贴一段含死循环的 TypeScript你会亲眼看到它在 5 分钟墙钟上限可自定义至 100ms被 QuickJS 中断钩子精准打断宿主服务纹丝不动。如果想深入源码仓库克隆地址为https://gitcode.com/gh_mirrors/executor14/executor重点阅读路径沙箱核心packages/kernel/runtime-quickjs/src/index.ts类型剥离与代码恢复packages/kernel/core/src/执行引擎与暂停/恢复packages/core/execution/src/engine.ts总结把信任边界画在 WASM 里Executor 执行内核的设计哲学可以浓缩为一句话不信任一行模型生成的代码但给它一张只写着一个出口的名片。WASM 隔离保证了物理上够不着三重配额保证了作不了大事tools代理保证了只能走正门暂停/恢复则把人类最终审批权完整地留给了你。对于正在构建 AI Agent 平台的新手开发者而言这套 QuickJS WASM 沙箱架构几乎是LLM 代码执行这一课题的参考级答案 【免费下载链接】executorThe missing integration layer for AI agents. Let them call any OpenAPI / MCP / GraphQL / custom js functions in secure environment.项目地址: https://gitcode.com/gh_mirrors/executor14/executor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考