不同客户端接入不同 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,就需要单独适配。
问题:
- 通信格式不统一。
- 工具调用事件不统一。
- 会话管理方式不统一。
- 权限确认机制不统一。
- 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" }}字段说明:
| 字段 | 含义 |
|---|---|
| jsonrpc | JSON-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 |
| 发送 Prompt | Request / Response |
| 推送文本 | Notification |
| 推送工具状态 | Notification |
| 请求权限 | Request / Response |
核心区别:
- Request:需要得到处理结果。
- Notification:只需要通知对方发生了某件事情。
4. 初始化机制:initialize
Client 和 Agent 在正式通信之前,需要进行初始化和能力协商。
主要解决两个问题:
- 双方使用什么协议版本?
- 双方分别支持什么能力?
初始化过程:
Client | | initialize | protocolVersion | clientInfo | clientCapabilities | vAgent | | 返回协议版本 | 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_chunk | Agent 文本输出 |
agent_thought_chunk | Agent 思考内容(受支持范围限制) |
tool_call | 工具调用开始 |
tool_call_update | 工具调用状态更新 |
plan | 任务计划更新 |
current_mode_update | 当前模式变化 |
Client 不必通过解析自然语言猜测 Agent 正在做什么,而是直接消费结构化事件。
6.4 工具调用状态
典型状态:
pending | vin_progress | +------> completed | +------> failedClient 可以根据状态展示:
- 正在执行的工具
- 工具名称
- 执行进度
- 执行结果
- 错误信息
6.5 Prompt 结束原因
v1 中常见的停止原因:
| stopReason | 含义 |
|---|---|
end_turn | 正常完成 |
max_tokens | 达到 Token 限制 |
max_turn_requests | 达到请求轮次限制 |
refusal | 拒绝执行 |
cancelled | 已取消 |
7. Permission:权限控制
ACP 定义了 Agent 向 Client 请求权限的机制。
主要方法:
session/request_permission例如 Agent 想执行:
rm -rf ./build可以向 Client 请求授权。
Client 展示权限确认界面:
Agent 请求操作权限
操作:rm -rf ./build
[允许一次] [拒绝一次]用户选择后,Client 将授权结果返回给 Agent。
7.1 权限机制的意义
- 统一不同 Agent 的权限交互方式。
- Client 可以集中处理用户授权。
- Agent 不必为每种客户端单独开发权限 UI。
- 可以在 UI 中统一记录操作请求。
WARNINGACP 不是安全沙箱。它定义的是权限请求和响应机制,并不能单独保证 Agent 无法执行危险操作。
真正的安全控制仍需要:
- 操作系统权限
- 容器隔离
- 沙箱
- 路径访问限制
- 命令执行策略
8. Filesystem:文件系统能力
Client 可以向 Agent 提供文件系统访问能力。
主要方法:
fs/read_text_filefs/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 提供文件读取或写入能力。
NOTEAgent 也可以使用自己的文件系统工具,并不是所有文件操作都必须经过 Client。
9. Terminal:终端能力
Client 还可以向 Agent 提供终端能力。
主要方法:
| 方法 | 作用 |
|---|---|
terminal/create | 创建终端 |
terminal/output | 获取终端输出 |
terminal/wait_for_exit | 等待命令结束 |
terminal/kill | 终止命令 |
terminal/release | 释放终端资源 |
例如 Agent 想执行:
npm test执行过程:
Agent | | terminal/create vClient | | 创建终端 | 返回 terminalId vAgent | | 获取输出 / 等待结束 vClient 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 | | 启动子进程 vAgent Process | +── stdin 接收 ACP 消息 | +── stdout 发送 ACP 消息 | +── stderr 普通日志例如:
my-agent --acpWARNINGstdout 只能输出协议消息,普通日志应该写入 stderr。否则 Client 可能无法正常解析消息。
11.2 WebSocket / SSE
对于 WebUI,可以设计:
Browser | | WebSocket vBackend | | ACP / stdio vAgent反方向:
Browser | | 用户输入 vBackend | | session/prompt vAgent这里 WebSocket 是自定义的 Web 传输适配层,并不是 ACP v1 默认定义的标准传输方式。
12. ACP、MCP、A2A 的区别
三者解决的问题不同。
| 协议 | 主要解决的问题 | 通信双方 |
|---|---|---|
| ACP | 客户端如何接入 Agent | Client ↔ Agent |
| MCP | 模型应用如何使用外部工具和资源 | Host ↔ MCP Server |
| A2A | 不同 Agent 如何协作 | Agent ↔ Agent |
ACP
Zed | | ACP vClaude Code负责客户端与 Agent 的交互。
MCP
DSH | | MCP vFilesystem Server负责 Agent 访问外部工具和资源。
A2A
Research Agent | | A2A vCoding Agent | | A2A vReview Agent负责 Agent 之间的任务协作。
三者可以同时存在,不是互相替代的关系。
13. 扩展机制
ACP 提供了一定的扩展能力:
_meta:额外元数据。- 自定义方法:可使用
_前缀。 - 自定义能力:通过初始化阶段声明。
例如:
my-agent/get_metrics可以作为自定义扩展方法。
但应优先使用协议已有的标准能力,避免所有业务功能都依赖私有扩展。
14. ACP v1 与 v2
官方存在 v1 稳定协议和 v2 Draft 草案。
两者不能直接混用。
研究和开发时必须明确协议版本。
| 方面 | v1 | v2 |
|---|---|---|
| 状态 | 稳定版 | 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 └── TerminalACP 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 这种设计的价值
- 前端不再绑定某个 Agent 内核。
- 不同 Agent 使用统一的通信接口。
- Session 管理可以统一。
- 工具调用事件可以统一渲染。
- 权限交互可以统一处理。
- 可以同时支持 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 交互。
建议重点研究三个部分:
session/prompt:理解 Agent 的任务执行生命周期。session/update:理解如何构建统一的 Agent 事件系统。fs/*、terminal/*、session/request_permission:理解 Client 如何向 Agent 提供环境和交互能力。
18. 官方资料
- ACP 官方文档:https://agentclientprotocol.com/
- ACP GitHub:https://github.com/agentclientprotocol/agent-client-protocol
- TypeScript SDK:https://github.com/agentclientprotocol/typescript-sdk
- Python SDK:https://github.com/agentclientprotocol/python-sdk
- v1 Overview:https://agentclientprotocol.com/protocol/v1/overview
- v2 Draft Overview:https://agentclientprotocol.com/protocol/v2/overview