Serverless Agent 和 Agent in Sandbox:我们的实践感受

这两年做 Agent 业务,我们更多的实践是在做 Serverless Agent,通过提供合适的工具和文件系统集成,让 Agent 以为自己是在一个服务器上运行。后来从 Manus 开始,行业看到了 Agent in Sandbox 的能力上限,给 Agent 一个完整的操作系统,能力确实远超受限的工具集。openclaw 开源之后,更多团队开始真正动手实践这种模式,我们也基于它做过一些尝试。

主业务层面,我们现在仍然是 Serverless Agent 为主;Sandbox 也深度试过。两种方案的痛点和适用场景确实不一样,下面就只讲我们的真实感受。

不过在聊具体方案之前,有一个容易混淆的点值得先说清楚:Sandbox 不等于 24 小时常驻。我们在比较这两种方案时,实际上涉及三件事:执行环境的能力边界、Agent 的生命周期、敏感能力怎么暴露。后面的讨论主要围绕第一点展开,但长生命周期部署带来的问题会单独拎出来讲,因为很多 “Sandbox 的缺点” 其实是常驻部署的锅。

Serverless Agent

过往我们选择 Serverless Agent 的目的是好扩缩容。我只需要管理好文件系统挂载和备份,短时间的 Agent 对话就可以做成 Serverless 的。更关键是执行环境也可控,我们可以管控工具和敏感的 API,大多数情况下 Agent 拿不到我们的敏感工具和用户 BYOK 使用的 key。

优点

  1. 扩缩容友好。面对突发流量,通常只需要 Agent core loop 可以快速扩容,其他模块在我们的场景下一般不会成为瓶颈
  2. 可控性强。敏感的工具调用和权限由我们设计的流程和用户审批来决定
  3. 攻击面小。有状态环境仅在 Agent loop 运行期间存在,过后就清理回收
  4. 成本结构清晰,交付链路短。在我们当前的实现里,基本只为实际计算时间付费,空闲期间不产生额外开销。用户发一条消息,Agent 跑完就走,不需要维护长连接状态
  5. 升级路径集中。控制面统一,部署一次所有用户即可生效,相比分布式沙箱更容易统一升级和回滚,但这不意味着没有升级风险,模型版本切换、tool schema 变更、存储兼容性等仍然可能导致问题

缺点

  1. 用户隔离需要花心思。高资源消耗的任务放在一起可能互相挤占
  2. 工具接入成本高。有的工具 CLI 完备但没有 API / MCP 实现,我们需要做一层封装才能让 Agent 用上,尤其是涉及鉴权的工具。通过 shell 可以覆盖大部分 CLI,但涉及鉴权、OAuth 等场景仍然需要额外开发
  3. 运行环境不跨会话持久。文件系统是持久化的,但会话中安装的依赖、插件会随会话结束回收,下次对话需要重新配置

Agent in Sandbox

早期的 e2b、Deno 等沙箱,更多是临时运行不信任代码而使用的。Manus 让大家看到了给 Agent 一个完整 OS 的能力上限,而 openclaw 的开源真正让大量团队开始动手实践。

在一些特定接入方式下,Sandbox 容易被实现成长生命周期进程。比如 openclaw 的部分 IM channel 天生不支持 webhook,如果不做额外的 gateway 抽象转发,沙箱就必须持续运行来保持心跳。这不是 Sandbox 的必然要求,但一旦走到这条路上,成本和安全问题会被显著放大。

不论生命周期长短,Agent in Sandbox 都需要花更多时间在减少密钥暴露面上。沙箱环境可能是不受信的,任何外部事件、Prompt Injection 都有可能导致沙箱被攻陷。

优点(完整 OS 能力带来的)

  1. 工具接入成本大幅降低。这是和 Serverless “工具需要单独开发” 形成直接对比的核心优势。Agent 拥有完整操作系统,不必为每个工具补 API / MCP 封装,可以直接复用现有的 CLI、脚本和生态。面对未知任务时,Agent 能自己装依赖、写脚本、跑测试、看日志来试错。这才是 Sandbox 模式火起来的根本原因,不是因为 24h 在线,而是因为能力上限高了一个量级。skills 机制作为配套的能力分发体系,进一步放大了这个优势
  2. 贴近用户的触达方式。在某些需要心跳保活的 IM 接入场景下,常驻的 Sandbox Agent 可以直接嵌入 IM 系统,配合定时任务和心跳机制,具备一定程度的主动性,能在用户未发起对话时执行预定任务
  3. 状态持久化天然支持。文件、数据库、配置都持久存在于沙箱中,多轮对话之间不需要序列化 / 反序列化上下文,Agent 可以在之前的工作基础上继续推进
  4. 默认隔离边界更清晰。每个用户独占一个完整沙箱环境,租户间的数据污染和资源互占风险更低。但实际的隔离强度还取决于宿主机隔离级别、网络策略、凭证代理方式等

缺点(主要来自长生命周期部署)

  1. 成本高。Sandbox 按秒计费,长期运行折算下来甚至比单独采买服务器还贵,而我们只是用上了快速启动、内存暂停备份等能力。VPS 没有沙箱的快速启停 / 内存快照能力,运维成本也高。所以按需启动的沙箱才是平衡点
  2. 运维困难、调试困难。过去我们升级 Agent 版本,用户是无感的。而现在的 Sandbox,当用户量大的时候就变成了某种意义上的客户端,想想 Android 和 iOS 的 APP 升级,只不过介于手机客户端和服务端之间。我们需要预埋升级脚本等机制,才能控制好沙箱业务逻辑的升级,同时还有升级失败的风险。如果业务需要多人协作同一个 Agent 环境,权限和并发控制也会变复杂
  3. 攻击面变大。长期运行的沙箱持续暴露在外部输入中,用户交互、触发任务、浏览查询资料,任何一个环节都可能成为 Prompt Injection 的入口。一旦 Agent 被诱导执行恶意操作,它在沙箱内的读写能力和持久状态都可能被滥用,而长期在线意味着这种风险持续存在,爆炸半径极大
  4. 状态漂移。沙箱运行时间越长,环境越偏离预期基线。调试的时候你不知道这个沙箱经历了什么,容易出现“我这边复现不了”的问题

我们的实践:如何应对 Sandbox 的问题

业界对沙箱中的密钥管理有两种主流模式,参考 browser-use 的总结:一种是 Isolate the Tool,Agent 跑在后端,只把危险操作隔离到沙箱;另一种是 Isolate the Agent,整个 Agent 跑在沙箱里,沙箱内零密钥,所有敏感操作经过外部的 Control Plane 代理。从密钥与敏感能力的暴露方式来看,而不是部署形态的一一对应,我们的 Serverless Agent 更接近前者,而 Sandbox 方案则采用了后者的思路。

核心思路是:不把密钥塞进沙箱,而是反过来,沙箱内零密钥,所有敏感能力统一过网关。

  1. 控制沙箱启停时间。大多数用户的对话和定时任务覆盖全天时间有限,我们设计了方案来探测沙箱的存活,空闲时暂停,有需要时拉起。效果上,沙箱的实际运行时长降到了全天的 5%-30%,取决于用户使用强度,成本显著下降;代价是引入了启停调度的复杂度,偶尔会出现用户消息到达时沙箱还在拉起中的延迟
  2. Gateway 层控制敏感信息的暴露范围。我们将敏感的内部系统请求、LLM 请求、业务封装的工具 Token 用统一的业务 Token 代替,请求指向网关,由网关控制 OAuth Token 后续能力的调用和限制,同时做审计、用户确认和计费。沙箱暂停期间可以直接拒绝敏感请求,进一步收窄攻击面。这个方案基本解决了密钥暴露的问题,但网关本身成了新的单点,需要额外的高可用和限流设计
  3. 升级机制。我们通过预埋升级脚本,在拉起沙箱时静默执行动态更新,达成 skills 等能力的动态下发,逐步灰度到最新状态。目前能覆盖大部分常规升级,但涉及底层依赖变更的升级仍然需要人工介入

总结

这两种方案不是谁替代谁的关系,核心区别在于执行环境的丰富度,Serverless 是受限工具集,Sandbox 是完整 OS。我们目前的选择是 Serverless 为主路,Sandbox 作为补充

一个简单的选型参考:当任务边界清晰、工具可前置集成、合规压力高时,优先 Serverless;当任务开放度高、工具异构、需要长期工作记忆和自主探索时,再考虑 Sandbox,并尽量避免默认长期常驻。

Sandbox 的价值在能力上限,它的难点在于一旦走向长生命周期和强状态,工程复杂度会迅速上升。对于商业化场景,按需启动的 Sandbox 可能是更务实的选择,既保留了完整 OS 的能力上限,又规避了长时间运行带来的成本和安全问题。