Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Sandboxes GA:agent 拥有了自己的电脑

原文:Agents have their own computers with Sandboxes GA / 2026-04-13 Source: https://blog.cloudflare.com/sandbox-ga/

去年六月我们发布 Cloudflare Sandboxes 时,前提很简单:AI agent 需要开发和运行代码,而它们需要在某个安全的地方做。

如果一个 agent 像开发者一样行事,这意味着克隆仓库、用多种语言构建代码、运行开发服务器等等。要有效地做这些,它们通常需要一台完整的电脑(如果不需要,它们可以 伸手够一些更轻量的东西)。

很多开发者用 VM 或现有容器方案拼凑解法,但有一堆难题要解决:

  • 突发性 —— 每个会话都需要自己的沙箱,你常常需要快速拉起多个,但又不想为待机的闲置算力付费。

  • 快速状态恢复 —— 每个会话都应该快速启动、快速重启,恢复过去的状态。

  • 安全 —— agent 需要安全访问服务,但不能被托付凭据。

  • 控制 —— 需要简单地以编程方式控制沙箱的生命周期、执行命令、处理文件等等。

  • 人机工效 —— 你需要为人类和 agent 都给出一个简单接口来做常见操作。

我们花时间解决了这些问题,这样你就不必。从最初发布以来,我们让 Sandboxes 成为一个更适合规模化运行 agent 的地方。我们和最初的合作伙伴(如在 Figma Make 中用容器跑 agent 的 Figma)一起工作:

“Figma Make 旨在帮助各种背景的构建者和创造者更快地从想法走向生产。要兑现这个目标,我们需要一个能提供可靠、高度可扩展沙箱的基础设施方案,在那里可以运行不可信的 agent 和用户编写的代码。Cloudflare Containers 就是这个方案。”

Alex Mullans,Figma 的 AI 与开发者平台

我们想把 Sandboxes 带给更多优秀组织,所以今天我们激动地宣布:Sandboxes 和 Cloudflare Containers 现已正式可用(GA)。

下面看看 Sandboxes 最近的几项变化:

  • 安全凭据注入 让你在 agent 从不接触凭据的情况下完成认证调用

  • PTY 支持 给你和你的 agent 一个真实的终端

  • 持久代码解释器 给你的 agent 一个开箱即用、跨调用保留状态的执行 Python、JavaScript 和 TypeScript 的位置

  • 后台进程和实时预览 URL 提供一种简单方式与开发服务器交互、验证进行中的修改

  • 文件系统监听 提升 agent 修改时的迭代速度

  • 快照 让你快速恢复 agent 的编码会话

  • 更高的限额和按 Active CPU 计价 让你以规模部署 agent 队列,而无需为未使用的 CPU 周期付费

Sandboxes 101

在进入最近的变化之前,我们先快速看看基础。

一个 Cloudflare Sandbox 是一个由 Cloudflare Containers 驱动的、持久且隔离的环境。你按名字请求一个 sandbox。如果它在跑,你拿到它。如果它不在,它启动。当它闲置,它自动睡眠并在收到请求时唤醒。用诸如 execgitClonewriteFile 以及 更多 方法以编程方式与 sandbox 交互很容易。

import { getSandbox } from "@cloudflare/sandbox";
export { Sandbox } from "@cloudflare/sandbox";

export default {
  async fetch(request: Request, env: Env) {
    // Ask for a sandbox by name. It starts on demand.
    const sandbox = getSandbox(env.Sandbox, "agent-session-47");

    // Clone a repository into it.
    await sandbox.gitCheckout("https://github.com/org/repo", {
      targetDir: "/workspace",
      depth: 1,
    });

    // Run the test suite. Stream output back in real time.
    return sandbox.exec("npm", ["test"], { stream: true });
  },
};

只要你提供同一个 ID,后续请求可以从世界上任何地方触达同一个 sandbox。

安全凭据注入

agentic 工作负载里最难的问题之一是认证。你常常需要 agent 访问私有服务,但又不能完全信任它们持有原始凭据。

Sandboxes 通过在网络层使用可编程的出口代理注入凭据来解决这个问题。这意味着 sandbox 内的 agent 永远不会接触凭据,你可以按需完全自定义认证逻辑:

class OpenCodeInABox extends Sandbox {
  static outboundByHost = {
    "my-internal-vcs.dev": (request, env, ctx) => {
      const headersWithAuth = new Headers(request.headers);
      headersWithAuth.set("x-auth-token", env.SECRET);
      return fetch(request, { headers: headersWithAuth });
    }
  }
}

要深入了解这如何工作——包括身份感知的凭据注入、动态修改规则,以及与 Workers bindings 的集成——请阅读我们最近关于 Sandbox auth 的博文。

真实的终端,不是模拟

早期 agent 系统常常把 shell 访问建模成请求-响应循环:跑一个命令、等输出、把记录塞回 prompt、重复。它能用,但不是开发者真正使用终端的方式。

人类跑些什么、看着输出流入、打断它、稍后重连、继续。Agent 也能从同样的反馈循环受益。

二月,我们发布了 PTY 支持。一个 sandbox 内的伪终端会话,通过 WebSocket 代理,与 xterm.js 兼容。

只需调用 sandbox.terminal 提供后端:

// Worker: upgrade a WebSocket connection into a live terminal session
export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);
    if (url.pathname === "/terminal") {
      const sandbox = getSandbox(env.Sandbox, "my-session");
      return sandbox.terminal(request, { cols: 80, rows: 24 });
    }
    return new Response("Not found", { status: 404 });
  },
};

并使用 xterm addon 从客户端调用它:

// Browser: connect xterm.js to the sandbox shell
import { Terminal } from "xterm";
import { SandboxAddon } from "@cloudflare/sandbox/xterm";

const term = new Terminal();
const addon = new SandboxAddon({
  getWebSocketUrl: ({ origin }) => `${origin}/terminal`,
});

term.loadAddon(addon);
term.open(document.getElementById("terminal-container")!);
addon.connect({ sandboxId: "my-session" });

这让 agent 和开发者可以用一个完整的 PTY 现场调试这些会话。

每个终端会话有自己的隔离 shell、自己的工作目录、自己的环境。你需要多少就开多少,就像在自己机器上一样。输出在服务端缓冲,所以重连会回放你错过的内容。

一个会记忆的代码解释器

对数据分析、脚本编写和探索性工作流,我们也提供了一个更高层的抽象:一个持久的代码执行上下文。

关键词是“持久“。许多代码解释器实现把每个片段隔离运行,所以状态在调用之间消失。你不能在一步设置变量、下一步读取它。

Sandboxes 让你创建保留状态的“context“。变量和导入跨调用保留,就像 Jupyter notebook 一样:

// Create a Python context. State persists for its lifetime.
const ctx = await sandbox.createCodeContext({ language: "python" });

// First execution: load data
await sandbox.runCode(`
  import pandas as pd
  df = pd.read_csv('/workspace/sales.csv')
  df['margin'] = (df['revenue'] - df['cost']) / df['revenue']
`, { context: ctx });

// Second execution: df is still there
const result = await sandbox.runCode(`
  df.groupby('region')['margin'].mean().sort_values(ascending=False)
`, { context: ctx, onStdout: (line) => console.log(line.text) });

// result contains matplotlib charts, structured json output, and Pandas tables in HTML

启动一个服务器,得到一个 URL,发布它

Agent 在能构建一些东西并立刻给用户看时更有用。Sandboxes 支持后台进程、就绪检查和 预览 URL。这让 agent 可以启动一个开发服务器,并在不离开对话的情况下分享一个实时链接。

// Start a dev server as a background process
const server = await sandbox.startProcess("npm run dev", {
  cwd: "/workspace",
});

// Wait until the server is actually ready — don't just sleep and hope
await server.waitForLog(/Local:.*localhost:(\d+)/);

// Expose the running service with a public URL
const { url } = await sandbox.exposePort(3000);

// url is a live public URL the agent can share with the user
console.log(`Preview: ${url}`);

借助 waitForPort()waitForLog(),agent 可以基于运行程序发出的真实信号来安排工作,而不是靠猜。这比常见替代方案——通常是 sleep(2000) 然后祈祷——好得多。

监听文件系统并立即响应

现代开发循环是事件驱动的。保存一个文件,重新构建。改一个 config,重启服务器。改一个测试,重跑套件。

我们三月发布了 sandbox.watch()。它返回一个由原生 inotify(Linux 用于文件系统事件的内核机制)支撑的 SSE 流。

import { parseSSEStream, type FileWatchSSEEvent } from '@cloudflare/sandbox';

const stream = await sandbox.watch('/workspace/src', {
  recursive: true,
  include: ['*.ts', '*.tsx']
});

for await (const event of parseSSEStream<FileWatchSSEEvent>(stream)) {
  if (event.type === 'modify' && event.path.endsWith('.ts')) {
    await sandbox.exec('npx tsc --noEmit', { cwd: '/workspace' });
  }
}

这是那种悄悄改变 agent 能做什么的原语之一。一个能实时观察文件系统的 agent,可以参与到与人类开发者同样的反馈循环中。

用快照快速唤醒

想象一个(人类)开发者在笔记本上工作。他 git clone 一个仓库,跑 npm install,写代码,推一个 PR,然后在等代码审查时合上笔记本。当要继续工作时,他重新打开笔记本,从离开的地方继续。

如果一个 agent 想在朴素的容器平台上复刻这个工作流,你会撞上一个坎。如何快速从离开的地方继续?你可以让 sandbox 一直跑,但那要为闲置算力付费。你可以从容器镜像全新启动,但要等漫长的 git clonenpm install

我们的答案是快照,将在未来几周陆续发布。

快照保留容器的完整磁盘状态,OS config、安装的依赖、修改过的文件、数据文件等等,然后让你稍后快速恢复。

你可以配置一个 Sandbox,在它进入睡眠时自动快照。

class AgentDevEnvironment extends Sandbox {
  sleepAfter = "5m";
  persistAcrossSessions = {type: "disk"}; // you can also specify individual directories
}

你也可以以编程方式拍快照并手动恢复。这对检查点工作或分叉会话很有用。例如,如果你想并行跑四个 agent 实例,你可以轻松地从同一状态启动四个 sandbox。

class AgentDevEnvironment extends Sandbox {}

async forkDevEnvironment(baseId, numberOfForks) {
  const baseInstance = await getSandbox(baseId);
  const snapshotId = await baseInstance.snapshot();

  const forks = Array.from({ length: numberOfForks }, async (_, i) => {
    const newInstance = await getSandbox(`${baseId}-fork-${i}`);
    return newInstance.start({ snapshot: snapshotId });
  });

  await Promise.all(forks);
}

快照存放在你账户内的 R2 中,提供持久性和位置独立性。R2 的 分层缓存 系统让在 Region: Earth 范围内的恢复都很快。

未来发布中,实时内存状态也将被捕获,让运行中的进程能从离开的地方精确继续。一个终端和一个编辑器将以上次关闭时的精确状态重新打开。

如果你有兴趣在快照上线前恢复会话状态,你今天可以使用 backup and restore 方法。它们也用 R2 持久化和恢复目录,但不如真正的 VM 级快照高性能。不过它们仍然能比朴素地重建会话状态带来可观的速度提升。

启动一个 sandbox、克隆 ‘axios’ 并 npm install 用 30 秒。从备份恢复用 2 秒。

请关注官方快照发布。

更高限额与按 Active CPU 计价

自最初发布以来,我们一直在稳步增加容量。标准价格计划上的用户现在可以并发跑 15,000 个 lite 实例、6,000 个 basic 实例,以及 1,000+ 个更大的并发实例。要跑更多请 联系我们!

我们也调整了价格模型,使其在规模运行时更具成本效益。Sandboxes 现在 只对实际使用的 CPU 周期计费。这意味着你不会为 agent 等 LLM 响应时的闲置 CPU 付费。

这就是一台电脑该有的样子

九个月前,我们发布了一个能跑命令、访问文件系统的 sandbox。那足以验证概念。

我们现在拥有的是另一个层面的东西。今天的 Sandbox 是一个完整的开发环境:可以连接浏览器的终端、带持久状态的代码解释器、带实时预览 URL 的后台进程、实时发出变更事件的文件系统、用于安全凭据注入的出口代理,以及让热启动几乎瞬间完成的快照机制。

当你在它之上构建,会浮现一个令人满意的模式:做真实工程工作的 agent。克隆一个仓库,装它,跑测试,读失败,改代码,再跑测试。让一个人类工程师高效的那种紧密反馈循环——现在 agent 也拥有了。

我们处在 SDK 的 0.8.9 版本。今天就能开始:

npm i @cloudflare/sandbox@latest

– 原文译于 2026-04-30