第 13 章:ASP——Agent Sandbox Protocol
第 13 章:ASP——Agent Sandbox Protocol
大多数 agent 跑在它执行代码的同一台机器上——大脑与双手长在一起。ASP(Agent Sandbox Protocol)要做的只有一件事:把"大脑"(agent 循环与 LLM 调用)与"双手"(沙箱里的文件系统与 shell)解耦,让任何 agent harness 通过一份
.asp.json契约文件就能把工具执行搬进远程沙箱。本章讲清它的动机、契约字段、SSH transport 的工作方式与 RFC 草案现状。
动机:把"大脑"与"双手"解耦
ASP 的目标一句话可以说完:标准化 agent harness(大脑:agent 循环、LLM 调用、凭据)与工具执行所在的沙箱(双手:文件系统、shell)之间的接口——任何 harness 通过一份声明式配置文件加一个标准 transport,就能驱动任何沙箱,harness 里不需要嵌任何 provider SDK。
为什么值得做?现状是"大脑与双手长在一起"带来一连串问题:
- 安全边界缺失:agent 与其执行环境同宿主,凭据与宿主信息暴露在 agent 可及范围内,agent 甚至可能 OOM 或杀掉自己的运行时(Vercel 关于 agentic 架构安全边界的文章对此有系统论述);
- 网络管控两难:沙箱的外网访问是 reward hacking 的重要通道,但 agent 跑在沙箱里时断网会连模型 API 一起断掉,开发者只能退而求其次维护脆弱的模型端点 allowlist;
- 复现性差:共享环境的状态漂移让结果难以复现;
- 解耦被少数玩家垄断:目前只有 agent 开发者自己能重写执行工具实现分离;在 Claude Code、Codex、pi 等现成 agent 之上构建的人只能继承其工具、无法解耦。
业界已有两种解法,但各有代价:Anthropic 的 managed agents 把 agent 系统拆成 session、orchestration、harness、sandbox、resources、tools,靠在沙箱内安装 environment worker 实现分离——代价是沙箱与该 harness 绑定;provider SDK 集成则相反,把 harness 与单一 provider 绑定。
而 ASP 的答案是:SSH 已经实现了这个缺失接口需要的全部原语——执行命令、经 SFTP 传文件、认证与主机校验。许多沙箱 provider 本来就可达 SSH 或可以配置成可达。缺的只是一个"告诉 harness 去远程执行工具、如何连接"的共享约定,ASP 提供了这个约定。
范围:刻意收窄
参照 managed agents 的组件表,ASP 刻意收窄(deliberately niche):只标准化 harness 到沙箱这一条边,且这条边上只定义 execute(name, input) -> String。
provision({resources}) 那一半被明确排除在外——供给(provisioning)是编排者的职责(例如 Harbor 本身),在 agent 启动之前由 daytona_setup.py、docker_setup.py 这类工具完成,agent 在运行时不应有自行供给资源的自由。会话、编排、资源、工具定义,都维持 harness 现状。ASP 采纳 execute、排除 provision,这条边界画得非常清醒。
契约文件:.asp.json
ASP 的全部接口就是一份 .asp.json 文件(完整 schema 见仓库中的 asp.schema.json):
| 字段 | 含义 |
|---|---|
version |
当前为 "0" |
transport |
"ssh"——首个支持的 transport;保留该字段是为了未来扩充 |
connection.host / .port / .user |
SSH 端点;provider 可把访问令牌编码在用户名里 |
connection.identity |
客户端私钥,按环境变量名或文件路径给出;令牌认证足够时可省略 |
connection.host_key |
固定的服务端公钥;省略表示 trust-on-first-use |
workspace |
沙箱内的绝对路径,相对工具路径以它为基准解析 |
harness 的工作目录(及逐级向上的父目录)中发现 .asp.json 后,就把工具 I/O 绑定到沙箱。工具调用是无状态的:每条命令一个全新 shell,但文件系统持久。最关键的设计决策是——agent 对这一切毫不知情:它不会被告知 transport 的存在,也不可能利用这个信息,因为它的所有工具都在远程执行,没有任何"动词"能触及 harness 所在的机器。它唯一能观察到的环境就是沙箱本身。边界靠能力(capability)强制,而不是靠策略或提示词。
SSH transport 的工作方式
选 SSH 作为第一个 transport 有三条理由:
- 原语齐全:命令执行、SFTP 文件传输、认证与主机校验都是 SSH 的既有能力,harness 无需发明任何新东西;
- 生态现成:大量沙箱 provider 已原生可达 SSH(如 Daytona 的托管网关、令牌即用户名),容器场景里跑个 sshd、发布端口即可(如 Docker);
- 网络方向正确:SSH 是入站(ingress)——有状态防火墙放行 harness 发起连接的回包,丢弃沙箱主动发起的所有连接。于是工具照常工作而沙箱外网全断(已在 Daytona 与 Docker 上验证),ASP 与"沙箱断网"天然组合。
两层工具架构
改造一个现成 agent 支持 ASP,只需要两步:检测 .asp.json,把工具的原始 I/O(read、write、exec)改道到配置的 transport。之所以代价这么小,是因为 agent 工具天然分成两层:
flowchart TB
subgraph P["策略层(policy layer)——留在 harness,一行不改"]
S1[工具 schema
path / offset / limit]
S2[截断限制 / 分页]
end
subgraph M["机制层(mechanism layer)——唯一被替换的缝隙"]
F1[read]
F2[write]
F3[exec]
end
P --> M
M -- 本地 I/O(改造前) --> L[本机文件系统与 shell]
M -- 同样的 I/O 走 transport(改造后) --> R[远程沙箱]策略层面向模型:工具 schema(path、offset、limit)、截断限制、分页——这些留在 harness 里原样运行;机制层是底下一小撮原始 I/O 函数。ASP 只换机制层:本地 I/O 变成经网络走同一 I/O。于是模型看到的工具行为完全一致,既有提示词与评测可以直接平移。
示例与支持矩阵
官方给出两个 ASP 实现示例:一个用 asyncssh SDK 的原生 Python agent,以及为极简 harness pi 写的扩展 pi-asp.ts。两个示例都在 MVP 中验证通过。
SSH SDK 支持矩阵(节选):
| 语言 | 库 | 备注 | MVP 已验证 |
|---|---|---|---|
| Python | asyncssh | 异步,SFTP 支持干净 | 是 |
| Python | paramiko | 同步,成熟 | 否 |
| TypeScript | ssh2 | Node 标准库;ssh2-sftp-client 补充 Promise SFTP | 否 |
| Go | golang.org/x/crypto/ssh | 官方扩展标准库 | 否 |
| Rust | russh | 异步(tokio),含 SFTP | 否 |
| 任意 | OpenSSH client | 零依赖;ControlMaster 连接复用 | 是 |
沙箱 provider 侧(节选):
| Provider | 方式 | MVP 已验证 |
|---|---|---|
| Docker | 容器内 sshd + 发布端口 | 是(含断网验证) |
| Apple Container | 容器内 sshd + 可路由 VM IP | 是 |
| Daytona | 托管网关,令牌即用户名 | 是(含 SFTP 与 network_block_all) |
| E2B | 文档记载经 websocat ProxyCommand over WSS,自定义模板 | 否;需 proxyCommand 字段 |
| Modal | 无原生 SSH 端点;sshd 加 Modal tunnel 应可行 | 否 |
| GKE | 无原生 SSH 端点;pod 内 sshd 加 port-forward | 否 |
RFC 草案现状与展望
ASP 目前是 v0 草案,托管在 Harbor 仓库的 PR #3023 中,由 @alexgshaw 发起并共同设计,评论公开征集。草案明确了两个方向:
- 近期:推出 terminus-slim——基于 ASP 的 Terminus 版本;
- 中期:v0 从 SSH 起步,但格式可为 stdio、HTTP 等更多 transport 预留空间;一个更有主见的版本还可能定义与 transport 无关的操作与类型,用于生成 SDK。
草案同时声明:v0 阶段一切内容(包括 schema)都可能在未来 v0.1 或 v1 中变更。对工程团队的建议是:现在就可以在开发环境中试点 .asp.json 契约,但生产化集成应等版本稳定。
本章小结
- ASP 标准化 agent harness(大脑)与沙箱(双手)之间的接口,目标是一份声明式配置驱动任何沙箱、harness 内零 provider SDK。
- 动机来自真实痛点:同宿主运行缺少安全边界、断网与模型 API 冲突、共享环境不可复现,而现有解法(environment worker、provider SDK)都以单向绑定为代价。
- 范围刻意收窄:只定义 harness 到沙箱边的
execute(name, input) -> String;provisioning 明确交给编排者(如 Harbor),agent 运行时不得自供资源。 - 契约文件
.asp.json字段:version、transport、connection.host/.port/.user、connection.identity、connection.host_key、workspace;从工作目录逐级向上查找。 - 工具调用无状态(每命令新 shell、文件系统持久);agent 对远程执行毫不知情,边界靠能力强制而非提示词。
- SSH 是首个 transport:原语齐全(exec、SFTP、认证)、provider 生态现成、入站方向让"工具可用 + 外网全断"自然成立。
- 两层工具架构是低改造成本的根源:只换机制层的 read/write/exec,策略层与既有提示词、评测原样保留。
- 现状为 v0 RFC 草案(PR #3023),schema 仍可能变更;近期计划包括 terminus-slim 与更多 transport。
延伸阅读
- ASP——本章对应的官方页面(RFC 草案全文)
- PR #3023——RFC 讨论与评论入口
- Pre-integrated sandboxes——可承载 ASP 的沙箱清单(见本书第 12 章)
- Vercel: Security boundaries in agentic architectures——解耦动机的系统论述
- Anthropic: Managed agents——对照阅读的组件化方案