引子

在软件工程的世界里,真正改变开发范式的,往往不是某一门语言,也不是某一个框架,而是那些“看不见”的协议。

当年,编辑器各自为政,语法提示、跳转定义、重构能力完全依赖 IDE 厂商自身实现。直到 Language Server Protocol 的出现,编辑器与语言服务被第一次标准化解耦。语言能力不再绑定于工具本身,而成为一种可以复用、共享、跨平台的能力服务。从此,VSCode、Vim、JetBrains 等工具可以共享同一套语言智能生态,开发体验发生了结构性变化。

多年之后,AI 进入工程现场。我们发现,大模型虽然强大,却像一个“孤岛”。它无法主动访问本地文件,不能安全地调用数据库,也无法直接操作浏览器。于是,Model Context Protocol 诞生了。它为模型定义了一种标准化的“工具调用与上下文扩展机制”,让模型能够安全地接入外部世界。模型开始从“对话引擎”转向“可执行体”。

但故事并未停止。随着 AI Coding Agent 的兴起,问题进一步升级:不仅是模型要调用工具,工具之间也需要协调,Agent 之间需要协作,编辑器需要与智能体建立长期会话与控制通道。于是,我们看到了 Agent Communication Protocol 的出现。ACP 试图解决的不再是“模型如何用工具”,而是“智能体如何成为开发环境中的一等公民”。

从 LSP 到 MCP,再到 ACP,我们看到的不是简单的协议更替,而是一条清晰的演进路径:
从语言能力的解耦 → 到模型能力的扩展 → 再到智能体能力的系统级嵌入。

这不仅是协议的演进史,更是软件开发范式正在发生的深层次变革。

LSP

每个开发者都有自己钟爱的集成开发环境(IDE),可能是 Visual Studio Code、JetBrains 系列中的某一款、Zed 或者其他任何一款 IDE。但你有没有想过,你的 IDE 是如何为你提供自动补全、跳转到定义以及悬停提示信息等功能的呢?而且这些功能还不只是针对一种编程语言,而是适用于如此多的编程语言。

如果你曾试图弄清楚这背后的工作原理,你很可能会遇到 “语言服务器协议(Language Server Protocol,简称 LSP)” 这个术语。

LSP之前IDE时代

在过去,编写代码完全是一种不同的体验。我们常常在文本编辑器中输入整个程序,然后手动编译,接着修正错误,再重新编译,有时这个过程会没完没了。这让人感到沮丧,但现在回顾起来,那些却是编程的黄金时代。

随着时间的推移,我们从简单的文本编辑器过渡到了真正意义上的代码编辑器,也就是我们现在所说的集成开发环境(IDEs)。在早期,大多数集成开发环境都是为了支持单一编程语言而构建的。但随着更多编程语言开始流行起来,编辑器也不得不随之发展。于是,它们开始像下面的图表中那样,通过扩展或插件来支持多种编程语言。

这些扩展充当了编辑器与语言工具之间的桥梁。语言工具能够理解你的代码,并提供特定于该语言的功能,比如自动补全、跳转到定义、悬停提示信息以及错误高亮显示。为了支持丰富的代码编辑功能,编辑器必须与每种语言工具紧密集成。

在这里插入图片描述

上图清楚地说明了两件事。

  • 其一,编辑器必须为每种语言构建定制化的集成方案。

  • 其二,语言工具的提供方必须为同一种语言开发不同的插件,仅仅是为了支持不同的编辑器。

为一种编程语言添加诸如自动补全、跳转到定义或悬停提示信息这样的功能并非易事。更糟糕的是,语言工具的提供方不得不针对每一款编辑器重复同样的工作,因为每一款编辑器都有其自身的应用程序编程接口(API)。

而且还存在一些更棘手的挑战:

  • 不同的语言,不同的运行时:

    语言工具的编写语言常常与编辑器所使用的语言不同。例如,语言工具可能是用 Python 或 Go 编写的,而 Visual Studio Code(VS Code)是基于 Node.js 运行的。所以,要让它们协同工作并非总是一帆风顺的。

  • 性能影响:

    语言工具要进行大量繁重的工作,比如解析代码、分析语法以及查找定义。在编辑器内部运行所有这些操作可能会使运行速度变慢。

  • 集成的工作量过大:

    正如我们之前所看到的,编辑器必须为每种语言工具分别构建支持,而且语言工具的提供方必须为每个编辑器编写插件,即使是针对同一种语言也是如此。

为了解决所有这些问题,语言服务器协议(LSP)应运而生。

LSP是什么

语言服务器协议(LSP)是一种规范(一套规则)或协议,它定义了编辑器和语言服务器之间的通信方式。

语言服务器协议(LSP)有两个主要组成部分。

  • 语言服务器:这是一个后台进程,它能够理解你的代码,并提供特定于某种语言的功能。

    语言服务器并非新鲜事物。在语言服务器协议(LSP)出现之前,它被称为语言工具,会紧密集成到编辑器或集成开发环境(IDE)中。如今的不同之处在于,语言服务器作为一个独立的进程运行,并通过语言服务器协议(LSP)与编辑器进行通信。

  • 语言客户端:它是编辑器中的一种插件或扩展程序,负责与语言服务器进行通信,获取相应功能并将这些智能特性展示给你。

    现在,任何符合语言服务器协议(LSP)的服务器都可以与任何符合该协议的编辑器协同工作。

在这里插入图片描述
我们已经看过了上面的概要示意图。现在,这里有一张详细的示意图,展示了一个 Python 语言服务器如何能与多个编辑器协同工作。

在这里插入图片描述
我们已经了解了在语言服务器协议(LSP)出现之前存在的问题。现在,让我们来看看 LSP 是如何让事情变得更简单的。

  • 问题:不同的语言,不同的运行时

    解决方案:

    如今,编辑器和语言服务器是相互独立的进程。它们只需通过 LSP(基于 JSON - RPC)交换消息,所以双方使用何种语言编写并不重要。只要两者都遵循该协议,它们就可以协同工作。

  • 问题:性能问题

    解决方案:

    像解析文件和分析语法这类繁重的任务由语言服务器承担,不会在编辑器中运行。这样,编辑器就能保持轻量级且响应迅速。这是一种清晰的分工,双方都能发挥各自所长。

  • 问题:M×N 集成问题

    解决方案:M + N

    现在,每个编辑器只需有一个 LSP 客户端,每种语言只需实现一个遵循 LSP 标准的语言服务器。

    之后,同一个语言服务器就可以在任何支持 LSP 的编辑器中复用,无需额外的工作。

在这里插入图片描述
语言服务器协议背后的核心思想是让语言开发者无需为每个编辑器分别编写不同的实现方案而头疼。

语言服务器协议(LSP)的工作原理

好了,我们现在知道了语言服务器协议(LSP)是编辑器和语言服务器之间进行通信的标准方式。但这种 “通信” 究竟是如何实现的呢?

让我们来详细剖析一下。

语言服务器协议(LSP)是构建在一种名为 JSON-RPC(JSON 远程过程调用)的技术之上的,它是一种让两个程序能够使用纯 JSON 格式来回发送消息的简单方式。下面是一张简要的示意图,展示了集成开发环境(IDE)和语言服务器是如何交换消息的。

在这里插入图片描述

下面通过一个简化的流程,来理解 IDE 与语言服务器之间是如何交换消息的:

  • 用户打开文件 → didOpen(已打开)
    编辑器通知语言服务器:某个文件已经被打开,请开始对其进行分析。

  • 用户编辑文件 → didChange(已更改)
    每当用户输入内容,编辑器都会将最新的变更发送给服务器。

  • 服务器返回错误或警告 → publishDiagnostics(发布诊断信息)
    服务器完成分析后,将发现的错误、警告或提示信息返回给编辑器。

  • 用户触发“转到定义” → definition(定义)
    编辑器向服务器请求某个符号的定义位置,服务器返回对应的源码位置。

  • 用户关闭文件 → didClose(已关闭)
    编辑器通知服务器:文件已关闭,可以释放相关资源。

也就是说,每当你打开文件、编辑代码、执行跳转或触发补全时,编辑器与语言服务器之间都会进行一次精心编排的 JSON-RPC 消息交互。你看到的是流畅的开发体验,背后其实是一套标准化的协议在默默工作。

如果你想亲眼观察这些消息交互过程,可以在 Visual Studio Code 中启用跟踪日志功能。下面以 Python 语言服务器为例进行说明(请确保已经安装 Python 扩展)。

首先,按下 Ctrl + Shift + P,输入并选择:

首选项:打开设置(JSON)

然后在 settings.json 中添加以下配置:

"python.analysis.logLevel": "Trace"

接着,点击:

视图(View) → 输出(Output)

在输出面板的下拉菜单中选择 Python Language Server

此时,当你在任意 Python 文件中进行编辑操作时,就可以实时看到编辑器与语言服务器之间的 JSON-RPC 消息交互过程。

至此,LSP 不再只是一个抽象的“协议概念”,而是一套可以被观测、被调试、被验证的通信机制。

在这里插入图片描述
现在,让我们来看看语言服务器能够通过语言服务器协议(LSP)实现并支持的所有语言特性。

在这里插入图片描述
语言服务器无需实现上述所有特性。它只需告知编辑器自己支持哪些特性,并在初始握手阶段共享这些能力。

在连接开始时,客户端会发送一个包含自身能力的初始化请求。然后,服务器会以其支持的特性作为响应。这被称为静态能力注册。

下面的截图展示了客户端向服务器发送的初始化请求。

在这里插入图片描述
目前,大多数主流编程语言都已经拥有对应的语言服务器。你可以在官方页面查看完整列表。如果你需要的语言服务器尚未被列出,也可以按照页面中的说明,在 GitHub 上提交 Pull Request 进行贡献。

下面列举几个示例:

  • Go → Go 语言服务器
  • JavaScript 和 TypeScript → JavaScript 与 TypeScript 语言服务器
  • PHP → PHP 语言服务器
  • Python → Python 语言服务器

在这里插入图片描述
参考链接:https://www.devshorts.in/p/understanding-language-server-protocol

再给一个实际的案例,比如我下载了一个支持LSP的现代IDE,然后写了一行python代码又写了一行golang代码,IDE会做什么?

先打破一个误区:

👉 IDE 本身并不真正“理解”Python 或 Go。

IDE 只做三件事:

  1. 监听你的输入
  2. 把事件转换成 JSON-RPC 请求
  3. 把语言服务器返回的数据渲染出来

真正理解代码的是语言服务器。

假设你写下:

import os
os.pa

你刚输入 os.pa,IDE 想做自动补全。

第一步IDE 会向 Python 语言服务器发送一个 JSON-RPC 请求:

{
  "method": "textDocument/completion",
  "params": {
    "textDocument": { "uri": "file:///test.py" },
    "position": { "line": 1, "character": 5 }
  }
}

意思是:

“在 test.py 第 2 行第 6 个字符的位置,请给我补全建议。”

第二步:Python 语言服务器(例如 Pylance / Pyright)会分析:

  • 当前文件 AST
  • 已 import 模块
  • 类型信息

然后返回:

{
  "result": [
    {
      "label": "path",
      "kind": 2,
      "detail": "module",
      "documentation": "Common pathname manipulations."
    },
    {
      "label": "pardir",
      "kind": 13,
      "detail": "str",
      "documentation": "Parent directory constant ('..')"
    }
  ]
}

IDE 接收到后会:

  • 展示自动补全下拉框
  • 显示文档说明
  • 支持 Tab 自动补全

⚡ 注意:

LSP 返回的是结构化数据,不是“渲染好的 UI”。

现在你打开一个 Go 文件:

package main

import "fmt"

func main() {
    fmt.Pr
}

你输入 fmt.Pr

IDE 再次发送:

{
  "method": "textDocument/completion"
}

Go 语言服务器(例如 gopls)会:

  • 解析当前包
  • 检查标准库
  • 分析符号表

返回:

{
  "result": [
    {
      "label": "Println",
      "kind": 3,
      "detail": "func(a ...interface{}) (n int, err error)"
    },
    {
      "label": "Printf",
      "kind": 3,
      "detail": "func(format string, a ...interface{})"
    }
  ]
}

IDE 负责把这些数据显示成:

  • 下拉列表
  • 函数签名提示
  • 参数高亮

LSP 服务器可以返回很多类型的数据:

功能 LSP 方法 返回内容
语法错误 publishDiagnostics 错误位置、严重级别、提示信息
跳转定义 definition 文件路径 + 行号
查找引用 references 所有使用位置
重命名 rename 需要修改的所有位置
悬浮提示 hover 文档说明 + 类型信息
代码格式化 formatting 修改后的完整文本

举个完整错误例子:

Python 代码:

print(unknown_var)

语言服务器会返回:

{
  "method": "textDocument/publishDiagnostics",
  "params": {
    "diagnostics": [
      {
        "range": { "start": { "line": 0, "character": 6 }},
        "severity": 1,
        "message": "Name 'unknown_var' is not defined"
      }
    ]
  }
}

IDE 做什么?

  • 红色波浪线
  • 错误提示气泡
  • 问题面板显示错误

LSP 服务器返回的是:

📦 “结构化的语言智能数据”

IDE 负责:

🎨 把数据渲染成交互体验

当你在同一个 IDE 中:

  • 写 Python → 连接 Python LSP
  • 写 Go → 连接 Go LSP

IDE 的 UI 完全一样。不同的只是背后连接的语言服务器不同。

这就是 LSP 的威力:

编辑器与语言能力彻底解耦。

MCP

MCP 解决了使用大模型的痛点:大模型只知道训练时学到的静态知识,无法获取动态的实时信息或执行具体的操作。

换句话说,AI 大模型是一位学识渊博但是光说不做的博士,他不会上网,不会使用工具,只能根据已有的知识来回答问题。

而MCP协议做的事情就是:告诉AI大模型有哪些工具(tools)和资源(resources)可以使用,以怎么样的工作流/提示(prompts)来使用,以通用统一协议的方式将AI大模型和外界进行连接(这也就是将其比喻为大模型USB通用接口的由来)。

在这里插入图片描述

从 API、LSP 到 MCP

在这里插入图片描述
要理解一个新的协议,最好的方式之一,是回头看看在它之前,系统与协议是如何运作的。技术的演进往往不是凭空出现,而是在旧有问题之上不断抽象、解耦与标准化的过程。

API(Application Programming Interface,应用程序接口)

在更早的时代,为了标准化 Web 应用中前端与后端之间的交互方式,工程师们定义了 API(应用程序编程接口)。

API 的核心作用,是约定一种通信方式,使得:

  • 后端能够向前端返回结构化数据
  • 前端能够向后端提交请求数据

它本质上解决的是:

不同系统之间,如何用统一方式交换数据。

通过 API,前端可以访问服务器、数据库以及各种后端服务。前后端的职责开始清晰分离,Web 架构也因此逐渐成熟。

Language Server Protocol(语言服务器协议)

时间来到 2016 年,LSP 协议正式出现。

如果说 API 解决的是“前端与后端如何通信”,那么 LSP 解决的则是:

编辑器与语言能力之间如何通信。

在 LSP 出现之前,各家 IDE 的代码编辑能力几乎都是“自研体系”:

  • 自动补全的实现方式不同
  • 代码诊断接口不同
  • 查找引用机制不同
  • 工作区操作 API 不统一

可以说生态非常混乱。

于是,微软将 IDE 中常见的能力抽象为一系列“行为事件”(如打开文件、修改文件、请求补全、请求定义等),并定义了一套统一的通信协议 —— LSP。

从此:

  • 语言能力被抽离为“语言服务器”
  • IDE 只负责 UI 与交互
  • 双方通过标准化协议通信

例如,当你在编写 Go 微服务时,只要 IDE 兼容 LSP,它就可以连接到 Go 语言服务器。IDE 不再需要关心如何实现代码诊断或语法分析,只需要:

  • 发送 LSP 规定的行为事件
  • 渲染语言服务器返回的结构化结果

编辑器与语言实现彻底解耦。

Model Context Protocol(模型上下文协议)

时间再往前推进到 2024 年 11 月底,Anthropic 推出了 MCP 协议。

如果说 LSP 是为“语言智能”建立标准,那么 MCP 试图为“模型智能”建立标准。

MCP(Model Context Protocol)是一种开放标准,用于规范 AI 应用程序与外部系统之间的交互方式。它的核心目标是:

让模型能够以标准化方式访问外部能力。

MCP 协议围绕三种核心接口展开:

  • prompt(提示):定义模型输入结构
  • tools(工具):允许模型调用外部能力
  • resources(资源):为模型提供可访问的数据上下文

如果类比:

  • API 标准化了前后端交互
  • LSP 标准化了 IDE 与语言能力交互
  • MCP 则开始标准化模型与外部世界的交互

技术演进的路径开始变得清晰:

从“系统之间的通信”
到“编辑器与语言能力的通信”
再到“模型与现实世界的通信”

而这,也正是协议不断抽象与升级的历史轨迹。

在没有 MCP 协议之前,各家的 AI 产品在构建 AI 系统这一事情上并没有一个共识。每个团队会创建一个 AI 应用,他们通过自定义的方式连接到他们的上下文,这个自定义方式使用了他们自己的的提示逻辑,并使用不同的方式来引入工具和资源,然后以不同的方式协同访问这些工具和数据。如果一家公司内有多个团队,每个团队有自己的一套自定义的方式,那么可以想象整个行业也是这么做的,这就存在成百上千个自定义协议。

这就好比过去充电协议未统一时(虽然现在也还没有统一),管理各式各样的充电设备、充电协议、充电标准真的是很头疼的一件事。

在这里插入图片描述
而现在有了MCP,模型可以和数据、文件系统、开发工具、Web 和浏览器自动化、生产力和通信、各种社区生态能力集成,实现协作工作能力。 而最大的优点在于:MCP 是开放标准,有利于服务商开发 API,避免重复造轮子,各家有了一个共识来使用一套标准来构建各自的产品,而后也为这些产品之间的联动打下了基础(这也是谷歌推出A2A协议想做的事)。

在这里插入图片描述

MCP 应用架构

在这里插入图片描述
上图展示了使用 Model Context Protocol 构建完整应用时的整体结构。可以看到,体系主要包含:

  • MCP Client(客户端)
  • MCP Server(服务端)
  • 三个核心接口:Tools、Resources、Prompts

MCP 客户端的核心职责是:

调用工具、获取资源,并将相关信息嵌入到提示词中,构建完整的模型上下文。

它的工作流程通常是:

  1. 查询服务端有哪些工具和资源可用
  2. 将工具说明嵌入提示词
  3. 结合当前用户输入与上下文
  4. 调用模型进行推理
  5. 根据模型决策决定是否调用工具

客户端本质上是:

模型的“执行协调者”

MCP 服务端的作用是:

将工具、资源与提示模板,以标准化方式对外暴露。

这里的“暴露”可以类比传统后端服务:

  • 开放 IP:PORT
  • 等待客户端连接
  • 提供 API 能力

不同的是,MCP Server 暴露的不是普通 HTTP API,而是:

  • 可调用工具
  • 可访问资源
  • 可复用提示模板

1️⃣ 工具:Tools

在 Anthropic 官方文档中,Tools 的定义是:

Enable LLMs to perform actions through your server.

也就是说:

通过工具,LLM 可以执行真实操作。

工具可以:

  • 与外部系统交互
  • 执行计算
  • 调用数据库
  • 发起 HTTP 请求
  • 操作文件

这正好解决了大模型此前的核心痛点:

模型只能“说”,不能“做”。

工具的工作流程

  1. 客户端向服务端询问有哪些工具
  2. 服务端返回工具描述与调用方式
  3. 客户端将工具能力嵌入提示词
  4. 模型自行决定是否调用工具
  5. 若调用,客户端执行并返回结果

重要的一点是:

工具由模型控制,而不是由用户直接触发。

2️⃣ 资源:Resources

官方定义:

Expose data and content from your servers to LLMs.

资源用于:

向模型提供可读取的数据与内容。

例如:

  • 文件内容
  • 文档
  • 数据库记录
  • 系统信息

与 Tools 不同的是:

  • Tools 由模型决定何时调用
  • Resources 由应用决定何时加载

在过去,用户通常通过:

  • 复制粘贴
  • 上传附件

向模型提供上下文。

而现在,资源成为一种标准化接口,使客户端可以自动获取并注入上下文。

例如在安装各类 AI 应用时(如 Cursor、Cherry Studio、Cline 等),应用会读取本机环境信息(操作系统、内核版本等),再传递给模型。

需要注意的是:

目前并非所有 MCP 客户端都完整支持 Resources 功能。

3️⃣ 提示:Prompts

官方定义:

Create reusable prompt templates and workflows.

提示词本身并不新鲜,但 MCP 的意义在于:

将可复用提示模板标准化与结构化。

提示是由用户控制的。

用户可以预定义提示模板,用于:

  • 特定任务
  • 特定工具链
  • 特定工作流

很多 AI 产品已经实现了类似能力,例如 @ 功能:

当你 @ 一个文档或网站时,系统会自动套用预定义的提示模板。

例如:

你以迭代方式完成给定任务,将其分解为清晰步骤……

这类复杂工作流提示,正是 Prompts 接口试图标准化的内容。

除了核心三大接口外,MCP 作者还设计了一些扩展功能。目前多数客户端尚未完全支持。

1️⃣ 采样:Sampling

“采样”这个词通常指:

有选择地获取部分数据。

在 MCP 中,Sampling 允许:

服务端请求客户端调用模型,并对结果进行采样后返回。

工作机制大致如下:

  1. 服务端请求客户端调用模型

  2. 客户端可以:

    • 直接调用
    • 修改参数
    • 拒绝请求
  3. 模型生成结果

  4. 客户端采样并返回结果给服务端

优势在于:

  • 服务端无需托管模型
  • 服务端无需实现模型调用逻辑
  • 可以通过客户端间接获得模型能力

2️⃣ 信息引导请求:Elicitations

如果说 Sampling 是:

服务端采样模型

那么 Elicitations 是:

服务端采样用户

它允许服务端通过客户端向用户请求:

  • 操作确认
  • 补充信息
  • 决策选择

例如关键操作确认、背景信息收集等。

3️⃣ 命名空间:Namespacing

未来 MCP 服务生态丰富之后,必然会出现命名冲突问题。

例如:

  • A 公司提供 SayHello
  • B 公司也提供 SayHello

模型调用时就可能产生歧义。

目前的解决思路通常是添加前缀:

A-SayHello
B-SayHello

但作者希望未来能够在协议层面,将命名空间设计为一等公民。

4️⃣ 注册中心:MCP Registry

随着 MCP 服务数量增长,需要统一治理方案。

MCP Registry 提供:

  • 集中式服务仓库
  • RESTful 管理 API(增删改查)
  • 服务健康监控

在作者的构想中,未来可以按功能聚合工具包,例如:

  • Office 套件(文档处理、表格计算)
  • 数据分析工具包
  • DevOps 工具集

用户可以直接订阅工具包,而无需逐个添加工具。

核心架构

消息协议:JSON-RPC 2.0

消息协议规定了客户端与服务端之间的消息格式标准。也就是说,双方必须约定:

每一条请求与响应应该长什么样。

在 Model Context Protocol 中,唯一标准的消息格式是JSON-RPC 2.0。

JSON-RPC 2.0 是一种轻量级的远程过程调用(RPC)协议:

  • 使用 JSON 作为数据格式
  • 结构简单
  • 易于解析
  • 适合双向通信场景

假设我们有一个计算器 MCP 工具,客户端希望执行表达式 1+1

客户端发送的 JSON-RPC 请求格式如下:

{
  "jsonrpc": "2.0",           // 协议版本,固定为 "2.0"
  "method": "calculate",      // 要调用的方法名
  "params": {                 // 方法参数
    "expression": "1+1"
  },
  "id": 1                     // 请求标识符,用于匹配响应
}

字段说明:

  • jsonrpc:协议版本号
  • method:调用的方法名称
  • params:参数(对象或数组)
  • id:请求唯一标识,用于匹配返回结果

当 MCP 服务端处理完成后,会返回如下响应:

{
  "jsonrpc": "2.0",   // 协议版本
  "result": "2",      // 调用结果
  "id": 1             // 对应的请求标识符
}

如果发生错误,则返回:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "Method not found"
  },
  "id": 1
}

可以看到:

JSON-RPC 负责“格式标准”,而 MCP 负责“语义规范”。

传输协议:Transport Layer

如果说 JSON-RPC 解决的是:

消息长什么样?

那么传输层解决的是:

消息通过什么方式传递?

MCP 协议内置了两种标准传输实现,并在 2025 年 3 月 26 日引入了新的数据传输方式 Streamable HTTP

标准输入 / 输出(STDIO)

STDIO 通过标准输入(stdin)与标准输出(stdout)实现通信。

由于 STDIO 要求 MCP 服务端运行在客户端本机上,因此适用于:

  • 本地插件
  • 本地工具栏
  • 命令行工具
  • 桌面应用集成

使用 STDIO 时,必须遵守以下规范:

  1. 所有消息必须为 UTF-8 编码
  2. 消息格式必须为 JSON-RPC
  3. 每条消息以换行符 \n 分隔
  4. 服务端日志必须写入 stderr
  5. 严禁在 stdout 输出非协议内容(否则会导致解析错误)

核心原则只有一句话:

stdout 只允许输出协议消息。

STDIO 模式的传输流程

  1. 客户端启动 MCP Server 进程
  2. 客户端通过 stdin 写入 JSON-RPC 请求
  3. 服务端解析请求
  4. 服务端通过 stdout 返回 JSON-RPC 响应
  5. 日志信息通过 stderr 输出

STDIO 模式结构简单,适合本地运行的轻量级集成场景。

在这里插入图片描述

服务器发送事件(SSE)

SSE(Server-Sent Events)是目前 MCP 远程模式下使用最多的传输方式,同时也是争议最多的一种模式。

SSE 支持:

  • 服务端 → 客户端 的流式推送
  • 客户端 → 服务端 通过 HTTP POST 发送请求

因此,它实际上是一种:

HTTP POST + SSE 的组合通信模式

假设我们仅使用 HTTP POST 来完成 MCP 工具调用,那么通信模式将是典型的:

在这里插入图片描述

请求 → 等待 → 响应

这种同步阻塞模式在传统 Web API 中没问题,但在 AI 应用场景中会带来明显问题:

1️⃣ 同步阻塞

  • HTTP POST 默认是同步请求
  • 长时间任务(如复杂工作流执行)会导致客户端线程阻塞
  • 不适合需要持续推理或长任务执行的场景

2️⃣ 短连接问题

  • MCP 客户端通常需要频繁访问服务端
  • 默认 HTTP Keep-Alive 通常 < 60 秒
  • 存在连接超时与会话状态丢失风险

3️⃣ 服务端无法主动推送

纯 HTTP 模式下:

  • 数据流必须由客户端发起
  • 服务端无法主动向客户端发送消息

但 MCP 中的某些能力(例如 Sampling)依赖:

服务端主动向客户端发起交互

4️⃣ 流式输出需求

大多数 AI 场景都需要:

  • Token 级流式输出
  • 实时进度反馈
  • 分段推理结果返回

纯 HTTP POST 很难优雅支持这些需求。基于上述原因,MCP 在远程模式下选择:

HTTP + SSE 作为标准传输方式

什么是 SSE?

SSE(Server-Sent Events)是一种基于 HTTP 的单向通信技术,允许服务器持续向客户端推送消息。

其核心特点:

  • 单向传输(服务器 → 客户端)
  • 基于 HTTP 协议
  • 使用一次 HTTP GET 建立长连接
  • 适合实时数据推送场景(如进度更新、流式响应等)

一次完整会话通常如下:

在这里插入图片描述

1️⃣ 建立连接

客户端通过 HTTP GET 建立 SSE 连接。
服务端确认连接,并生成唯一的 Session ID。

2️⃣ 发送请求

客户端通过 HTTP POST 发送 JSON-RPC 2.0 请求。

请求中包含:

  • Session ID
  • Request ID
  • 方法与参数

3️⃣ 服务端确认接收

服务端立即返回:

202 Accepted

表示请求已被接受。

4️⃣ 异步处理

服务端内部处理逻辑:

  • 解析参数
  • 调用工具或访问资源
  • 生成结果

5️⃣ 推送结果

处理完成后,服务端通过 SSE 通道推送 JSON-RPC 响应:

  • 包含对应的 Request ID
  • 可能是流式分段返回

6️⃣ 客户端匹配响应

客户端通过 SSE 监听数据流,并根据 Request ID:

  • 将响应与原请求匹配
  • 更新界面或继续执行

7️⃣ 循环处理

客户端可以持续发送 POST 请求,
服务端持续通过 SSE 推送响应。

8️⃣ 连接关闭

当会话结束时:

  • 客户端关闭 SSE 连接
  • 会话终止

总结一句话

客户端通过 HTTP POST 发送请求
服务端通过 SSE 长连接异步返回结果

这是一种:

HTTP POST(客户端→服务端) + HTTP SSE(服务端→客户端)的伪双工通信模式

为什么不直接使用 WebSocket?

既然 SSE 是“伪双工”,那为什么不直接使用真正双工的 WebSocket?官方团队确实认真讨论过这个问题,并最终暂时放弃 WebSocket,主要原因如下:

1️⃣ RPC 场景下增加复杂度

在 RPC 风格的 MCP 服务中(例如无状态工具调用):

  • 每次调用都依赖 WebSocket
  • 会增加连接维护成本
  • 网络管理复杂度上升

2️⃣ 浏览器限制

在浏览器环境中:

  • WebSocket 无法像普通 HTTP 请求一样灵活附加请求头(如 Authorization)
  • 认证流程变得更复杂

3️⃣ 协议升级复杂

WebSocket 只能通过 HTTP GET 升级:

  • POST 需要二次握手
  • 增加额外延迟
  • 提高状态管理复杂度

4️⃣ 规范兼容性风险

如果 MCP 同时支持:

  • HTTP + SSE
  • WebSocket

将导致:

  • 客户端与服务端组合复杂度爆炸
  • 兼容矩阵难以维护
  • 可能破坏统一规范

虽然 SSE 带来了诸多优势,但它也存在缺点:

❗ 不支持断点恢复,如果 SSE 长连接断开:

  • 无法从中断位置恢复
  • 必须重新建立连接
  • 之前的上下文可能丢失

❗ 对服务器高可用要求高

  • 必须维持稳定长连接
  • 任意中断都会影响通信

❗ 单向限制

  • 服务端只能通过 SSE 通道发送消息, 不能随意发起新通道通信。

Streamable HTTP

基于前文提到的 SSE 模式存在的种种问题,
在 2025-03-26 发布的 Model Context Protocol 标准更新中,官方对传输层进行了调整,并引入了新的传输模式:

Streamable HTTP

这并不是简单的“替换 SSE”,而是对原有通信模式的一次结构性优化。相比于原有的 HTTP + SSE 固定模式,Streamable HTTP 的最大特点是:

允许服务端按需选择通信模式。

服务端可以:

  • 使用简单的无状态 HTTP 模式
  • 在需要时升级为流式 SSE 模式
  • 同一协议层下统一处理

具体改动:

1️⃣ 移除专门的 /sse 端点

在旧模式中:

  • /message 用于 POST 请求
  • /sse 专门用于建立 SSE 流

而在 Streamable HTTP 中:

所有通信统一通过 /message 端点处理。

请求与流式响应都在统一协议层完成,减少端点分裂与状态复杂度。

2️⃣ 按需升级为流式响应

当任务需要流式输出时:

  • 服务端可以将响应升级为 SSE 流
  • 客户端也可以通过 GET 请求初始化 SSE 流

换句话说:

流式能力成为“可选能力”,而不是“默认强制能力”。

3️⃣ 支持无状态模式(Stateless)

Streamable HTTP 不再强制要求持续长连接。

这意味着:

  • 服务端可以完全无状态
  • 每次请求独立处理
  • 不需要维持长期会话

这对构建轻量级 MCP Server 非常友好。

Streamable HTTP 的优势

✅ 更灵活

  • 不强制使用流式传输
  • 可根据场景按需升级为 SSE

✅ 更简单

  • 支持无状态服务端
  • 不需要维持复杂的长连接管理

✅ 更兼容

  • 完全基于 HTTP
  • 不引入额外协议
  • 更容易部署在现有 Web 基础设施之上

可以把通信方式理解成“打电话”和“发消息”的区别。

旧的 SSE 模式就像:

打电话时必须保持通话不中断。

只要通话断了,就必须重新拨号。

而 Streamable HTTP 更像:

你可以随时给对方发一条消息,然后等对方回复。

  • 不需要一直保持通话
  • 需要时再建立流式连接
  • 更加自然、轻量

总结

本质上 MCP 协议是规定了大模型与外界应用沟通的一套标准规范,需要注意的是,MCP 协议只提供统一的工具接口,而无法决定工具将被如何选择和组合。

一个可用的好用的 AI 产品应该是多个组件共同协作的结果:大语言模型(LLM)负责提供基础的自然语言理解与生成能力,智能体(Agent)框架承担任务分解与执行逻辑的协调功能,而模块化控制平台(MCP)则致力于提供标准化的工具调用接口。

ACP

在这里插入图片描述

近两年,AI 编码助手呈现爆发式增长:GitHub Copilot、Claude Code、Gemini CLI、OpenHands、Qwen Code、Kimi CLI、OpenCode……

但开发体验却愈发割裂:

  • 每个编辑器都要为每一个 AI 助手单独写插件:VS Code 一套、JetBrains 一套、Neovim/Emacs 再一套。
  • 每个 AI 助手也要针对不同编辑器分别适配,维护成本高,功能还不统一。
  • 一旦后端 API 或交互模式升级,前端插件就必须全部跟着修改。

这与 LSP 出现之前的“语言服务碎片化”极其相似:在 LSP 出现之前,各 IDE 都需要分别为每种语言实现语法高亮、代码补全、跳转等功能,而 LSP 将“语言服务”抽象成统一标准,极大降低了集成成本。

在 AI 编码时代,我们遇到的问题更复杂:

如何让“任意编辑器”可以连接“任意 AI 编码代理”,而不是被某家厂商的“编辑器 + AI”生态绑死?

ACP 是什么?和 IBM 的 ACP 有何不同?

Agent Client Protocol(Zed 社区主推)
在这里插入图片描述

ACP(Agent Client Protocol,智能体客户端协议)是一个标准化的通信协议,定义了 IDE/编辑器与 AI 编码助手之间的交互规范。如果你熟悉 LSP(Language Server Protocol),可以将 ACP 理解为 “AI Agent 的 LSP”

ACP 的设计围绕一个核心原则:让 IDE 完全掌控 AI Agent 的每一步操作

在传统的 AI 编码助手中,Agent 往往是一个“黑盒” ——你发送一个请求,等待一段时间后得到结果,但中间发生了什么、Agent 读取了哪些文件、修改了什么代码,这些过程对 IDE 和用户来说都是不可见的。这在企业环境中带来了严重问题:

  • 安全风险:无法审计 Agent 访问了哪些敏感文件
  • 信任问题:用户不知道 Agent 在“思考”什么,难以建立信任
  • 协作困难:IDE 无法在 UI 中实时展示 Agent 的工作进度
  • 调试困难:出错时无法追溯 Agent 的操作历史

ACP 通过将 工具调用(Tool Call) 作为一等公民,彻底解决了这个问题。在 ACP 中,Agent 的每一个操作——读取文件、编辑代码、执行命令——都必须通过明确的工具调用来完成,并且这些调用对 IDE 完全 可见、可控、可审核

Agent Client Protocol(ACP)是一个基于 JSON-RPC 2.0 的开放协议,用于标准化:

  • 客户端(Client):编辑器、IDE、终端 UI 或桌面应用
  • 代理(Agent):具备代码理解、生成、重构能力的 AI 编码代理(通常基于大模型 + 工具调用)

一句话概括 ACP 的目标:

任何编辑器 都能无缝连接 任何 AI 编码代理,就像 LSP 统一语言服务那样,实现统一的 AI 编码体验。

注意不要和 IBM 的 ACP 混淆

当前“ACP”存在两条主线,需要明确区分:

名称 全称 核心对象 典型场景
Agent Client Protocol Agent Client Protocol(Zed) 编辑器 / IDE ↔ AI 编码代理 Zed、JetBrains、Neovim 等连接 Gemini CLI、Claude Code、OpenHands
Agent Communication Protocol Agent Communication Protocol(IBM 等) Agent ↔ Agent、应用 ↔ Agent 多智能体协作、跨系统编排

本文中如无特别说明,“ACP”均指 Zed 社区主导的 Agent Client Protocol

架构与消息模型

ACP 采用 主从通信模型:IDE 作为 Client,Agent 作为 Server 子进程。通信通过 JSON-RPC 2.0 协议在 stdio (标准输入输出)上进行。

在这里插入图片描述
一个典型的交互流程如下:

  1. 初始化与能力协商
    IDE 启动 Agent 子进程后,双方首先进行能力协商——类似 LSP 的初始化握手。
    这种双向协商确保了 IDE 和 Agent 都清楚对方的能力边界,避免了不兼容问题。

  2. 会话与任务执行
    用户在 IDE 中发起请求后,Agent 开始工作。关键在于,Agent 的每一步操作都会实时推送给 IDE,IDE 可以在 UI 中实时展示这些信息:执行计划、当前正在读取的文件、即将修改的代码。
    用户对 Agent 的行为一目了然

  3. 权限控制与审核
    当 Agent 需要执行敏感操作(如修改文件、执行命令)时,必须向 IDE 请求权限。IDE 可以:

  • 自动批准(基于用户预设的策略)
  • 弹窗询问用户
  • 展示 Diff,让用户审核后再应用

这种机制让企业可以实施细粒度的安全策略,例如:

“允许 Agent 读取任何文件,但修改代码必须经过人工审核”。

在 ACP 中:

  • Client = 编辑器 / UI 端

    • 掌握本地文件系统
    • 终端操作
    • 权限确认 UI
  • Server = AI 代理

    • 掌握大模型推理
    • 代码生成能力
    • 工具编排能力

典型架构如下:

+---------------------------+       JSON-RPC (stdio/pipe/TCP)       +------------------------+
|  Editor / IDE / GUI      |  <------------------------------->    |  Coding Agent (ACP)    |
|  (Zed / JetBrains /      |                                      |  (Gemini CLI /         |
|   AionUi / Open Cowork)  |                                      |   Claude Code / etc.)  |
+---------------------------+                                      +------------------------+
         ↑                                                                           ↑
         |  提供:文件系统、终端、权限 UI                                         |  执行:分析、规划、生成代码
         |                                                                           |
    人机交互 & 环境层                                                         智能决策 & 执行层

这种划分的两个关键好处:

  1. 安全:代理不直接访问本地文件或终端,一切通过 Client 提供的受控接口 + 权限确认
  2. 可组合:代理既可以是本地 CLI 工具,也可以是远程服务,只要遵循 ACP 协议,就能挂载到各种编辑器 / 桌面 UI 上

ACP 严格遵守 JSON-RPC 2.0 标准,把所有交互规范化为两类消息:

  1. Request / Response(请求-响应)
  2. Notification(通知,无需响应)

请求示例:initialize

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "clientInfo": {
      "name": "Zed",
      "version": "0.202.0",
      "capabilities": {
        "fs": {
          "readTextFile": true,
          "writeTextFile": true
        },
        "terminal": true
      }
    }
  }
}

响应示例:initializeResult

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "agentInfo": {
      "name": "Gemini CLI",
      "version": "1.3.0"
    },
    "capabilities": {
      "loadSession": true,
      "modes": ["chat", "edit"]
    }
  }
}

通知示例:session/update(流式输出)

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "abc-123",
    "updates": [
      { "type": "messageChunk", "role": "assistant", "content": "正在分析你的项目结构…" }
    ]
  }
}

一次完整交互的“生命周期”:

从编辑器视角看,一次使用 AI 的完整流程可以拆解为 4 个阶段:

  1. 初始化

    • initialize:能力协商(双方是谁、都能干什么)
  2. 会话建立

    • session/new:新建会话
    • session/load:加载旧会话(取决于代理是否支持)
  3. 对话 & 操作过程

    • session/prompt:发送用户请求(附上下文)
    • 代理通过 session/update 持续推送计划、生成内容、进度
    • 用户或编辑器可发送 session/cancel 终止
  4. 工具调用 & 权限

    • 当代理需要读写文件或执行命令时:

      • 通过 session/request_permission 请求授权
      • Client 通过 UI 询问用户是否允许
      • 再通过 fs/*terminal/* 调用具体能力

这个生命周期已在多款产品中验证,如 Gemini CLI、Claude Code、OpenHands 与 JetBrains / Zed / AionUi 的集成。

为了避免“一上新功能就得改协议核心”的问题,ACP 提供了类似 LSP 的扩展能力:

  • 自定义方法:以 _ 前缀区分实验 / 私有扩展,例如 _symmacp/pipeline
  • 扩展元数据:统一放在 _meta 中,避免污染主结构
  • 能力声明:所有扩展在 initialize 里通过 capabilities 广而告之

这保证了:

  • 主协议稳定,可长期演化
  • 厂商 & 社区可以在不破坏兼容性的前提下进行创新

如何把自己的工具“接上 ACP 总线”

为了降低接入门槛,ACP 提供了多语言 SDK,封装了:

  • 面向协议的 Pydantic / struct 类型模型(防止字段乱写)
  • 基于 asyncio / async 的传输和消息收发
  • Agent / Client 抽象基类,简化实现过程

目前主流语言支持包括:

语言 SDK 包名
Python agent-client-protocol
Rust agent-client-protocol
Kotlin acp-kotlin
TypeScript @agentclientprotocol/sdk

用 Python 写一个最简 ACP Agent 的思路

下面是一个抽象化AgentServer的示例(简化版,用于快速建立直觉):

from acp import Agent, schema
import asyncio

class SimpleAgent(Agent):
    async def initialize(self, params: schema.InitializeParams) -> schema.InitializeResult:
        """处理初始化请求"""
        return schema.InitializeResult(
            agentInfo={"name": "simple-agent", "version": "0.1"},
            capabilities={"loadSession": False}
        )

    async def session_new(self, params: schema.SessionNewParams) -> schema.SessionNewResult:
        """创建新会话"""
        return schema.SessionNewResult(sessionId="session-1")

    async def session_prompt(self, params: schema.SessionPromptParams) -> schema.SessionPromptResult:
        """处理用户请求"""
        await self.send_session_update(
            schema.SessionUpdateParams(
                sessionId=params.sessionId,
                updates=[schema.MessageChunk(type="messageChunk", content="思考中…")]
            )
        )

        return schema.SessionPromptResult(
            stopReason="completed",
            response=f"Echo: {params.prompt}"
        )

if __name__ == "__main__":
    agent = SimpleAgent()
    asyncio.run(agent.serve_stdio())  # 通过 stdio 与 ACP 客户端通讯
    # asyncio.run(agent.serve_tcp(host="0.0.0.0", port=9000))  # 网络远程访问

然后在 Zed / JetBrains / AionUi 等ACP 客户端的配置里写上类似内容,即可把你的远程Agent 挂到对应 IDE:

{
  "agent_servers": {
    "My Simple Agent": {
      "command": "python",
      "args": ["-m", "my_simple_agent_module"]
    }
  }
}

如果你是“编辑器 / UI”开发者,该做什么?

你需要实现一个 ACP Client 层,其职责包括:

启动 Agent 进程

  • 按用户配置执行 command + args

维护 JSON-RPC 连接

  • 通过 stdio / socket 读写 NDJSON 流

协议调度

  • 框架层统一处理 initializesession/newsession/prompt
  • session/update 映射到 UI:流式输出、Patch 展示、权限弹窗

能力适配

  • 把 IDE 的文件 API 映射为 ACP 的 fs/* 方法
  • 把内置终端映射为 terminal/* 方法

JetBrains 在 2025 年底发布的 ACP 支持,就是经典示例:整个 IDE 家族(IntelliJ、GoLand、PyCharm 等)只需实现一次 ACP Client,就可以同时接入 Gemini CLI、Claude Code、OpenHands 等多种 Agent。

格式化如下:


如何在团队中落地 ACP?

假设你所在团队有两个诉求:

  1. 想在公司主力 IDE 中统一引入各种 AI 编码助手
  2. 想把自研的代码 Agent 提供给团队成员使用

我们可以按照“编辑器团队”和“Agent 团队”两侧来规划。

如果你负责“编辑器 / 内部开发工具”

短期目标(1–2 个月):做一个最小可用的 ACP Client 集成

  • 选一个编辑器或内部 Web IDE 作为试点

  • 引入 TypeScript / Kotlin ACP SDK

  • 实现最基本的功能:

    • initialize / session/new / session/prompt
    • 接入 session/update → 将文本流显示到一个简单的 Chat 面板
  • 配置 1–2 个现成 Agent(如 Gemini ACP、OpenCode ACP)验证全链路

中期目标(3–6 个月):扩展到“生产可用”

  • 接入文件能力:实现 fs/read_text_file / fs/write_text_file 映射到项目文件树

  • 接入终端能力:实现 terminal/* 映射到 IDE 内置终端

  • 实现权限模型:

    • 所有写文件 / 执行命令必须弹窗确认
    • 提供“一次性允许 / 本会话允许 / 永久允许”选项
  • 引入多 Agent 支持:有选择地接入 Claude Code、Qwen Code、OpenHands 等

长期目标:内部 AI 平台对接

  • 在 IDE 侧只负责 ACP Client

  • 把企业内部的 AI 编码平台封装成一个或多个 ACP Agent Server,对内统一暴露

  • 通过组织级策略控制:

    • 哪些项目可用哪些 Agent
    • 哪些目录可被 Agent 读写

如果你负责“Agent / 智能体平台”

第一步:把现有 Agent 封装成 ACP Server

  • 选用合适的 SDK(Python / Rust)

  • 在现有业务逻辑外包一层:

    • 实现 initialize,声明你的能力(是否支持 loadSession、支持哪些模式)
    • 实现 session/new / session/prompt,将用户意图映射到你的内部工作流
  • 如果 Agent 需要访问文件 / 终端:

    • 改为通过 ACP 的 fs/*terminal/* 间接访问,而不是直接用 os / subprocess

第二步:写好文档和示例配置

  • 提供针对 Zed / JetBrains / AionUi / Neovim 的示例配置片段

  • 明确说明:

    • 启动命令
    • 需要的环境变量(如 API Key、代理配置)
    • 支持的模式(chat / edit / refactor / test 等)

第三步:企业内推广

  • 把 ACP 集成纳入内部 IDE / Web IDE 的“官方支持列表”
  • 从一个“高价值用例”切入(例如:安全审计 Agent 或重构 Agent),而不是泛泛聊天

小结:ACP 在整个智能体协议版图中的位置

如果把当前 Agent 相关协议做一个“分层”梳理,大致如下:

+---------------------------------+
| 应用层(IDE、桌面端、业务系统 UI) |
+---------------------------------+
| Agent Client Protocol (ACP)     | ← 本文主角:UI ↔ 编码 Agent
+---------------------------------+
| MCP / 其它 Tool 协议           | ← Agent ↔ 工具 / 数据源
+---------------------------------+
| A2A / IBM ACP / 自定义协议      | ← Agent ↔ Agent
+---------------------------------+
| HTTP / TCP / stdio / NDJSON     |
+---------------------------------+
  • MCP 解决“模型如何安全、统一地调用工具和数据源”
  • A2A / IBM ACP 解决“Agent 与 Agent 之间如何协作”
  • ACP(Agent Client Protocol) 聚焦在一个非常垂直但极其重要的领域:编辑器 / 开发环境 ↔ AI 编码 Agent

在“AI 原生开发体验”这条路径上,ACP 与 LSP 一样,很可能会成为一种长期存在的基础设施标准:

  • LSP:统一语言服务
  • MCP:统一模型与工具
  • ACP:统一 AI 编码 Agent 与编辑器

企业级 AI 平台治理体系

在多 AI 助手共存的企业环境中,单靠一个 IDE 插件或单一助手已经无法满足企业研发效率和治理要求。

现在 Agent 领域有三个主要协议,它们解决的问题完全不同:

协议 解决的问题 通信双方 典型场景
MCP Agent 如何使用工具 Agent ↔ 工具/数据源 查询数据库、调用 API
ACP 客户端如何与 Agent 交互 客户端 ↔ Agent 编辑器、笔记软件、自动化工具
A2A Agent 之间如何协作 Agent ↔ Agent 多 Agent 协同完成复杂任务

用一个比喻来理解:

  • MCP 是 Agent 的“工具箱”——定义 Agent 能用什么工具
  • ACP 是 Agent 的“工作台”——定义 Agent 在哪里工作、如何与用户交互(不只是编辑器,任何交互式客户端都可以)
  • A2A 是 Agent 的“通讯录”——定义 Agent 如何找到其他 Agent 并协作

三者可以组合使用,形成完整的智能体生态体系:

Agent 在“工作台”(ACP)中执行任务,调用“工具箱”(MCP)里的工具,并通过“通讯录”(A2A)与其他 Agent 协作。

在这里插入图片描述
结合 AutoDev 的 ACP 集成实践,以及 MCP/Skill 与 A2A 协议,企业可以构建一个完整的 AI 平台协作与治理体系:

层级 主要对象 核心关注点 企业价值
MCP / Skill 企业复用能力、业务 Skill 可组合、可调用的企业级能力模块 将业务知识与 AI 能力模块化,实现团队复用、版本控制和权限管理
ACP IDE 与 AI 助手 实时交互、文件操作、会话管理 将 AI 智能体变为可治理、可观察的工程对象,统一管理本地与远程助手,提升研发效率与工具灵活性
A2A Agent 之间 分布式协作、异步任务 构建企业级智能网络,实现跨团队、跨组织的 Agent 调度与能力互用,支持长周期任务与 Agent Marketplace

MCP / Skill:模块化企业能力

在 AutoDev 实践中,通过 MCP,Agent 能访问企业内部能力,例如数据库、API、代码索引和自研业务 Skill。企业可以将业务知识和 AI 能力模块化,形成可复用、可管理的能力库。

核心价值:

  • 企业级能力复用,避免每个项目重复集成 AI 助手能力
  • 精细化权限管理,确保 AI 访问企业资源可控
  • 支持版本迭代,保证团队使用一致且稳定的能力模块

ACP:可控的人机交互层

通过 ACP 协议,企业可以让 IDE 与多 AI 助手之间实现透明、可观察、可控的交互。

实践经验(AutoDev):

  • 双向 ACP:AutoDev 可作为 ACP 客户端,也可作为服务端
  • 统一渲染层:不同助手的事件通过统一接口分发,实现“一次编写,多端渲染”
  • 非 ACP 助手适配:如 Claude Code,通过协议适配层接入 ACP 架构

企业价值:

  • 多助手协作无缝,提升研发效率
  • 操作和修改可追踪,满足安全和合规要求
  • 会话持久化,支持长任务和上下文延续

A2A:智能体协作网络

单个 AI 助手无法覆盖所有任务。通过 A2A(Agent-to-Agent Protocol),企业可以构建跨团队、跨项目的智能任务网络:

功能亮点:

  • 并行执行:多个 Agent 可同时处理不同任务
  • 任务拆分与协作:如 Augment Intent,Coordinator Agent 拆分任务,Specialist Agent 各司其职
  • 产出物管理:Agent 完成任务生成可视化产出(Diff、截图、录屏),便于审查与迭代

企业价值:

  • 支撑长周期任务和跨团队协作
  • 不同模型或 Agent 可组合使用,实现最佳方案选择(Best-of-N)
  • 构建企业级 Agent Marketplace,实现能力共享

总结:三层协议的协同价值

通过 MCP / Skill、ACP 和 A2A 三层结合,企业 AI 平台不再是“工具堆叠”,而是可管理、可复用、可扩展的研发生产力基础设施:

  • 研发效率提升:ACP 保证开发者桌面与 IDE 内多助手协作顺畅
  • 企业级能力复用:MCP / Skill 模块化企业知识和能力,实现团队复用和权限控制
  • 跨团队智能协作:A2A 支持长周期、跨项目任务的智能 Agent 网络
  • 统一治理与监控:三层协议结合,实现权限、日志、审计和安全策略统一管理

这种三层体系,让企业 AI 平台真正成为可扩展、可观测、可治理的生产力平台,而不仅仅是工具的简单叠加。

ACP 协议正在成为多智能体时代的关键基础设施。它解决了一个核心问题:如何让多个 AI 助手在同一开发环境中协同工作,同时保持可控、可观测、可治理。

核心要点:

  • ACP 定义了标准化的人机交互协议,让 IDE 能够统一管理来自不同 AI 助手的操作请求,实现“一次集成,多端协作

  • 双向 ACP 架构(如 AutoDev 实践)既支持作为客户端调用外部 Agent,也支持作为服务端被其他工具调用

  • 与 MCP、A2A 形成三层协议体系:

    • MCP 提供能力模块化
    • ACP 管理人机交互
    • A2A 实现智能体间协作
  • 企业级治理成为可能:统一的协议层让权限控制、操作审计、安全策略得以落地

随着 JetBrains、Augment、Google 等厂商的积极布局,ACP 生态正在快速成熟。对于企业而言,现在是构建多智能体研发平台的最佳时机。

参考链接:

[1] Agent Client Protocol 官网: https://agentclientprotocol.com/

[2] ACP GitHub 仓库: https://github.com/agentclientprotocol/agent-client-protocol

[3] Model Context Protocol: https://modelcontextprotocol.io/

[4] A2A Protocol: https://a2a-protocol.org/

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐