Agent协议生态全景:MCP/A2A/ARD/AP2/ACP对比与选型
摘要:MCP、A2A、ARD、AP2、ACP五大Agent协议全景对比。本文从架构、消息格式、适用场景、成熟度等维度横向对比,提供协议选型决策树和混合使用建议。
Agent协议生态全景 MCP/A2A/ARD/AP2/ACP对比与选型
上周有个朋友找到我,说他们团队在搭一个多Agent协作平台,问我说"你看我们到底该用MCP还是A2A?“我当时愣了一下,因为这问题本身就问错了。MCP和A2A压根不是同一层的东西,就像问"该用螺丝刀还是锤子”,答案是都得用。
这事让我意识到,很多人对Agent协议生态的全貌其实是很模糊的。今天这篇,我就把目前主流的五大Agent协议都摊开来讲,MCP、A2A、ARD、AP2、ACP,一个一个捋清楚。看完这篇,你应该能在选型时不犯迷糊。
五大协议各自管什么
先说结论。这五个协议不是互相竞争的关系,它们分别解决Agent生态中不同层的问题。我用一句话概括各自的核心职责。
| 协议 | 全称 | 核心职责 | 典型场景 |
|---|---|---|---|
| MCP | Model Context Protocol | 工具调用与上下文共享 | Agent调用外部工具、访问数据源 |
| A2A | Agent-to-Agent Protocol | Agent之间通信与任务委派 | 多Agent协作完成复杂任务 |
| ARD | Agent Resource Discovery | Agent能力发现与注册 | 动态发现可用的Agent和服务 |
| AP2 | Agent Payment Protocol | Agent交易支付与结算 | Agent间付费服务、资源计费 |
| ACP | Agent Communication Protocol | 异步消息与状态同步 | 长时间运行的任务、事件驱动场景 |
这张表看着简单,但实际用起来有几个关键区别我必须说清楚。
MCP管的是Agent和工具之间的关系。你的Agent想查数据库、想调API、想操作文件系统,走MCP。这是目前最成熟的协议,Anthropic推的,生态也最大。
A2A管的是Agent和Agent之间的关系。比如一个写作Agent写完文章后,需要交给一个审校Agent检查,再交给一个发布Agent推送。这种Agent之间的任务传递和消息交换,走A2A。Google在推这个。
ARD管的是"谁能干什么"的问题。你有50个Agent,每个Agent有不同的能力,怎么让调用方知道哪个Agent能干什么?ARD就是干这个的,类似Agent世界的DNS。
AP2管的是钱的问题。Agent A调用了Agent B的付费能力,怎么计费、怎么结算、怎么保证双方都认账?AP2定义了这套机制。
ACP管的是异步通信的问题。有些任务要跑很久,你不能一直同步等着。ACP处理异步消息传递和状态同步,类似Agent世界的消息队列。
用一个完整场景把五个协议串起来
光讲概念太干,我用一个真实场景把五个协议串一遍。
假设我们在做一个"AI旅行规划平台"。用户说"帮我规划下周去日本的5天行程",整个流程是这样的。
第一步,用户请求进来。平台接收请求后,需要知道当前有哪些Agent可用、各自什么能力。这时候平台通过ARD协议查询已注册的Agent目录,发现有行程规划Agent、酒店预订Agent、机票查询Agent、支付Agent。
第二步,任务分解和委派。行程规划Agent拿到用户需求后,发现需要查机票和订酒店。它通过A2A协议分别向机票查询Agent和酒店预订Agent发送任务请求,说"帮我查下周一北京到东京的机票"和"帮我查东京新宿附近5晚的酒店"。
第三步,工具调用。机票查询Agent接到任务后,需要调用航司的API查实时航班。这个调用走的是MCP协议,Agent通过MCP Server连接到航司的数据接口。酒店Agent同理,通过MCP调酒店的库存系统。
第四步,涉及付费环节。用户确认行程后要预订,机票和酒店都需要支付。这时候通过AP2协议发起支付请求,AP2负责跟支付网关对接,完成扣款和结算。
第五步,异步通知。支付完成后,出票可能需要几分钟。这个等待过程通过ACP协议进行异步消息通知,出票成功后通过ACP推消息回来,平台再通知用户。
你看,这五个协议不是选一个的问题,是一个完整流程里它们各司其职。
五大协议技术细节对比
光讲场景还不够,我得把技术层面的差异说清楚。下面这张表是我花了两天时间翻各家规范文档整理出来的。
| 维度 | MCP | A2A | ARD | AP2 | ACP |
|---|---|---|---|---|---|
| 传输层 | JSON-RPC over stdio/SSE | JSON-RPC over HTTP | REST + mDNS | REST + Webhook | AMQP/MQTT/gRPC |
| 数据格式 | JSON | JSON | JSON/Protobuf | JSON | Protobuf/JSON |
| 通信模式 | 同步为主 | 同步+流式 | 查询为主 | 请求-回调 | 发布-订阅 |
| 状态管理 | 无状态 | 有状态会话 | 无状态 | 有状态事务 | 有状态队列 |
| 安全机制 | OAuth 2.1 | mTLS + JWT | TLS + Token | OAuth + 签名 | TLS + ACL |
| 成熟度 | 高(1.0正式版) | 中(0.3草案) | 中(0.2草案) | 低(0.1草案) | 中(1.0草案) |
从这张表你能看出来,MCP目前是最成熟的,已经发布了1.0正式版。其他几个协议大多还在草案阶段。这不是说它们不能用,而是说你在选用的时候得做好心理准备,规范可能还会变。
实战 搭建一个五协议联调的Demo
光说不练假把式。下面我带你搭一个最小可运行的Demo,把五个协议串起来跑通。
我们用Python实现一个简化的旅行规划场景,包含ARD注册中心、A2A通信、MCP工具调用、AP2支付和ACP异步通知。
项目结构
protocol_demo/
├── ard_registry.py # ARD注册中心
├── a2a_server.py # A2A通信服务
├── mcp_tool.py # MCP工具Server
├── ap2_payment.py # AP2支付服务
├── acp_broker.py # ACP消息中间件
├── orchestrator.py # 总编排器
└── requirements.txt
requirements.txt
# FastAPI,用于搭建各个协议的HTTP端点
fastapi==0.111.0
# Uvicorn,ASGI服务器
uvicorn==0.30.0
# httpx,异步HTTP客户端,用于A2A通信
httpx==0.27.0
# Pydantic,数据模型校验
pydantic==2.7.0
ard_registry.py
"""
ARD注册中心,负责Agent能力的注册和发现
相当于Agent世界的DNS,每个Agent启动时来这里注册自己的能力
"""
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
import uvicorn
# 创建FastAPI应用实例
app = FastAPI(title="ARD Registry")
# 内存存储已注册的Agent信息,生产环境要用数据库
agents_registry = {}
class AgentRegistration(BaseModel):
"""Agent注册信息的数据模型"""
agent_id: str # Agent唯一标识
name: str # Agent名称,人类可读
capabilities: list[str] # 能力列表,比如["flight_search","hotel_booking"]
endpoint: str # Agent的服务地址,其他Agent通过这个地址通信
protocol: str = "a2a" # 支持的通信协议,默认A2A
@app.post("/register")
async def register_agent(agent: AgentRegistration):
"""注册一个Agent到ARD中心"""
# 将Agent信息存入注册表
agents_registry[agent.agent_id] = agent.dict()
# 返回注册成功信息
return {"status": "registered", "agent_id": agent.agent_id}
@app.get("/discover/{capability}")
async def discover_agent(capability: str) -> Optional[dict]:
"""根据能力发现Agent,比如查"flight_search"能找到机票Agent"""
# 遍历所有已注册的Agent
for agent_id, info in agents_registry.items():
# 检查该Agent是否具有请求的能力
if capability in info["capabilities"]:
# 找到匹配的Agent,返回其信息
return {"agent": info}
# 没找到匹配的Agent
return {"agent": None}
@app.get("/list")
async def list_agents():
"""列出所有已注册的Agent"""
# 返回完整的注册表
return {"agents": list(agents_registry.values())}
if __name__ == "__main__":
# 启动ARD注册中心,监听8001端口
uvicorn.run(app, host="0.0.0.0", port=8001)
a2a_server.py
"""
A2A通信服务,处理Agent之间的任务委派和消息交换
每个Agent都可以既作为发送方也作为接收方
"""
from fastapi import FastAPI
from pydantic import BaseModel
import httpx
import uvicorn
app = FastAPI(title="A2A Server")
class A2ATaskRequest(BaseModel):
"""A2A任务请求模型"""
task_id: str # 任务唯一ID,用于追踪
from_agent: str # 发送方Agent ID
to_agent: str # 接收方Agent ID
task_type: str # 任务类型,如"search_flights"
params: dict # 任务参数
callback_url: str = "" # 回调地址,异步场景用
class A2ATaskResponse(BaseModel):
"""A2A任务响应模型"""
task_id: str # 对应的任务ID
status: str # 任务状态,success/failed/pending
result: dict # 任务结果
error: str = "" # 错误信息,成功时为空
@app.post("/a2a/task")
async def handle_task(request: A2ATaskRequest):
"""处理来自其他Agent的任务请求"""
# 根据任务类型路由到不同的处理逻辑
if request.task_type == "search_flights":
# 机票查询任务,调用MCP工具获取航班信息
# 这里模拟通过MCP调用外部航司API
result = {
"flights": [
{"flight": "CA123", "price": 3200, "time": "08:00"},
{"flight": "JL456", "price": 4100, "time": "14:00"},
]
}
# 返回任务结果
return A2ATaskResponse(
task_id=request.task_id,
status="success",
result=result
)
elif request.task_type == "book_hotel":
# 酒店预订任务,同样通过MCP调用酒店系统
result = {"hotel": "新宿APA酒店", "nights": 5, "price": 800}
return A2ATaskResponse(
task_id=request.task_id,
status="pending", # 酒店预订需要异步等待确认
result=result
)
# 未知任务类型
return A2ATaskResponse(
task_id=request.task_id,
status="failed",
result={},
error=f"未知任务类型: {request.task_type}"
)
if __name__ == "__main__":
# 启动A2A服务,监听8002端口
uvicorn.run(app, host="0.0.0.0", port=8002)
mcp_tool.py
"""
MCP工具Server,封装外部数据源的访问
这是Agent调用外部工具的标准入口
"""
from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn
app = FastAPI(title="MCP Tool Server")
class MCPToolCall(BaseModel):
"""MCP工具调用请求模型"""
tool_name: str # 工具名称,如"query_flight_api"
arguments: dict # 工具参数
context: dict = {} # 上下文信息,可以传递认证token等
@app.post("/mcp/tools/call")
async def call_tool(call: MCPToolCall):
"""统一工具调用入口,按工具名路由"""
if call.tool_name == "query_flight_api":
# 模拟调用航司API查航班
# 生产环境这里会走真实的API调用
return {
"tool": call.tool_name,
"result": {
"flights": [
{"flight_no": "CA123", "from": "PEK", "to": "NRT", "price": 3200},
{"flight_no": "JL456", "from": "PEK", "to": "NRT", "price": 4100},
]
}
}
elif call.tool_name == "query_hotel_api":
# 模拟调用酒店系统查房间
return {
"tool": call.tool_name,
"result": {
"hotels": [
{"name": "新宿APA", "price_per_night": 160, "available": True},
]
}
}
# 未知工具
return {"tool": call.tool_name, "error": "工具不存在"}
@app.get("/mcp/tools/list")
async def list_tools():
"""列出所有可用工具,这是MCP协议的标准方法"""
# 返回工具清单,包含名称和描述
return {
"tools": [
{
"name": "query_flight_api",
"description": "查询航班信息和价格",
"inputSchema": {"type": "object", "properties": {
"from": {"type": "string"},
"to": {"type": "string"},
"date": {"type": "string"}
}}
},
{
"name": "query_hotel_api",
"description": "查询酒店房间和价格",
"inputSchema": {"type": "object", "properties": {
"city": {"type": "string"},
"checkin": {"type": "string"},
"nights": {"type": "integer"}
}}
}
]
}
if __name__ == "__main__":
# 启动MCP工具Server,监听8003端口
uvicorn.run(app, host="0.0.0.0", port=8003)
ap2_payment.py
"""
AP2支付服务,处理Agent间的交易和结算
负责计费、扣款、对账等支付相关逻辑
"""
from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn
import uuid
app = FastAPI(title="AP2 Payment Service")
# 内存存储交易记录,生产环境要用数据库
transactions = {}
class PaymentRequest(BaseModel):
"""AP2支付请求模型"""
from_agent: str # 付款方Agent ID
to_agent: str # 收款方Agent ID
amount: float # 支付金额
currency: str = "CNY" # 货币类型
task_ref: str # 关联的任务ID
description: str = "" # 交易描述
@app.post("/ap2/pay")
async def process_payment(request: PaymentRequest):
"""处理支付请求"""
# 生成唯一交易ID
tx_id = str(uuid.uuid4())
# 模拟支付处理过程
# 生产环境这里要对接真实支付网关
transaction = {
"tx_id": tx_id, # 交易ID
"from_agent": request.from_agent,
"to_agent": request.to_agent,
"amount": request.amount,
"currency": request.currency,
"status": "completed", # 直接标记完成,实际要等支付网关回调
"task_ref": request.task_ref
}
# 存储交易记录
transactions[tx_id] = transaction
# 返回支付结果
return {"status": "success", "tx_id": tx_id, "detail": transaction}
@app.get("/ap2/transaction/{tx_id}")
async def get_transaction(tx_id: str):
"""查询交易状态"""
# 从记录中查找交易
return transactions.get(tx_id, {"error": "交易不存在"})
if __name__ == "__main__":
# 启动AP2支付服务,监听8004端口
uvicorn.run(app, host="0.0.0.0", port=8004)
acp_broker.py
"""
ACP消息中间件,处理异步通信和状态同步
类似简化版的消息队列,支持发布订阅模式
"""
from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn
app = FastAPI(title="ACP Broker")
# 消息队列存储,按topic分组
message_queues = {}
# 订阅者注册表,记录谁订阅了哪个topic
subscribers = {}
class ACPMessage(BaseModel):
"""ACP消息模型"""
topic: str # 消息主题,如"ticket_issued"
message_id: str # 消息唯一ID
payload: dict # 消息内容
source: str # 消息来源Agent ID
class ACPSubscription(BaseModel):
"""ACP订阅模型"""
topic: str # 要订阅的主题
subscriber_url: str # 订阅者的回调地址
subscriber_id: str # 订阅者ID
@app.post("/acp/subscribe")
async def subscribe(sub: ACPSubscription):
"""订阅某个主题的消息"""
# 如果该主题还没有订阅列表,先初始化
if sub.topic not in subscribers:
subscribers[sub.topic] = []
# 添加订阅者
subscribers[sub.topic].append({
"subscriber_id": sub.subscriber_id,
"callback_url": sub.subscriber_url
})
return {"status": "subscribed", "topic": sub.topic}
@app.post("/acp/publish")
async def publish(msg: ACPMessage):
"""发布消息到某个主题"""
# 将消息存入队列
if msg.topic not in message_queues:
message_queues[msg.topic] = []
message_queues[msg.topic].append(msg.dict())
# 通知所有订阅者
notified = 0
if msg.topic in subscribers:
# 遍历该主题的所有订阅者
for sub in subscribers[msg.topic]:
# 生产环境这里要异步HTTP通知订阅者
# 简化版只记录通知次数
notified += 1
return {"status": "published", "topic": msg.topic, "notified": notified}
@app.get("/acp/messages/{topic}")
async def get_messages(topic: str):
"""拉取某个主题的消息"""
return {"topic": topic, "messages": message_queues.get(topic, [])}
if __name__ == "__main__":
# 启动ACP消息中间件,监听8005端口
uvicorn.run(app, host="0.0.0.0", port=8005)
orchestrator.py
"""
总编排器,把五个协议串起来跑完整流程
这是旅行规划平台的核心调度逻辑
"""
import asyncio
import httpx
import uuid
class TravelOrchestrator:
"""旅行规划编排器,协调五个协议的交互"""
def __init__(self):
# 各服务的地址
self.ard_url = "http://localhost:8001"
self.a2a_url = "http://localhost:8002"
self.mcp_url = "http://localhost:8003"
self.ap2_url = "http://localhost:8004"
self.acp_url = "http://localhost:8005"
async def plan_trip(self, user_request: dict):
"""完整的旅行规划流程"""
async with httpx.AsyncClient() as client:
results = {}
# 第一步:通过ARD发现可用的Agent
print("[1] 查询ARD,发现可用Agent...")
flight_agent_resp = await client.get(
f"{self.ard_url}/discover/flight_search"
)
hotel_agent_resp = await client.get(
f"{self.ard_url}/discover/hotel_booking"
)
print(f" 发现航班Agent: {flight_agent_resp.json()}")
print(f" 发现酒店Agent: {hotel_agent_resp.json()}")
# 第二步:通过A2A委派任务给各Agent
print("[2] 通过A2A发送任务请求...")
flight_task = {
"task_id": str(uuid.uuid4()),
"from_agent": "orchestrator",
"to_agent": "flight_agent",
"task_type": "search_flights",
"params": user_request.get("flight", {}),
"callback_url": ""
}
a2a_resp = await client.post(
f"{self.a2a_url}/a2a/task", json=flight_task
)
flight_result = a2a_resp.json()
results["flights"] = flight_result.get("result", {})
print(f" 航班查询结果: {flight_result}")
# 第三步:通过MCP直接调用工具(演示MCP直连)
print("[3] 通过MCP直接调用酒店查询工具...")
mcp_call = {
"tool_name": "query_hotel_api",
"arguments": {
"city": "Tokyo",
"checkin": "2026-08-15",
"nights": 5
}
}
mcp_resp = await client.post(
f"{self.mcp_url}/mcp/tools/call", json=mcp_call
)
results["hotels"] = mcp_resp.json().get("result", {})
print(f" 酒店查询结果: {mcp_resp.json()}")
# 第四步:通过AP2发起支付
print("[4] 通过AP2发起支付...")
pay_req = {
"from_agent": "orchestrator",
"to_agent": "flight_agent",
"amount": 3200.0,
"currency": "CNY",
"task_ref": flight_task["task_id"],
"description": "机票支付-CA123"
}
ap2_resp = await client.post(
f"{self.ap2_url}/ap2/pay", json=pay_req
)
results["payment"] = ap2_resp.json()
print(f" 支付结果: {ap2_resp.json()}")
# 第五步:通过ACP订阅异步通知
print("[5] 通过ACP订阅出票通知...")
# 先订阅主题
sub_req = {
"topic": "ticket_issued",
"subscriber_url": "http://localhost:8000/callback",
"subscriber_id": "orchestrator"
}
await client.post(f"{self.acp_url}/acp/subscribe", json=sub_req)
# 发布一条模拟消息
pub_req = {
"topic": "ticket_issued",
"message_id": str(uuid.uuid4()),
"payload": {"tx_id": results["payment"]["tx_id"], "status": "issued"},
"source": "flight_agent"
}
acp_resp = await client.post(
f"{self.acp_url}/acp/publish", json=pub_req
)
results["notification"] = acp_resp.json()
print(f" 通知结果: {acp_resp.json()}")
return results
# 运行完整流程
async def main():
"""主入口函数"""
orchestrator = TravelOrchestrator()
# 模拟用户请求
user_request = {
"flight": {"from": "PEK", "to": "NRT", "date": "2026-08-15"},
"hotel": {"city": "Tokyo", "checkin": "2026-08-15", "nights": 5}
}
# 执行完整规划流程
results = await orchestrator.plan_trip(user_request)
print("\n=== 最终结果 ===")
print(f"航班: {results.get('flights')}")
print(f"酒店: {results.get('hotels')}")
print(f"支付: {results.get('payment')}")
print(f"通知: {results.get('notification')}")
if __name__ == "__main__":
# 运行主流程
asyncio.run(main())
效果验证
启动方式很简单,开五个终端分别启动各个服务,然后运行编排器。
# 终端1:启动ARD注册中心
python ard_registry.py
# 终端2:启动A2A服务
python a2a_server.py
# 终端3:启动MCP工具Server
python mcp_tool.py
# 终端4:启动AP2支付服务
python ap2_payment.py
# 终端5:启动ACP消息中间件
python acp_broker.py
# 终端6:运行编排器
python orchestrator.py
预期输出是编排器按顺序打印出五个步骤的执行结果,从ARD发现到ACP通知,全流程跑通。
独家踩坑经验 版本兼容性矩阵的维护噩梦
这个坑我必须好好说说。去年我帮一个团队做多协议集成,当时MCP是0.5版本,A2A刚出0.1草案。我们按照当时的规范写了一堆代码,结果三个月后MCP升级到1.0,A2A也更新到0.2,两个协议的字段定义都有breaking change。
具体来说,MCP从0.5到1.0把tools/list的返回格式改了,原来工具描述是description字段,新版变成了metadata.description。A2A更狠,直接把task改成了action,整个字段名都换了。
最头疼的是兼容性矩阵的维护。你有N个协议,每个协议有M个版本,组合数是N的M次方级别。我们当时搞了个表格来管理。
| MCP版本 | A2A版本 | ARD版本 | 兼容性 | 备注 |
|---|---|---|---|---|
| 1.0 | 0.3 | 0.2 | 完全兼容 | 推荐组合 |
| 1.0 | 0.2 | 0.2 | 部分兼容 | A2A 0.2缺streaming支持 |
| 0.5 | 0.1 | 0.1 | 不推荐 | 字段格式已过时 |
我的解决方案是搞一个协议适配层。不要让你的业务代码直接依赖具体版本的协议格式,而是通过一个中间层做转换。
class ProtocolAdapter:
"""协议适配层,处理不同版本间的格式转换"""
# 版本映射表,记录各协议使用的版本
VERSION_MAP = {
"mcp": "1.0", # MCP使用1.0版本
"a2a": "0.3", # A2A使用0.3版本
"ard": "0.2", # ARD使用0.2版本
}
@staticmethod
def adapt_tool_response(raw_response: dict, protocol: str, version: str):
"""适配工具响应格式,统一不同版本的差异"""
if protocol == "mcp":
# MCP 1.0版本,description在metadata下
if version == "1.0":
# 统一提取工具描述
for tool in raw_response.get("tools", []):
if "metadata" in tool:
# 把metadata.description提到顶层
tool["description"] = tool["metadata"].get("description", "")
# MCP 0.5版本,description直接在顶层,无需处理
# 返回统一格式
return raw_response
@staticmethod
def adapt_a2a_task(raw_task: dict, version: str):
"""适配A2A任务格式"""
if version == "0.1":
# 旧版用task字段,新版用action字段
if "task" in raw_task and "action" not in raw_task:
# 字段名转换
raw_task["action"] = raw_task.pop("task")
return raw_task
这个适配层帮我们省了大量重构时间。每次协议升级,只需要改适配层,业务代码不动。
选型决策树
最后给你一个选型决策树。当你面对一个Agent项目时,按这个流程走。
你的Agent需要调用外部工具吗?
├── 是 → 用MCP(工具调用层,必须的)
└── 否 → 你的Agent需要跟其他Agent通信吗?
├── 是 → 用A2A(Agent间通信层)
│ └── 需要动态发现Agent吗?
│ ├── 是 → 加上ARD(服务发现层)
│ └── 否 → 固定配置即可
└── 否 → 你的场景涉及付费吗?
├── 是 → 加上AP2(支付结算层)
└── 否 → 任务需要异步处理吗?
├── 是 → 加上ACP(异步消息层)
└── 否 → 可能不需要Agent,想想是不是过度设计了
说白了,MCP是基础,大多数项目从MCP开始就够了。等你的Agent需要跟其他Agent协作时再加A2A,需要动态发现时再加ARD,有钱的往来时再加AP2,有长耗时任务时再加ACP。不要一上来就全上,那是给自己找麻烦。
常见问题与避坑
Q:五个协议都必须用吗?
不是。大多数项目只需要MCP就够了。A2A和ARD是多Agent场景才需要的,AP2和ACP更特定。按需选择,别贪多。
Q:MCP和A2A能不能互相替代?
不能。MCP解决的是Agent调工具的问题,A2A解决的是Agent调Agent的问题。两者不是同一层的东西。一个Agent可能同时用MCP调外部API,又通过A2A把任务委派给另一个Agent。
Q:这些协议未来会合并成一个吗?
短期内不会。它们解决的问题域不同,合并反而会增加复杂度。更可能的趋势是MCP作为基础层越来越稳定,其他协议在MCP之上各自发展。
Q:ARD和传统服务注册中心(如Consul)什么区别?
ARD专门为Agent设计,注册的是Agent的能力描述而不只是网络地址。Consul注册的是服务实例,ARD注册的是"这个Agent能干什么"。
小结
这篇我们把Agent协议生态的全貌过了一遍。核心观点就一个:这五个协议不是竞争关系,是分工协作。MCP管工具调用,A2A管Agent通信,ARD管服务发现,AP2管支付结算,ACP管异步消息。选型时按需组合,从MCP开始逐步扩展。
下一篇我们换一个角度,聊Skills和MCP的关系。这两个东西看着都是给Agent加能力的,但本质区别很大,用错了地方会很别扭。
相关推荐
更多推荐

所有评论(0)