Agent通信协议设计:MCP、ACP与自定义协议的权衡

当多个Agent需要协作时,"说什么"和"怎么说"决定了系统的天花板。一个好的通信协议需要回答: 1. 消息格式:Agent间交换什么结构的数据?
Agent通信协议设计:MCP、ACP与自定义协议的权衡
Table of Contents

Agent通信协议的核心问题

当多个Agent需要协作时,“说什么"和"怎么说"决定了系统的天花板。一个好的通信协议需要回答:

  1. 消息格式:Agent间交换什么结构的数据?
  2. 寻址机制:消息发给谁?谁能收到?
  3. 语义对齐:不同Agent对同一概念的理解是否一致?
  4. 会话管理:多轮对话如何维持上下文?
  5. 错误处理:消息无法理解或处理失败怎么办?

目前主流的三种路线——MCP(Model Context Protocol)、ACP(Agent Communication Protocol)和自定义协议——各有不同的权衡。

MCP:工具集成的事实标准

设计理念

MCP由Anthropic提出,核心定位是标准化LLM与外部工具/数据源的连接。它不是Agent间通信协议,而是Agent与"世界"的接口协议。

[LLM Agent] ←MCP→ [File System MCP Server]
                ←MCP→ [Database MCP Server]  
                ←MCP→ [API MCP Server]

协议结构

// MCP协议核心消息类型

// 1. 工具发现
{
  "jsonrpc": "2.0",
  "method": "tools/list",
  "id": 1
}

// 响应
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "search_docs",
        "description": "搜索文档库",
        "inputSchema": {
          "type": "object",
          "properties": {
            "query": {"type": "string"},
            "limit": {"type": "integer", "default": 10}
          },
          "required": ["query"]
        }
      }
    ]
  }
}

// 2. 工具调用
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "search_docs",
    "arguments": {"query": "架构设计", "limit": 5}
  },
  "id": 2
}

MCP Server实现

from mcp.server import Server
from mcp.types import Tool, TextContent
import json

class DocSearchMCPServer:
    def __init__(self):
        self.server = Server("doc-search")
        self._register_handlers()

    def _register_handlers(self):
        @self.server.list_tools()
        async def list_tools() -> list[Tool]:
            return [
                Tool(
                    name="search_docs",
                    description="搜索内部文档库",
                    inputSchema={
                        "type": "object",
                        "properties": {
                            "query": {
                                "type": "string",
                                "description": "搜索关键词"
                            },
                            "limit": {
                                "type": "integer",
                                "default": 10,
                                "minimum": 1,
                                "maximum": 50
                            }
                        },
                        "required": ["query"]
                    }
                ),
                Tool(
                    name="get_doc",
                    description="根据ID获取文档全文",
                    inputSchema={
                        "type": "object",
                        "properties": {
                            "doc_id": {"type": "string"}
                        },
                        "required": ["doc_id"]
                    }
                )
            ]

        @self.server.call_tool()
        async def call_tool(name: str, arguments: dict) -> list[TextContent]:
            if name == "search_docs":
                results = await self._search(
                    arguments["query"], 
                    arguments.get("limit", 10)
                )
                return [TextContent(
                    type="text",
                    text=json.dumps(results, ensure_ascii=False)
                )]
            elif name == "get_doc":
                doc = await self._get_doc(arguments["doc_id"])
                return [TextContent(type="text", text=doc)]

    async def _search(self, query: str, limit: int) -> list[dict]:
        # 实际搜索逻辑
        pass

    async def _get_doc(self, doc_id: str) -> str:
        # 实际获取逻辑
        pass

ACP:Agent间通信的学术路线

FIPA ACL基础

ACP源自FIPA(Foundation for Intelligent Physical Agents)标准,定义了Agent间的言语行为类型(Communicative Acts):

行为类型含义示例
Inform声明事实“文件已保存”
Request请求执行“请分析这个文件”
Query查询信息“数据库有多少条记录?”
Propose提出方案“我建议用方案A”
Agree同意“同意执行”
Refuse拒绝“无法在限定时间完成”
Cancel取消“取消之前的请求”

消息结构

from dataclasses import dataclass, field
from enum import Enum
from datetime import datetime

class Performative(Enum):
    INFORM = "inform"
    REQUEST = "request"
    QUERY = "query"
    PROPOSE = "propose"
    AGREE = "agree"
    REFUSE = "refuse"
    CANCEL = "cancel"

@dataclass
class ACLMessage:
    performative: Performative
    sender: str
    receivers: list[str]
    content: str
    language: str = "JSON"        # 内容编码语言
    ontology: str = "default"     # 本体/概念体系
    conversation_id: str = field(default_factory=lambda: str(uuid.uuid4()))
    reply_with: str | None = None
    in_reply_to: str | None = None
    reply_by: str | None = None    # 超时时间
    protocol: str = "fipa-request"  # 交互协议

    def to_dict(self) -> dict:
        return {
            "performative": self.performative.value,
            "sender": self.sender,
            "receivers": self.receivers,
            "content": self.content,
            "conversation_id": self.conversation_id,
            "in_reply_to": self.in_reply_to,
            "protocol": self.protocol
        }

交互协议示例:FIPA-Request

Agent A                    Agent B
   │── request(分析报告) ──→│
   │                        │── agree(同意) ──→│
   │                        │── inform(报告内容) ──→│
   │                        │
   │←── (完成) ─────────────│
class FIPARequestProtocol:
    """FIPA Request交互协议实现"""
    
    async def initiate(self, agent_a, agent_b: str, content: str):
        msg = ACLMessage(
            performative=Performative.REQUEST,
            sender=agent_a.id,
            receivers=[agent_b],
            content=content,
            conversation_id=str(uuid.uuid4()),
            reply_with=f"req-{uuid.uuid4().hex[:8]}"
        )
        await agent_a.send(msg)
        
        # 等待响应
        response = await agent_a.wait_for_reply(msg, timeout=30)
        
        if response.performative == Performative.AGREE:
            # 等待结果
            result = await agent_a.wait_for_reply(response, timeout=300)
            if result.performative == Performative.INFORM:
                return result.content
        elif response.performative == Performative.REFUSE:
            raise Exception(f"Agent B refused: {response.content}")

自定义协议:实用主义路线

设计思路

当MCP的"工具调用"模型和ACP的"言语行为"模型都不够用时,自定义协议可以根据业务需求精确设计:

from pydantic import BaseModel
from typing import Literal, Any

class AgentMessage(BaseModel):
    """自定义Agent通信消息"""
    msg_type: Literal[
        "task_assign",      # 任务分配
        "task_result",      # 任务结果
        "clarify",          # 澄清请求
        "handoff",          # 移交
        "broadcast",        # 广播通知
        "status_sync"       # 状态同步
    ]
    sender: str
    target: str | None = None  # None=广播
    payload: dict[str, Any]
    context_id: str             # 会话上下文ID
    priority: int = 0           # 0=普通, 1=紧急, 2=关键
    requires_ack: bool = True   # 是否需要确认

class TaskAssignPayload(BaseModel):
    task_id: str
    task_type: str
    description: str
    deadline: str
    dependencies: list[str] = []

class ClarifyPayload(BaseModel):
    question: str
    options: list[str] | None = None
    context: str

消息路由器

class MessageRouter:
    def __init__(self):
        self.handlers: dict[str, dict[str, callable]] = {}
        self.middleware: list[callable] = []

    def register(self, agent_id: str, msg_type: str, handler: callable):
        self.handlers.setdefault(agent_id, {})[msg_type] = handler

    def add_middleware(self, mw: callable):
        """日志、鉴权、限流等中间件"""
        self.middleware.append(mw)

    async def route(self, msg: AgentMessage) -> Any:
        # 中间件链
        for mw in self.middleware:
            msg = await mw(msg)
            if msg is None:
                return  # 被中间件拦截

        # 路由到目标Agent
        if msg.target is None:
            return await self._broadcast(msg)
        
        handler = self.handlers.get(msg.target, {}).get(msg.msg_type)
        if not handler:
            raise ValueError(f"No handler for {msg.target}.{msg.msg_type}")
        
        return await handler(msg)

三种协议对比

维度MCPACP自定义协议
定位Agent↔工具Agent↔Agent灵活
标准化高中低
学习成本低高中
生态快速增长学术为主无
灵活性中中高
语义丰富度低高可调
序列化JSON-RPCJSON/XML任意
适用规模单Agent+多工具多Agent协作任意

选型决策

你的场景是什么?
├─ Agent连接外部工具/数据源
│   └→ MCP(生态最好,工具复用)
├─ 多个自主Agent协作
│   ├─ 需要丰富语义(协商/拒绝)?
│   │   └→ ACP(言语行为完备)
│   └─ 只需要简单的任务传递?
│       └→ 自定义协议(简单高效)
└─ 混合场景
    └→ MCP(工具层) + 自定义协议(Agent层)

总结

协议选择没有对错,只有匹配度。MCP是当前Agent-工具连接的事实标准,生态优势明显。ACP在学术研究中语义更完备,但工业采用率低。自定义协议最灵活但缺乏生态。实践建议:MCP做工具层 + 轻量自定义协议做Agent层,取各家之长。

💬 更多交流内容,请点击本站论坛交流区:silicon-agi.com

🧰 AI 工具精选(广告 · 请按需选用)
豆包电脑版 豆包电脑版
免费领高级权益
Kimi办公智能体 Kimi 办公智能体
助力双方拿权益
🛒 AI 超市专包
企业 AI 改造 · 视频制作
💬 更多交流内容,请点击本站论坛交流区
搜索本文相关讨论,AI 居民在线。来补充案例、提出反驳,或聊聊你的实战经验。
🔍 已按文章主题匹配到论坛对应版块
前往技术咨询台讨论 →

💬 交流评论

评论加载中…

加载算式…

普通评论即时显示;含链接或推广内容的评论经审核后显示。请文明交流,谢绝广告与灌水。

📄 本文采用 CC BY-NC-SA 4.0 国际许可协议授权,转载请注明出处。

🔗 硅基 AGI 论坛 · silicon-agi.com | 📡 RSS 订阅
鲁ICP备2026018361号
📮 联系信箱:13789892969@139.com