核心摘要

Agent Client Protocol(ACP)v1 是编码智能体与面向开发者的客户端之间的开放 JSON-RPC 2.0 契约,客户端通常是 IDE 或代码编辑器。它标准化会话建立、提示轮次、消息和工具状态流、权限请求、文件访问、终端执行、取消以及可选的会话恢复。

ACP 解决的是集成问题,不是自主性或安全问题。消息符合协议,不代表智能体可信、文件路径已获授权、命令安全,也不能证明外部写入恰好执行了一次。

目录

核心要点

  • ACP 连接交互式客户端与编码智能体,不负责连接任意两个智能体。
  • 稳定 ACP 的线协议兼容性由整数 protocolVersion 协商,可选行为由能力协商决定。
  • ACP 必须双向工作,因为智能体会请求客户端拥有的文件、终端、信息征询和权限决定能力。
  • session/update 描述过程和结果,原始 session/prompt 响应则通过停止原因结束本轮交互。
  • 权限界面、身份认证、对象级授权、沙箱、幂等和故障恢复仍由具体实现负责。
  • 已发布的远程 HTTP 与 WebSocket 设计仍是 Active RFD,应依据目标实现的明确支持部署,不能假定普遍兼容。

ACP 标准化了哪一层边界?

ACP 标准化开发者界面应用与编码智能体程序之间的边界。它把编辑器界面和本地环境,与可替换模型、提示词、工具和控制循环的智能体运行时分离开。

没有共享协议时,每个编辑器和智能体组合都需要专用适配器。编辑器要分别理解各家的流式事件、工具结构、权限回调、会话状态和进程行为;智能体也要分别适配每个编辑器的文件、终端、代码差异和用户交互能力。ACP 为两端提供共同契约,将 N 个编辑器乘 M 个智能体的重复集成压缩为各自实现一次协议。

两个核心角色分别负责:

角色 主要职责 不会自动拥有
客户端(Client) 用户界面、编辑器状态、本地能力暴露、权限展示 智能体推理、模型调用、工具实现
智能体(Agent) 处理提示、驱动模型循环、协调工具、报告进度、维护会话上下文 编辑器界面、不受限的本地访问、后端业务授权

「客户端」这个名称容易造成误解,因为双方都能发起请求。它表示面向用户的一侧,而不是只能单向调用的网络客户端。客户端调用 initializesession/prompt 等智能体方法;智能体也可以反向调用 fs/read_text_filesession/request_permission 等客户端方法。

ACP 当前稳定的线协议版本是 1。官方仓库明确区分协商得到的线协议版本,以及 SDK、Crate、生成 Schema 制品各自的发布版本。两个不同版本的 Schema 制品可能描述同一个 v1 线协议,所以兼容性必须依据 protocolVersion 和能力集合判断,不能只比较依赖包版本号。

ACP v1 连接如何工作?

ACP v1 交互依次经过初始化、会话建立、一个或多个提示轮次,以及显式取消或清理。这个生命周期让客户端能够完整呈现智能体工作过程,但不需要接管智能体内部的推理循环。

sequenceDiagram participant U as 开发者 participant C as ACP 客户端 participant A as 编码智能体 U->>C: 提交任务 C->>A: initialize A-->>C: 版本与能力 C->>A: session/new A-->>C: sessionId C->>A: session/prompt A-->>C: session/update 流 A->>C: session/request_permission C-->>A: 选择或取消 A-->>C: 工具状态与差异更新 A-->>C: stopReason

初始化用于协商支持范围

每条连接都从 initialize 开始。客户端发送自己支持的最新主协议版本、可选能力和通常应提供的实现信息;智能体返回选定版本、自身能力、可用认证方式和实现信息。

json
{
  "jsonrpc": "2.0",
  "id": 0,
  "method": "initialize",
  "params": {
    "protocolVersion": 1,
    "clientCapabilities": {
      "fs": {
        "readTextFile": true,
        "writeTextFile": false
      },
      "terminal": true
    },
    "clientInfo": {
      "name": "review-workbench",
      "title": "代码审查工作台",
      "version": "2.4.0"
    }
  }
}

没有声明的能力等于不支持。客户端声明可读文件但不可写,不代表授予了模糊的「文件系统权限」,智能体不得调用 fs/write_text_file。新增可选能力不需要提升主协议版本,因此必须针对不同能力组合建立兼容性测试。

如果智能体选择了客户端无法支持的版本,客户端应关闭连接并清楚说明不兼容原因。继续执行可能会用错误语义解析一条格式合法的消息。

会话建立绑定工作上下文

session/new 创建一段独立对话并返回 sessionId。其中 cwd 必须是绝对路径,且始终作为相对路径解析的主要基准。当智能体声明 additionalDirectories 能力时,客户端还可以提供额外的绝对工作区根目录。

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "session/new",
  "params": {
    "cwd": "/work/inventory-service",
    "additionalDirectories": [
      "/work/shared-contracts"
    ],
    "mcpServers": []
  }
}

有效根目录集合应被视为文件访问的最大边界,而不只是导航信息。实现应规范化路径,拒绝目录穿越和符号链接逃逸,并在直接文件方法、Shell 工作目录、搜索工具以及智能体侧文件实现中使用同一边界。

会话恢复方法有不同语义:

方法 所需能力 历史记录行为
session/new 基线能力 建立新上下文
session/load loadSession 返回前通过更新完整回放对话
session/resume sessionCapabilities.resume 恢复上下文但不回放历史消息
session/close sessionCapabilities.close 取消当前工作并释放会话资源

会话 ID 只是路由句柄,不是身份或所有权证明。应用应在可信状态中,把它绑定到经过认证的用户、工作区、智能体构建版本、策略和保留规则。

提示响应负责结束一轮交互

session/prompt 携带内容块数组。文本和资源链接是基础输入;图片、音频和嵌入资源则要求智能体提前声明对应的提示能力。

智能体处理任务时,通过 session/update 通知发送消息片段、计划、工具调用、工具状态、文件位置、用量等已协商事件。原始提示请求保持未完成,直到智能体返回 stopReason

json
{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_4d53",
    "update": {
      "sessionUpdate": "tool_call",
      "toolCallId": "call_tests_01",
      "title": "运行针对性单元测试",
      "kind": "execute",
      "status": "pending"
    }
  }
}

客户端应按会话和工具调用标识关联更新,接受局部字段更新,并在规范允许的范围内容忍未知可选字段,不能因为扩展字段导致整轮交互失败。客户端也不能根据最后一段流式文本推断任务成功;提示响应和最终工具状态才是结构化的结束证据。

为什么 ACP 是双向协议?

ACP 是双向协议,因为客户端控制着智能体需要但不应直接拥有的资源。编辑器可以提供未保存缓冲区、原生终端、权限界面或结构化用户输入,同时保留对这些能力的控制。

主要的智能体到客户端接口包括:

接口 用途 必须实施的控制
fs/read_text_file 读取文本,包括未保存的编辑器状态 规范化路径和授权根目录
fs/write_text_file 创建或替换文本内容 写入策略、冲突处理、审计
terminal/create 使用参数、环境、目录和输出限制启动命令 可执行文件策略、沙箱、凭证
terminal/output 获取有界输出和退出状态 字节限制、编码、脱敏
session/request_permission 请求用户决定是否执行工具调用 真实预览和参数绑定
elicitation/create 收集结构化或 URL 交互产生的用户输入 能力、来源、Schema、隐私

这种反向调用非常适合编辑器集成。客户端可以返回当前缓冲区而不是磁盘上的旧内容,可以展示真实代码差异,也能让终端生命周期保持可见。但它同时形成高风险信任边界:被入侵或恶意的智能体可能要求客户端读取秘密或执行危险命令。

能力协商只回答「这个方法是否可用」,不回答「这次调用是否允许」。客户端仍须依据当前策略逐次检查路径、命令、环境变量、数据目的地和具体操作。

权限与工具更新如何配合?

ACP 将工具调用的可见生命周期与可选用户授权分开。智能体通过 session/update 报告工具调用,可以调用 session/request_permission 请求用户选择,然后继续报告 pendingin_progresscompletedfailed 等状态。

权限选项包括单次或长期允许、单次或长期拒绝。它们是界面展示提示,不是完整的安全策略语言。持久化的「始终允许」规则必须严格绑定经过认证的用户、工作区、智能体身份、工具身份、规范化参数或参数类别、策略版本和过期时间。

高影响操作的权限界面至少应展示:

  • 实际执行的工具或命令;
  • 具体目标文件、服务或业务记录;
  • 工作目录和关键参数;
  • 数据目的地与预期副作用;
  • 决定只适用一次还是持续生效。

下游操作仍然需要独立授权。用户批准修改 invoice-42,不能证明该用户属于这张发票所在租户。服务端必须从可信认证上下文获得身份,执行对象级授权,并拒绝模型参数中自报的用户或租户身份。

ACP 工具状态也不提供事务语义。命令或 API 写入可能已经提交,但智能体进程随后异常退出,客户端此时只能确认结果未知。生产系统需要稳定操作键、副作用日志和下游对账,再决定是否重试。这与工具使用的生产边界一致。

ACP 与 MCP、A2A、LSP 有什么区别?

ACP、MCP、A2A 与 LSP 标准化的是不同关系。只按缩写比较它们,会导致错误架构和被夸大的安全保证。

协议 主要关系 核心单元 无法替代
ACP 编辑器或界面客户端到编码智能体 会话与提示轮次 后端授权、智能体运行时
MCP AI Host 或 Client 到能力 Server 工具、资源、提示模板 面向用户的编码会话
A2A 智能体客户端到独立运行的智能体服务 任务、消息、制品 本地 IDE 集成
LSP 编辑器到语言服务器 文档与语言功能 生成式智能体工作流

ACP 对 MCP 友好,但不会替代 MCP。创建会话时,客户端可以向智能体提供 MCP 服务器配置,从而组合两层边界:

text
开发者 <-> IDE / ACP 客户端 <-> 编码智能体 <-> MCP 服务器 <-> 数据或操作

每一跳都需要独立身份、授权、输入校验、输出限制和审计。客户端的 ACP 批准结果不能作为通用凭证直接转发给 MCP 服务器。

A2A 协议面向远程智能体之间的协作和持久任务交换。编码智能体可以在运行时内部使用 A2A,但 IDE 仍需要 ACP 的本地会话呈现语义。MCP、A2A 与 A2UI 边界指南进一步解释了为什么只有在确实存在独立所有权边界时才应增加这些层。

LSP 是解释生态互操作目标时最接近的类比,但两者工作负载不同。语言服务器响应补全、悬停、诊断、符号查找等有界语言功能;编码智能体执行开放式多步骤任务,可能调用模型、请求权限、修改文件、运行命令并流式报告计划。因此,ACP 需要比「智能体版 LSP」这一口号更完整的会话、工具、权限和取消语义。

生产环境会出现哪些故障?

生产 ACP 集成会在进程、协议、策略和副作用边界失败,只跑通聊天演示并不能覆盖真实契约。

标准输出被污染

本地子进程传输必须分离协议帧和日志。诊断信息一旦写入协议流,合法 JSON-RPC 交换就可能变成无法恢复的解析错误。应通过专用诊断通道收集日志,限制消息行与总大小,并在连接关闭时终止整个进程树。

能力组合发生漂移

智能体更新可以在不改变 v1 主版本的情况下新增可选字段或改变能力组合。应固定智能体和 SDK 版本,记录实际协商结果,在允许的位置忽略未知可选数据,并对所有受支持组合运行兼容性用例。

不要根据 SDK 包版本推断线协议兼容性。ACP 官方仓库已经明确,Schema 制品版本与 protocolVersion 分别演进。

路径逃逸工作区

绝对路径在语法上有效,但不一定获得授权。实现需要解析符号链接和规范化路径,与会话有效根目录集合比较,并在执行时再次验证,从而缩小时序检查与使用之间的竞态窗口。

终端执行泄密或失控

命令与参数应作为结构化值传入,不要拼接 Shell 字符串。限制环境变量、执行时间、子进程、网络访问、输出字节和日志保留范围。ACP 的 outputByteLimit 限制终端保留输出,但客户端仍需脱敏,并保证从合法字符边界截断。

取消与副作用发生竞态

session/cancel 要求智能体尽快停止,但无法撤销已经提交的写入。客户端应取消待处理权限请求并提前标记未完成工具调用;智能体应捕获中断异常,返回具有语义的 cancelled 停止原因。对于外部写入,应区分 prepareddispatchedcommittedfailedoutcome_unknown

不可信内容影响智能体

编辑器文件、MCP 结果、命令输出、工具描述和远程资源都可能携带提示注入。每个内容块都应保留来源,将数据与可信策略分离,并独立限制工具权限,绝不能允许一段更新或资源文本扩大权限。

过早假设远程传输已稳定

ACP 网站已经发布 Streamable HTTP 与 WebSocket 传输的 Active RFD,但该提案的现状章节也明确说明当前 ACP 只有 stdio。除非目标客户端与智能体明确记录并测试了相同传输 Profile,否则应把 RFD 当作提案,不能仅凭生态页面提到远程场景,就把它描述为稳定 v1 行为。

如何测试 ACP 实现?

ACP 测试必须同时评估协议一致性和真实编码轨迹。最终答案看起来正确,并不能证明集成过程中没有泄露秘密、忽略取消、越界写文件或重复执行外部副作用。

建议采用以下发布矩阵:

层级 必需证据
线协议 合法 JSON-RPC、ID 关联、通知处理、错误映射
协商 支持与不支持的版本、缺失能力、混合能力集合
会话 新建、加载回放、无回放恢复、关闭、非法所有权
提示 内容能力校验、有序消息块、停止原因、用量限制
权限 允许、拒绝、持久规则范围、等待期间取消
文件 未保存内容读取、目录穿越、符号链接逃逸、冲突、超大内容
终端 结构化参数、超时、终止、释放、截断、编码、秘密脱敏
可靠性 智能体崩溃、畸形帧、重连、重复更新、未知副作用
安全 恶意仓库文本、污染工具结果、凭证隔离、跨租户访问
评测 任务成功率、无用工具调用、差异质量、回滚、延迟和成本

运行记录至少应关联客户端构建、智能体构建、协商协议版本、能力、会话与轮次 ID、模型和策略版本、工具调用 ID、脱敏参数摘要、权限决定、文件根目录、终端退出状态、取消时序、副作用状态和最终结果。不要保存隐藏思维链或无边界的私有文件内容。

AI 编码规则架构解释了仓库指令如何进入上下文但不成为授权。需要进一步设计状态、预算、审批、幂等与恢复时,可参考智能体 Harness 工程指南

常见问题

Agent Client Protocol 是什么?

ACP 是连接交互式客户端与编码智能体的开放 JSON-RPC 2.0 协议,客户端通常是 IDE。它定义智能体会话的生命周期和呈现契约,但把模型行为、工具实现、存储和业务策略留给两端产品负责。

ACP 只是 AI 智能体版 LSP 吗?

这个类比能解释互操作目标,却不能覆盖完整设计。LSP 标准化有界的语言智能功能;ACP 承载开放式会话、流式模型输出、计划、工具、权限、代码差异、终端、用量和取消,因此执行与安全范围更大。

ACP 会替代 MCP 吗?

不会。ACP 连接编辑器体验与编码智能体,MCP 连接 AI 应用或智能体与工具、资源和提示模板。ACP 可以告诉智能体连接哪些 MCP 服务器,但每条 MCP 请求仍需要自己的认证、授权、校验和结果控制。相关边界可参考 MCP 协议生产指南

ACP 能通过 HTTP 运行远程智能体吗?

远程传输工作已经存在,但必须根据目标实现核验。已发布的 Streamable HTTP 与 WebSocket 设计标记为 Active RFD,稳定 v1 文档则主要描述核心协议和本地子进程模型。部署前应固定具体传输提案或实现版本。

最低限度的安全 ACP 实现包括什么?

最低限度的安全实现需要协商能力,把会话绑定到授权工作区根目录,校验所有 JSON-RPC 输入,限制子进程与凭证,展示绑定真实参数的权限请求,限制输出,传播取消,记录副作用状态,并测试拒绝与故障路径。仅仅通过协议一致性测试还不够。

总结

ACP 为编辑器与编码智能体提供共同的双向会话契约。它最重要的价值不是增加一种模型 API,而是在保留原生文件、终端、代码差异、权限和进度体验的同时,将面向用户的客户端与可替换的智能体运行时分离。

实现时应严格尊重这层边界:逐项协商可选能力,缩小工作区和进程访问范围,把权限理解为用户意图而非后端授权,并围绕可能已经发生的副作用设计取消。只有相邻边界确实存在时,才把 ACP 与 MCP 或 A2A 组合起来。

相关资源