Agent Client Protocol (ACP)为Codex/OpenCode等编程Agent定义统一接口与会话合约;支持远程执行、权限询问、状态同步。
在远程 Sandbox 中使用 ACP 统一 Codex、OpenCode 和 Pi
想象 Codex 需要检查远程 VM 中的一个仓库。它需要读取该副本、在那里运行命令、请求权限,并将更新发送回你的应用。这是一个会话,而不是一个 shell 命令。
Agent Client Protocol,即 ACP,为客户端和编码 agent 提供了一个共享的会话契约。客户端启动一个具有 ACP 能力的 agent 进程、初始化连接、创建会话、发送 prompt、接收更新、处理来自 agent 的请求,以及在完成时关闭会话。它可以使用 stdin 和 stdout,这对于在远程环境中运行的 agent 很合适。
该协议是为应用程序(如代码编辑器)运行编码 agent 并与其通信而构建的。通常它们在同一台机器上运行,并通过 stdin 和 stdout 交换消息。
我们可以在远程环境中使用相同的安排。应用程序保持在原位;编码 agent 运行在 Sandbox 中。协议连接它们。它不创建 Sandbox 或安装 agent,但 Codex、OpenCode 和 Pi 都可以在运行后使用相同的连接。
共享客户端使用 ACP 的 TypeScript SDK。
在文件和命令所在的同一位置运行 agent。
本文使用 Agent Markup Language(即 AML)作为具体示例。这是一个 MIT 许可的 TypeScript 和 JSX 运行时,用于组合 agent 工作流、工具、Sandbox 和持久 Workspace。我们最近将其内置的编码 agent 迁移到 ACP,使其会话生命周期不再随选定的执行环境而变化。
在 AML 中,Sandbox 和 Workspace 是命名的运行时资源,不是通用标签。Sandbox 提供执行环境并附加工作文件;Workspace 拥有这些文件及其持久性。
AML Agent provider 是编码 agent 的通用接口。codexAgent()、opencodeAgent() 和 piAgent() 各自返回一个。provider 映射该 agent 的自身配置和能力;共享运行时处理会话、消息、stdin 和 stdout、MCP 服务器、取消和清理。
远程运行 agent 需要两件事。远程机器需要安装 agent 程序。你的应用需要一种方式来向它发送 prompt、接收其更新,以及在工作结束时停止它。ACP 所做的是标准化你的应用和 agent 之间的协议。
ACP 不会为你安装任何东西。如果你的远程容器或 VM 将运行 Codex、OpenCode 或 Pi,该程序需要先在镜像或快照中。对于快速实验,你可以作为设置的一部分安装它。对于可重复的工作,将其构建到镜像中,以便启动是可预测的。
Sandbox 拥有远程环境:进程运行的位置和它拥有的访问权限。Agent provider 提供命令和配置。ACP 然后以相同的方式将你的应用连接到该进程,无论你选择哪个 agent。
该协议本身并不使远程执行安全。Sandbox 的文件系统、网络和进程限制完成了这项工作。

在我们实现 ACP 之前,Sandbox 支持是三个独立的集成。每个 agent 都有自己对一个基本问题的答案:当文件和命令在其他地方时,我如何运行?
Pi 作为一个 SDK 留在应用程序内部。我们重建了 Pi 的 Bash 工具,以便 shell 命令调用 Sandbox 运行程序而不是主机 shell。Pi 本身不是一个与 Sandbox 通话的 RPC 客户端。我们为其 Bash 工具提供了一个自定义桥接。
Codex 在 Sandbox 内作为 CLI 运行。我们在那里创建了它的临时 Codex 状态,在那里写入了任何 JSON 输出 schema,为每个回合调用 CLI,读取其 JSON 事件,跟踪其线程 ID,然后删除其状态。
OpenCode 需要两条路径。在应用程序主机上,我们启动了一个 OpenCode 服务器,等待它监听,并将客户端连接到它。在 Sandbox 中,我们改为运行 opencode CLI,在那里保持一个单独的数据库和配置,并解析其 JSON 输出。CLI 在 Sandbox 内启动了 OpenCode 的服务器。
这些都是使一个 agent 工作的合理方式。总体来说,它们使每个新的 Sandbox provider 成为一个更大的工作。它需要为 Pi 支持嵌入式工具桥接、为 Codex 支持托管 CLI,以及为 OpenCode 支持服务器/客户端路径和单独的 CLI 路径。
ACP 理清了这一点。这三个现在都使用相同的协议与运行时通话。每个 Agent provider 告诉运行时要运行哪个程序以及如何配置它。共享代码在选定的 Sandbox 中启动该程序、设置会话、附加 MCP 服务器、发送 prompt 和 FollowUp、读取更新、处理取消和清理。
agent 仍然在其模型、凭证、工具和工作方式上存在差异。运行时停止维护在 Sandbox 中运行每个 agent 的单独方式。
这是一个具有 Daytona 设置外观的示例。在没有选择镜像或快照的情况下,provider 要求 Daytona 创建默认环境。
import { Agent, AmlRuntime, codexAgent, daytonaSandbox, localWorkspace, Sandbox, Workspace } from "@aml-jsx/sdk"
const Codex = codexAgent({})
const RemoteSandbox = daytonaSandbox({
config: {
apiKey: process.env.DAYTONA_API_KEY!,
},
})
const Project = localWorkspace({
directory: process.cwd(),
})
const runtime = new AmlRuntime()
await runtime.evaluate(
<Workspace id="project" provider={Project}>
<Sandbox access="read-write" provider={RemoteSandbox}>
<Agent provider={Codex}>
Inspect the repository, run the relevant tests, and implement the requested change.
</Agent>
</Sandbox>
</Workspace>,
)
对于 Daytona,运行时创建远程 Sandbox 并转移 Workspace 文件的进出。如果该 Sandbox 可以运行 codex-acp,它会在那里启动程序并通过 stdin 和 stdout 使用 ACP 与它通话。当工作结束时,它将 Workspace 的更改复制回来并释放远程 Sandbox。
你的工作流不需要自己的远程 agent 设置。将 Agent provider 更改为 OpenCode 或 Pi。将 Sandbox 更改为 Docker、受信任的本地执行或 Modal。设置代码会改变,但描述工作的树保持不变。
结果是一个共享的会话路径,环境设置仍然是显式的。兼容的 Sandbox 必须提供选定的 agent 可执行文件;运行时不再需要为 Codex、OpenCode 和 Pi 使用不同的会话路径。
AML 处于积极开发阶段,其公共 API 在首个稳定版本发布前可能会改变。检查存储库中的 ACP 引擎、Agent provider 和 Sandbox 适配器,或在项目网站上查看运行时模型和当前 provider 支持。
如果这对你的堆栈有用,请在 GitHub 上给 AML 加星,并发表评论:你会在你的堆栈中如何使用它?
进一步的操作,你可能需要考虑屏蔽此人和/或举报滥用。