第 13 章

第 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。

延伸阅读