3614 字
18 分钟
Agent Client Protocol(ACP):统一 Client 与 Agent 的通信协议

不同客户端接入不同 AI Agent,每多一个 Agent 就要多写一套适配器。ACP(Agent Client Protocol)由 Zed 团队发起,把 Client 与 Agent 之间的通信标准化,让 IDE、TUI、WebUI 与不同 Agent Runtime 解耦。

1. ACP 是什么?#

ACP 全称 Agent Client Protocol,主要解决的问题是:

不同客户端如何以统一的方式接入不同 AI Agent,而不需要针对每个 Agent 单独开发一套通信适配器。

例如:

  • Zed 接入 Claude Code。
  • JetBrains 接入不同 Coding Agent。
  • 自定义 WebUI 接入 DSH。
  • TUI 接入支持 ACP 的 Agent。

核心思想:

统一 Client 与 Agent 的通信协议,让客户端不必了解 Agent 内部的具体实现。

1.1 没有 ACP 的情况#

每个 Agent 都有自己的通信格式、会话管理、工具事件和权限交互方式。

Client
├── Claude Adapter
├── Gemini Adapter
└── DSH Adapter

每接入一个 Agent,就需要单独适配。

问题:

  1. 通信格式不统一。
  2. 工具调用事件不统一。
  3. 会话管理方式不统一。
  4. 权限确认机制不统一。
  5. Agent 更新可能导致适配器需要修改。

1.2 使用 ACP 的情况#

Client
|
| ACP / JSON-RPC 2.0
|
+── Claude Code
+── Gemini CLI
+── DSH
+── Other Agents

只要 Agent 实现 ACP,Client 就可以使用统一的协议与其通信。

NOTE

协议统一不意味着 Agent 能力完全相同,具体能力仍然由 Agent 实现决定。

2. 核心架构#

ACP 将系统划分为两个主要角色:

2.1 Client#

Client 是用户直接使用的应用程序。

例如:

  • Zed
  • JetBrains
  • TUI
  • WebUI

主要职责:

模块职责
UI消息展示、输入框、工具调用展示
Session创建、切换和恢复会话
Interaction接收用户输入、展示 Agent 输出
Permission处理 Agent 的权限请求
Filesystem向 Agent 提供文件系统能力
Terminal向 Agent 提供终端能力

Client 不只是负责展示内容,还可以向 Agent 提供执行环境能力。

2.2 Agent#

Agent 是真正执行任务的程序。

例如:

  • Claude Code
  • Gemini CLI
  • 自定义 DeepSeek Harness
  • 其他 Coding Agent

主要职责:

模块职责
LLM模型调用
Harness管理模型调用和执行循环
Tools工具调度与执行
Context上下文管理
Planning任务规划
Execution实际任务执行

ACP 不规定 Agent 必须使用什么模型、语言或 Harness 架构。

可以使用 Go、Python、TypeScript 实现,也可以给现有 CLI 增加 ACP 适配层。

2.3 整体架构#

┌─────────────────────────────┐
│ Client │
│ │
│ WebUI / IDE / TUI │
│ UI / Session / Permission │
│ Filesystem / Terminal │
└──────────────┬──────────────┘
│
│ ACP
│ JSON-RPC 2.0
│
┌──────────────▼──────────────┐
│ Agent │
│ │
│ Harness │
│ LLM Provider │
│ Context Manager │
│ Tool Executor │
│ Execution Loop │
└─────────────────────────────┘

3. 底层通信机制#

ACP 使用 JSON-RPC 2.0 作为消息协议。

JSON-RPC 主要有两种消息形式。

3.1 Request / Response#

请求需要对方返回结果。

例如创建 Session:

请求:

{
"jsonrpc": "2.0",
"id": 1,
"method": "session/new",
"params": {
"cwd": "/home/user/project"
}
}

响应:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"sessionId": "sess_123"
}
}

字段说明:

字段含义
jsonrpcJSON-RPC 版本
id请求 ID
method调用的方法
params请求参数
result成功结果
error错误信息

3.2 Notification#

通知不需要响应。

例如 Agent 向 Client 推送消息:

{
"jsonrpc": "2.0",
"method": "session/update",
"params": {
"sessionId": "sess_123",
"update": {
"sessionUpdate": "agent_message_chunk",
"content": {
"type": "text",
"text": "正在检查项目结构"
}
}
}
}

Notification 没有 id。

3.3 两种消息的区别#

场景消息类型
初始化Request / Response
创建会话Request / Response
发送 PromptRequest / Response
推送文本Notification
推送工具状态Notification
请求权限Request / Response

核心区别:

  • Request:需要得到处理结果。
  • Notification:只需要通知对方发生了某件事情。

4. 初始化机制:initialize#

Client 和 Agent 在正式通信之前,需要进行初始化和能力协商。

主要解决两个问题:

  1. 双方使用什么协议版本?
  2. 双方分别支持什么能力?

初始化过程:

Client
|
| initialize
| protocolVersion
| clientInfo
| clientCapabilities
|
v
Agent
|
| 返回协议版本
| agentInfo
| agentCapabilities
|
v
初始化完成

例如 Client 可以声明:

{
"protocolVersion": 1,
"clientInfo": {
"name": "my-webui",
"version": "0.1.0"
},
"clientCapabilities": {
"fs": {
"readTextFile": true,
"writeTextFile": true
},
"terminal": true
}
}

表示 Client 支持文件读取、文件写入和终端能力。

Agent 也会声明自己的能力。

能力协商的意义:

不是要求所有 Client 和 Agent 实现全部功能,而是根据双方支持的能力决定可以进行哪些交互。

5. Session:会话管理#

Session 是 ACP 的核心概念。

一个 Session 代表 Client 与 Agent 之间的一段独立会话。

Agent
├── Session A
│ ├── 用户消息
│ ├── Agent 回复
│ └── 工具调用
│
├── Session B
│ ├── 用户消息
│ └── Agent 回复
│
└── Session C
├── 用户消息
└── Agent 回复

5.1 主要方法#

方法作用
session/new创建会话
session/list查询会话
session/resume恢复会话
session/close关闭会话
session/delete删除会话
session/prompt发送用户消息
session/cancel取消正在执行的任务

具体可用方法应以选定的协议版本为准。

5.2 cwd#

创建 Session 时可以指定工作目录:

{
"cwd": "/home/user/project"
}

cwd 表示 Agent 执行任务时使用的工作目录。

例如:

/home/user/project

可以让 Agent 以这个项目作为主要工作上下文。

WARNING

工作目录配置不等于操作系统级安全沙箱,实际访问限制还需要运行环境实现。

5.3 close 与 delete 的区别#

  • session/close:关闭活动会话,释放相关运行资源。
  • session/delete:删除会话数据。

两者不是同一操作。

6. Prompt Lifecycle:任务执行生命周期#

这是 ACP 最重要的部分。

一次 Prompt Turn 代表用户提交任务到 Agent 完成这一轮任务的过程。

一次任务可能包含多次模型调用、工具调用和权限请求。

6.1 发送 Prompt#

Client 调用:

session/prompt

示例:

{
"jsonrpc": "2.0",
"id": 2,
"method": "session/prompt",
"params": {
"sessionId": "sess_123",
"prompt": [
{
"type": "text",
"text": "检查项目中的代码错误"
}
]
}
}

6.2 Agent 内部执行#

接收用户输入
|
v
构建上下文
|
v
调用 LLM
|
v
解析模型输出
|
+------> 普通文本
|
+------> 工具调用
|
+------> 请求权限
|
v
继续执行
|
v
返回结果

这里的模型调用、上下文管理和工具执行循环都属于 Agent 内部实现,不由 ACP 规定。

6.3 session/update#

Agent 通过 session/update 向 Client 推送执行过程中的事件。

常见事件包括:

事件作用
agent_message_chunkAgent 文本输出
agent_thought_chunkAgent 思考内容(受支持范围限制)
tool_call工具调用开始
tool_call_update工具调用状态更新
plan任务计划更新
current_mode_update当前模式变化

Client 不必通过解析自然语言猜测 Agent 正在做什么,而是直接消费结构化事件。

6.4 工具调用状态#

典型状态:

pending
|
v
in_progress
|
+------> completed
|
+------> failed

Client 可以根据状态展示:

  • 正在执行的工具
  • 工具名称
  • 执行进度
  • 执行结果
  • 错误信息

6.5 Prompt 结束原因#

v1 中常见的停止原因:

stopReason含义
end_turn正常完成
max_tokens达到 Token 限制
max_turn_requests达到请求轮次限制
refusal拒绝执行
cancelled已取消

7. Permission:权限控制#

ACP 定义了 Agent 向 Client 请求权限的机制。

主要方法:

session/request_permission

例如 Agent 想执行:

Terminal window
rm -rf ./build

可以向 Client 请求授权。

Client 展示权限确认界面:

Agent 请求操作权限
操作:
rm -rf ./build
[允许一次] [拒绝一次]

用户选择后,Client 将授权结果返回给 Agent。

7.1 权限机制的意义#

  1. 统一不同 Agent 的权限交互方式。
  2. Client 可以集中处理用户授权。
  3. Agent 不必为每种客户端单独开发权限 UI。
  4. 可以在 UI 中统一记录操作请求。
WARNING

ACP 不是安全沙箱。它定义的是权限请求和响应机制,并不能单独保证 Agent 无法执行危险操作。

真正的安全控制仍需要:

  • 操作系统权限
  • 容器隔离
  • 沙箱
  • 路径访问限制
  • 命令执行策略

8. Filesystem:文件系统能力#

Client 可以向 Agent 提供文件系统访问能力。

主要方法:

fs/read_text_file
fs/write_text_file

例如读取文件:

{
"jsonrpc": "2.0",
"id": 20,
"method": "fs/read_text_file",
"params": {
"sessionId": "sess_123",
"path": "/home/user/project/main.go"
}
}

返回:

{
"jsonrpc": "2.0",
"id": 20,
"result": {
"content": "package main\n\nfunc main() {}\n"
}
}

为什么需要 Client 提供文件访问?#

因为 Client 和 Agent 可能运行在不同的环境中。

例如:

用户电脑
|
+── IDE Client
|
+── 项目文件

Agent 可能运行在远程服务器或容器里,无法直接访问用户电脑上的文件。

通过 ACP,Agent 可以请求 Client 提供文件读取或写入能力。

NOTE

Agent 也可以使用自己的文件系统工具,并不是所有文件操作都必须经过 Client。

9. Terminal:终端能力#

Client 还可以向 Agent 提供终端能力。

主要方法:

方法作用
terminal/create创建终端
terminal/output获取终端输出
terminal/wait_for_exit等待命令结束
terminal/kill终止命令
terminal/release释放终端资源

例如 Agent 想执行:

Terminal window
npm test

执行过程:

Agent
|
| terminal/create
v
Client
|
| 创建终端
| 返回 terminalId
v
Agent
|
| 获取输出 / 等待结束
v
Client Terminal

这样 Agent 就可以使用 Client 所在环境提供的终端,而不必自己实现终端 UI。

10. Content:结构化内容#

ACP 不只是传输纯文本,还使用结构化 Content Block。

常见类型:

类型用途
text普通文本
image图片
audio音频
resource嵌入资源
resource_link资源链接

Client 可以根据内容类型决定如何渲染:

  • 文本:Markdown 渲染器。
  • 图片:图片组件。
  • 资源链接:资源预览组件。
  • 工具调用:工具状态组件。

这样比单纯传递一段字符串更适合完整的 Agent UI。

11. Transport:传输方式#

需要区分:

  • JSON-RPC:规定消息格式。
  • Transport:规定消息如何传输。

11.1 stdio#

ACP v1 的标准传输方式是 stdio。

Client
|
| 启动子进程
v
Agent Process
|
+── stdin 接收 ACP 消息
|
+── stdout 发送 ACP 消息
|
+── stderr 普通日志

例如:

Terminal window
my-agent --acp
WARNING

stdout 只能输出协议消息,普通日志应该写入 stderr。否则 Client 可能无法正常解析消息。

11.2 WebSocket / SSE#

对于 WebUI,可以设计:

Browser
|
| WebSocket
v
Backend
|
| ACP / stdio
v
Agent

反方向:

Browser
|
| 用户输入
v
Backend
|
| session/prompt
v
Agent

这里 WebSocket 是自定义的 Web 传输适配层,并不是 ACP v1 默认定义的标准传输方式。

12. ACP、MCP、A2A 的区别#

三者解决的问题不同。

协议主要解决的问题通信双方
ACP客户端如何接入 AgentClient ↔ Agent
MCP模型应用如何使用外部工具和资源Host ↔ MCP Server
A2A不同 Agent 如何协作Agent ↔ Agent

ACP#

Zed
|
| ACP
v
Claude Code

负责客户端与 Agent 的交互。

MCP#

DSH
|
| MCP
v
Filesystem Server

负责 Agent 访问外部工具和资源。

A2A#

Research Agent
|
| A2A
v
Coding Agent
|
| A2A
v
Review Agent

负责 Agent 之间的任务协作。

三者可以同时存在,不是互相替代的关系。

13. 扩展机制#

ACP 提供了一定的扩展能力:

  1. _meta:额外元数据。
  2. 自定义方法:可使用 _ 前缀。
  3. 自定义能力:通过初始化阶段声明。

例如:

my-agent/get_metrics

可以作为自定义扩展方法。

但应优先使用协议已有的标准能力,避免所有业务功能都依赖私有扩展。

14. ACP v1 与 v2#

官方存在 v1 稳定协议和 v2 Draft 草案。

两者不能直接混用。

研究和开发时必须明确协议版本。

方面v1v2
状态稳定版Draft
认证旧版认证设计新认证方法
会话恢复旧版会话加载设计session/resume
配置Session Modes 等Config Options
执行状态Prompt Stop Reason更强调状态更新和任务状态

建议:

  • 学习:先理解 v1 的完整生命周期。
  • 开发:根据实际 SDK 和目标客户端选择版本。
  • 不要混合使用不同版本的请求和响应 Schema。

15. 如何自己实现 ACP?#

假设要开发一个自定义 Agent。

15.1 Agent 端#

My Agent
│
├── ACP Server
│ ├── initialize
│ ├── session/new
│ ├── session/prompt
│ ├── session/cancel
│ └── session/update
│
├── Harness
│ ├── Context Manager
│ ├── LLM Provider
│ ├── Tool Executor
│ └── Execution Loop
│
└── Runtime
├── File System
└── Terminal

ACP Server 负责协议通信。

Harness 负责真正执行任务。

两者应该保持模块分离。

15.2 Client 端#

My Client
│
├── ACP Client
│ ├── Process Manager
│ ├── JSON-RPC Transport
│ ├── Request Dispatcher
│ └── Event Handler
│
├── Session Manager
├── Permission Manager
├── File System Provider
├── Terminal Provider
│
└── UI
├── Chat
├── Tool Calls
├── Plan
├── Terminal
└── Permission Dialog

推荐的技术分工:

  • Go:Backend、进程管理、会话管理。
  • React / TypeScript:WebUI。
  • ACP SDK:协议通信。
  • WebSocket:浏览器与 Backend 的实时通信。

16. 对个人 Agent / WebUI 架构的参考#

如果希望一个 WebUI 同时接入 DSH、Codex、Claude Code 等 Agent,可以考虑以下架构。

┌─────────────────────────────┐
│ Frontend │
│ │
│ WebUI / TUI │
└──────────────┬──────────────┘
│
│ 内部事件接口
│
┌──────────────▼──────────────┐
│ Backend │
│ │
│ Session Manager │
│ Agent Process Manager │
│ ACP Client │
│ Event Dispatcher │
│ Permission Manager │
└──────────────┬──────────────┘
│
│ ACP
│
┌───────┼────────┐
│ │ │
DSH Codex Claude

不支持 ACP 的 Agent,可以通过 ACP Adapter 进行适配。

16.1 这种设计的价值#

  1. 前端不再绑定某个 Agent 内核。
  2. 不同 Agent 使用统一的通信接口。
  3. Session 管理可以统一。
  4. 工具调用事件可以统一渲染。
  5. 权限交互可以统一处理。
  6. 可以同时支持 TUI 和 WebUI。

16.2 ACP 不负责什么?#

ACP 不是完整的 Agent 平台。

它不负责:

  • LLM 模型供应商管理。
  • Agent 内部 Harness。
  • 多 Agent 编排。
  • 长期记忆。
  • 分布式任务调度。
  • 运行时安全隔离。
  • Agent 自我优化。

这些仍然需要由 Agent Runtime 或平台 Backend 实现。

17. 总结#

ACP 最重要的价值不是 JSON-RPC,而是它定义了一个相对完整的 Agent Client 通信边界。

核心能力可以归纳为:

核心能力解决的问题
Initialize协议版本与能力协商
Session会话创建、恢复与管理
Prompt用户任务提交
Session Update实时事件推送
Permission用户授权交互
Filesystem文件访问能力
Terminal终端执行能力
Content Block结构化内容传输

一句话总结:ACP 让 Client 不必关心 Agent 内部如何思考和执行,只需要通过统一协议与 Agent 交互。

建议重点研究三个部分:

  1. session/prompt:理解 Agent 的任务执行生命周期。
  2. session/update:理解如何构建统一的 Agent 事件系统。
  3. fs/*、terminal/*、session/request_permission:理解 Client 如何向 Agent 提供环境和交互能力。

18. 官方资料#

Agent Client Protocol(ACP):统一 Client 与 Agent 的通信协议
https://blog.xqcherry.top/posts/ai/agent-client-protocol/
作者
xqcherry
发布于
2026-11-05
许可协议
CC BY-NC-SA 4.0