ACP(Agent Client Protocol)完整核心总结

一、一句话核心定义

ACP = AI 代理版的 LSP(语言服务器协议),是由 Zed Industries 主导的开放标准,基于 JSON-RPC 2.0 + stdio 标准输入输出,统一了IDE/客户端 ↔ AI 编码代理之间的通信规范,解决了 AI 工具生态的 N×M 碎片化问题。

它与语言完全无关,只定义消息格式和交互流程,任何能读写 stdio、解析 JSON 的语言都能实现。

二、核心工作原理

1. 架构与角色

只有两个核心角色,通信模型为客户端主动发起,代理响应+流式推送

  • Client(客户端):VS Code、Zed、Cursor、OpenClaw 网关、自定义 CLI 工具
  • Agent(服务端):Claude Code、Gemini CLI、OpenCode、任意兼容 ACP 的 AI 代理

2. 传输层:为什么用 stdio?

  • 父子进程通过 stdin/stdout 通信,stderr 仅用于日志和错误输出
  • 核心优势:无端口/防火墙/CORS 问题、本地 IPC 延迟极低(比 HTTP 快 10-100 倍)、进程生命周期自动绑定(客户端退出,代理自动销毁,无僵尸进程)

3. 三种标准消息类型

类型 格式特征 用途
Request(请求) 必须带唯一 id 客户端发起操作,代理必须返回对应响应
Response(响应) 带与请求相同的 id 代理对请求的结果回复
Notification(通知) id 单向推送,无需回复(流式输出、进度更新核心)

4. 完整标准工作流程

  1. 初始化握手:客户端启动代理子进程,发送 agent/initialize 协商双方支持的能力
  2. 创建会话:客户端调用 agent/createSession 分配独立上下文,隔离不同对话
  3. 发送消息:客户端将用户输入+当前文件/工程上下文打包为 agent/sendMessage 发送
  4. 流式输出:代理通过多条 agent/stream 通知逐字返回内容,实现打字效果
  5. 权限请求:代理需读写文件/执行命令时,先发送 agent/requestPermission 申请授权
  6. 资源操作:获得授权后,代理调用 agent/readFile/agent/executeCommand 等方法操作资源
  7. 结果返回:操作结果通过响应或流式通知返回给客户端
  8. 会话结束:调用 agent/destroySession 释放资源,或客户端直接终止代理进程

三、ACP 官方标准方法全集(按功能分类)

1. 初始化与生命周期

方法名 用途 核心参数
agent/initialize 初始化握手,协商双方能力 客户端名称、版本、支持的特性集
agent/shutdown 优雅关闭代理进程

2. 会话管理

方法名 用途 核心参数
agent/createSession 创建新会话,分配独立上下文 会话名称、初始上下文
agent/destroySession 销毁指定会话,释放资源 会话 ID
agent/listSessions 列出所有活跃会话
agent/getSession 获取指定会话的详细信息 会话 ID

3. 消息与交互

方法名 类型 用途 核心参数
agent/sendMessage Request 发送用户消息给代理 会话 ID、消息内容、上下文
agent/stream Notification 流式输出内容片段 内容文本、类型(文本/代码/思考)
agent/streamEnd Notification 流式输出结束标记
agent/cancelRequest Notification 取消正在进行的生成请求 请求 ID

4. 权限与安全

方法名 类型 用途 核心参数
agent/requestPermission Request 请求操作权限 权限类型(文件读/写/终端/网络)、目标路径、申请理由
agent/permissionGranted Notification 客户端授予权限 权限 ID、有效期
agent/permissionDenied Notification 客户端拒绝权限 权限 ID、拒绝理由

5. 文件系统访问

方法名 类型 用途 核心参数
agent/readFile Request 读取指定文件内容 文件路径、编码
agent/writeFile Request 写入内容到指定文件 文件路径、内容、是否覆盖
agent/listDirectory Request 列出目录内容 目录路径、是否递归
agent/statFile Request 获取文件/目录元信息 路径

6. 终端与命令执行

方法名 类型 用途 核心参数
agent/executeCommand Request 执行终端命令 命令、参数、工作目录
agent/commandOutput Notification 命令输出流式推送 输出内容、stdout/stderr 标识
agent/commandExit Notification 命令执行结束 退出码
agent/killCommand Request 终止正在运行的命令 命令 ID

7. 状态与错误

方法名 类型 用途 核心参数
agent/error Notification 代理发生错误 错误码、错误信息
agent/progress Notification 任务进度更新 进度百分比、描述

四、极简可跑 Python 实现(单文件无依赖)

1. ACP 代理(服务端)

保存为 acp_agent.py,实现初始化、消息处理和流式返回核心逻辑:

import sys
import json
import time

def send_acp_message(message):
    """标准ACP消息发送:写入stdout并立即刷新缓冲区"""
    json.dump(message, sys.stdout)
    sys.stdout.write('\n')
    sys.stdout.flush()

def main():
    while True:
        # 从stdin读取一行ACP消息
        line = sys.stdin.readline()
        if not line:
            break  # 客户端关闭,退出进程
        
        try:
            msg = json.loads(line.strip())
        except json.JSONDecodeError:
            continue

        # 1. 处理初始化握手
        if msg.get('method') == 'agent/initialize':
            send_acp_message({
                "jsonrpc": "2.0",
                "id": msg['id'],
                "result": {
                    "agentName": "DemoACPAgent",
                    "version": "0.1.0",
                    "capabilities": ["streaming", "basic_chat", "file_read"]
                }
            })
            continue

        # 2. 处理用户消息并流式返回
        if msg.get('method') == 'agent/sendMessage':
            # 先返回请求确认
            send_acp_message({
                "jsonrpc": "2.0",
                "id": msg['id'],
                "result": {"status": "processing"}
            })

            # 模拟大模型流式输出(逐字推送)
            response = f"ACP代理收到:{msg['params']['content']}"
            for char in response:
                send_acp_message({
                    "jsonrpc": "2.0",
                    "method": "agent/stream",
                    "params": {"content": char}
                })
                time.sleep(0.05)  # 模拟打字速度

            # 发送流结束标记
            send_acp_message({
                "jsonrpc": "2.0",
                "method": "agent/streamEnd"
            })
            continue

if __name__ == "__main__":
    main()

2. ACP 客户端(CLI 工具)

保存为 acp_client.py,实现代理启动、协议交互和用户界面:

import subprocess
import json
import sys

def main():
    # 启动ACP代理作为子进程
    agent = subprocess.Popen(
        [sys.executable, "acp_agent.py"],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        text=True,
        bufsize=1
    )

    def send_to_agent(msg):
        json.dump(msg, agent.stdin)
        agent.stdin.write('\n')
        agent.stdin.flush()

    # 步骤1:初始化握手
    print("=== ACP 连接初始化 ===")
    send_to_agent({
        "jsonrpc": "2.0",
        "id": 1,
        "method": "agent/initialize",
        "params": {"clientName": "DemoACPClient", "version": "0.1.0"}
    })

    # 读取初始化响应
    while True:
        resp = json.loads(agent.stdout.readline().strip())
        if resp.get('id') == 1:
            print(f"连接成功:{resp['result']['agentName']} v{resp['result']['version']}")
            print(f"代理支持能力:{resp['result']['capabilities']}\n")
            break

    # 步骤2:CLI用户交互(⚠️ 这部分完全是客户端自己实现,与ACP协议无关)
    print("=== ACP 演示客户端 ===")
    print("输入 'quit' 退出")
    while True:
        user_input = input("\n请输入消息:")
        if user_input.lower() == 'quit':
            break

        # 步骤3:构造ACP消息发送给代理
        send_to_agent({
            "jsonrpc": "2.0",
            "id": 2,
            "method": "agent/sendMessage",
            "params": {"content": user_input}
        })

        # 步骤4:读取流式响应并显示
        print("代理回复:", end='', flush=True)
        while True:
            msg = json.loads(agent.stdout.readline().strip())
            if msg.get('method') == 'agent/stream':
                print(msg['params']['content'], end='', flush=True)
            elif msg.get('method') == 'agent/streamEnd':
                print()
                break

    agent.terminate()
    print("\n连接已关闭")

if __name__ == "__main__":
    main()

3. 运行效果

python acp_client.py

输出:

=== ACP 连接初始化 ===
连接成功:DemoACPAgent v0.1.0
代理支持能力:['streaming', 'basic_chat', 'file_read']

=== ACP 演示客户端 ===
输入 'quit' 退出

请输入消息:你好ACP协议
代理回复:ACP代理收到:你好ACP协议

五、与其他AI代理协议的核心区别

协议 定位 解决的问题 典型链路
ACP 客户端 ↔ 代理通信 统一IDE与AI代理的交互标准 IDE → ACP → Claude Code
MCP 代理 ↔ 工具通信 统一AI代理访问外部资源的标准 Claude Code → MCP → GBrain/GStack
A2A 代理 ↔ 代理通信 多代理之间的协作与消息传递 OpenClaw → A2A → Hermes Agent

真实生产环境完整链路

IDE(ACP Client) → ACP → Claude Code → MCP → GBrain/文件系统/外部API

六、常见误区澄清

  1. ACP是OpenClaw的私有协议
    ✅ 事实:ACP是Zed Industries主导的开放标准,OpenClaw是最早深度支持并扩展该协议的框架之一

  2. ACP必须用TypeScript实现
    ✅ 事实:ACP与语言完全无关,Python/Go/Rust/Shell都能实现,核心只是读写stdio和解析JSON

  3. ACP代理必须是大模型
    ✅ 事实:ACP代理可以是任何程序。上面的示例没有调用任何大模型,只是简单回显用户输入

  4. CLI的用户菜单/权限弹窗是ACP定义的
    ✅ 事实:ACP协议不包含任何UI规范。所有用户交互(输入框、菜单、权限确认)都是客户端自己实现的

  5. ACP只能用于编码代理
    ✅ 事实:ACP最初为编码场景设计,但已被扩展到通用AI代理领域,支持任何类型的任务

  6. ACP用HTTP/WebSocket传输
    ✅ 事实:标准ACP只用stdio传输,没有网络依赖,更轻、更快、更安全

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐