简要定义
Sandbox 不是一个 VPS 账户。它是一次受控执行环境:拥有 Owner、生命周期、资源上限、网络策略、文件与进程 API、模板/快照来源,以及确定性的清理机制。VPS 或 Worker 只是 Sandbox Provider 背后的承载基础设施,不会直接暴露给应用开发者或 Agent。
flowchart TD
Sandbox --> Runtime[Agent Runtime]
Runtime --> Run1["Run (active)"]
Runtime --> Run2["Run (terminal lineage)"]
Runtime 必须在某个 Sandbox 之下创建——它不能脱离 Sandbox 独立存在。
为什么存在这个概念
如果直接把一台裸机或 VPS 暴露给 Agent,就没有统一的资源上限、网络隔离和清理保证。Sandbox 把这些边界收敛成一个显式、可编程的模型:创建时声明隔离级别和资源上限,销毁时确定性清理,中间的所有操作(文件、进程、Agent Run)都通过统一 API 完成,而不是通过裸 SSH。
在 Web / CLI / API 中的体现
应用通常为每个用户任务或每条隔离工作分支创建一个短生命周期 Sandbox:
const sandbox = await appaloft.sandboxes.create({
source: { kind: "template", templateId: process.env.APPALOFT_SANDBOX_TEMPLATE_ID! },
requestedIsolation: "gvisor",
limits: {
cpuMillis: 2_000,
memoryBytes: 2_147_483_648,
diskBytes: 10_737_418_240,
maxProcesses: 128,
},
networkPolicy: { mode: "deny", rules: [] },
expiresAt: new Date(Date.now() + 60 * 60 * 1_000).toISOString(),
});
try {
await sandbox.files.write({ path: "job/input.txt", contentBase64: "aGVsbG8=" });
await sandbox.exec({ argv: ["python3", "/workspace/job.py"], timeoutMs: 10_000 });
const agent = await sandbox.agents.create({ harness: "pi" });
const run = await agent.stream({ task: "检查测试失败并修复生产代码" });
for await (const envelope of run.fullStream) {
if (envelope.kind === "event") console.log(envelope.data);
}
} finally {
await sandbox.terminate();
}Run 事件会在执行过程中增量持久化;断线后可以用 run.events.stream({ afterSequence }) 从已确认的 sequence 之后继续读取,不会丢失中间输出。终止浏览器或 API 连接只会停止读取,不会取消 Run——需要真正停止执行时,必须显式调用 Run 的取消操作。
常见产品模式
Agent Runtime 从属于一个已经 ready 的 Sandbox:应用开发者保留自己的 Chat/Session,Appaloft 负责隔离执行、每个 Runtime 同时只有一个活跃 Run、fresh/continue 血缘关系、事件回放和取消。三类常见产品故事:
- Chat-to-App:用户让你的 SaaS 创建或修改一个应用。产品保留 Chat 和用户 Session,Appaloft 只接收一个有边界的任务,并在会过期的 Sandbox 中执行。
- 代码库维护:支持或工程工作流准备好 Workspace,让代码 Agent 修改,再把 Run 事件和最终结果回写到原始工单。
- 人工门控自动化:Run 遇到高风险能力时暂停执行;应用展示能力、目标地址、请求摘要和过期时间,由用户决定是否放行。
SDK 提供便捷的 Workspace + Agent 组合:
const workspace = await appaloft.workspaces.create({ sandbox: sandboxInput, harness: "opencode" });
const run = await workspace.agent.runs.create({ task: "Build the requested app in /workspace/app" });Agent 是 Sandbox Agent Runtime 的便捷别名,默认使用已准入的 Pi/OpenCode 模板并自动生成幂等键;需要显式锁定版本或续接上一次 Run 时,可以传入 harnessTemplateId、context 或 idempotencyKey。
Run 事件会限制数量、深度和字符串长度,并递归屏蔽 credential、secret、password、token 和 authorization 字段——它们不是审计事件,也不能替代完整的模型 transcript。取消操作会终止实际的客户端进程,并防止迟到的成功结果覆盖 cancelled 状态。当前 Agent 操作要求已登录的产品 Session;在正式提供作用域受限的长期应用凭据之前,不应该把 Deploy Token 当作等价的认证方式使用。
常见误区
- 把 Sandbox 当成长期运行的服务器:Sandbox 通常是短生命周期的,用完即销毁,不适合作为长期运行服务的宿主——那是 Server 和 Resource 的职责。
- 把生产凭据写进 Sandbox 环境变量或文件:生产凭据不应该出现在 Sandbox 环境变量、文件、Run 事件或错误信息中;需要调用外部目标时应使用受目标地址约束的凭据代理(credential broker),目标、方法或有效期不匹配时应该直接拒绝,而不是放行。
- 认为隔离等于信任 Agent 生成的代码:Appaloft 的隔离边界降低了宿主机的暴露面,但不会把任意依赖、模型输出或 Agent 生成的代码变成可信代码——仍然需要按不可信代码的标准去审查和限制权限。
相关任务
进阶细节
官方 examples 仓库提供完整源码:Chat-to-App、人工审批和 Preview-to-Promotion。