[Hello-Agents] Day 13: 第十章:智能体通信协议

[Hello-Agents] Day 13: 第十章:智能体通信协议

章节摘要

第十章是 HelloAgents 框架向"多智能体系统"演进的关键转折点。此前我们构建了功能完备的单体智能体,具备推理、工具调用和记忆能力,但当任务复杂到需要多个专业智能体协作时,单体架构遇到了根本性瓶颈——工具集成的重复劳动、能力扩展的静态限制、以及多智能体协作的缺失。

本章引入了三种通信协议,构成智能体通信基础设施层的完整拼图:MCP(Model Context Protocol)由 Anthropic 提出,解决智能体与外部工具/资源的标准化通信问题,其设计哲学是"上下文共享";A2A(Agent-to-Agent Protocol)由 Google 提出,解决智能体之间的点对点协作问题,其设计哲学是"对等通信";ANP(Agent Network Protocol)由开源社区维护,解决大规模智能体网络的服务发现问题,其设计哲学是"去中心化服务发现"。三种协议各司其职——MCP 负责 Agent 与工具的连接,A2A 负责 Agent 与 Agent 的对话,ANP 负责构建大规模网络的底层基础设施。

在 HelloAgents 框架中,这三种协议被统一抽象为 Tool 接口,实现了无缝集成。开发者可以用完全相同的 API 风格,为智能体添加不同层级的通信能力。核心价值在于:我们终于有了一套标准化的方式,让智能体能够动态发现和使用外部服务,让多个智能体能够像人类团队一样对话协商,让大规模智能体网络能够自我组织和扩展。

核心概念解析

1. 为什么需要通信协议?

回顾前几章构建的 ReAct 智能体,我们为每个新服务(GitHub API、数据库、文件系统)编写专门的 Tool 类。这种方式存在四个根本性问题:代码重复(每个工具都要处理 HTTP 请求、错误处理、认证等),难以维护(API 变更需要修改所有相关工具),无法复用(其他开发者的工具无法直接使用),扩展性差(添加新服务需要大量编码工作)。

通信协议的核心价值正是解决这些问题。它提供了一套标准化的接口规范,让智能体能够以统一的方式访问各种外部服务,无需为每个服务编写专门的适配器。类比互联网的 TCP/IP 协议——它让不同设备能够相互通信,而不需要为每种设备编写专门的通信代码。

2. MCP 的三层架构

MCP 协议采用 Host(宿主层)、Client(客户端层)、Server(服务器层)的三层架构设计。当用户提问时,Host 接收并管理对话流程,Client 负责与 MCP Server 建立连接并通信,Server 执行具体操作。这种关注点分离的设计让开发者只需专注于 MCP Server 的开发,无需关心 Host 和 Client 的实现细节。

MCP 提供了三大核心能力:Tools(工具)是主动执行的(执行操作),Resources(资源)是被动提供的(提供数据),Prompts(提示)是指导性的(提供模板)。MCP 的工具发现机制让 LLM 能够自动发现服务器提供的所有工具,并根据工具描述的质量来决定是否使用以及如何使用工具。

3. MCP 与 Function Calling 的关系

这是一个常被问到的问题。Function Calling 与 MCP 并非竞争关系,而是相辅相成的。Function Calling 是大语言模型的一项核心能力,让模型能够理解何时需要调用函数并精准生成调用参数;MCP 则扮演基础设施协议的角色,在工程层面解决工具与模型如何连接的问题。

类比来说:Function Calling 相当于你学会了"如何打电话"这项技能(包括何时拨号、如何与对方沟通、何时挂断);而 MCP 则是那个全球统一的"电话通信标准",确保任何一部电话都能顺利拨通另一部。

4. A2A 的任务生命周期

A2A 协议的核心抽象是任务(Task)工件(Artifact)。任务具有标准化的生命周期——创建、协商、代理、执行中、完成、失败。这种机制让智能体可以进行任务协商、进度跟踪和异常处理。与 MCP 不同,A2A 关注的是智能体之间的对等通信,每个智能体既是服务提供者也是服务消费者。

传统的中央协调器(星型拓扑)存在单点故障、性能瓶颈和扩展困难的问题。A2A 采用点对点架构(网状拓扑),从根本上解决了这些问题,让智能体网络更加灵活和可扩展。

5. ANP 的去中心化服务发现

当网络中存在大量功能各异的智能体时,服务发现、智能路由和动态扩展成为核心挑战。ANP 提供了服务注册、发现和路由机制,让智能体能够动态发现网络中的其他服务,无需预先配置所有连接关系。

ANP 的核心流程是:首先通过公开的发现服务进行语义查询匹配,然后基于 DID(Decentralized Identifier)进行身份验证,最后通过标准化接口进行服务执行。这种设计构建了一个去中心化的信任根基,实现了服务的动态发现和跨平台互操作性。

代码示例

MCP 客户端使用

import asyncio
from hello_agents.protocols import MCPClient

async def connect_to_server():
    # 连接到社区提供的文件系统服务器
    client = MCPClient([
        "npx", "-y",
        "@modelcontextprotocol/server-filesystem",
        "."  # 指定根目录
    ])

    async with client:
        # 获取所有可用工具
        tools = await client.list_tools()
        print(f"服务器提供了 {len(tools)} 个工具")

        # 调用工具(读取文件)
        result = await client.call_tool("read_file", {"path": "README.md"})
        print(f"文件内容:{result}")

asyncio.run(connect_to_server())

在智能体中使用 MCP 工具

from hello_agents import SimpleAgent, HelloAgentsLLM
from hello_agents.tools import MCPTool

agent = SimpleAgent(name="文件助手", llm=HelloAgentsLLM())

# 连接到社区提供的文件系统服务器
fs_tool = MCPTool(
    name="filesystem",
    description="访问本地文件系统",
    server_command=["npx", "-y", "@modelcontextprotocol/server-filesystem", "."]
)
agent.add_tool(fs_tool)
# ✅ MCP工具 'filesystem' 已展开为多个独立工具

# Agent现在可以自动使用这些工具!
response = agent.run("请读取my_README.md文件,并总结其中的主要内容")
print(response)

A2A 多智能体协作

from hello_agents.protocols import A2AServer, A2AClient
import threading, time

# 创建多个Agent服务
researcher = A2AServer(name="researcher", description="研究员")
writer = A2AServer(name="writer", description="撰写员")
editor = A2AServer(name="editor", description="编辑")

# 定义技能
@researcher.skill("research")
def do_research(text):
    return str({"topic": text, "findings": f"{text}的研究结果"})

@writer.skill("write")
def write_article(text):
    return f"# {text}\n\n文章内容..."

@editor.skill("edit")
def edit_article(text):
    return str({"article": text + "\n\n[已编辑]", "approved": True})

# 启动所有服务
threading.Thread(target=lambda: researcher.run(port=5000), daemon=True).start()
threading.Thread(target=lambda: writer.run(port=5001), daemon=True).start()
threading.Thread(target=lambda: editor.run(port=5002), daemon=True).start()
time.sleep(2)

# 创建客户端并协作
researcher_client = A2AClient("http://localhost:5000")
writer_client = A2AClient("http://localhost:5001")

research = researcher_client.execute_skill("research", "AI在医疗领域的应用")
article = writer_client.execute_skill("write", str(research))
print(f"最终结果:{article}")

个人思考与反思

这一章的核心收获是理解了"协议分层"的思想。智能体系统的复杂度来自于多个层次的通信需求——有的是与工具的交互( MCP),有的是与同伴的协作( A2A),有的是与整个网络的连接( ANP)。单一协议无法覆盖所有场景,但通过分层抽象,HelloAgents 提供了一套统一的接入方式。

最有启发性的是 MCP 的设计理念——它不仅仅是 RPC 远程过程调用,更重要的是"上下文共享"。当智能体访问一个代码仓库时,MCP 服务器能提供文件内容、代码结构、依赖关系、提交历史等丰富的上下文信息,让智能体能够做出更智能的决策。这种设计思路值得借鉴到其他系统的设计中。

ANP 部分相对薄弱,毕竟还处于概念阶段,生态不成熟。但其"去中心化服务发现"的思路很有价值——在大规模系统中,预先配置所有连接关系是不现实的,必须让系统能够自我组织和动态发现。这与 Web 服务的 DNS 机制有异曲同工之妙。

A2A 协议让我重新思考了"多智能体协作"的意义。传统做法是用中央协调器,但星型拓扑存在单点故障和性能瓶颈。A2A 的对等通信模型虽然复杂度和成本更高,但提供了更好的可扩展性和容错性。这是一种架构选择,而非绝对的优劣。

关于 MCP 与 Function Calling 的关系,书中给出了清晰的解答。我之前的困惑在于"既然有了 Function Calling,为什么还需要 MCP?"——答案是它们在不同的层次解决问题。Function Calling 是模型的内生能力,MCP 是工程层面的协议规范。一个决定"何时调用",一个决定"如何调用"。

实践建议

1. 优先使用成熟的 MCP 社区服务

Anthropic 和社区已经提供了大量现成的 MCP 服务器(文件系统、GitHub、数据库等),可以直接使用。建议优先选择大公司背书的 MCP 工具,生态相对成熟,时效性有保障。

2. 根据系统规模选择协议

小规模协作(2-5个智能体)推荐使用 A2A;需要访问外部服务时使用 MCP;大规模网络(10+智能体)考虑 ANP。三种协议可以组合使用,HelloAgents 提供了统一的 Tool 接口来简化这种组合。

3. 构建自定义 MCP 服务器的思路

当现有 MCP 服务无法满足需求时,可以构建自定义服务器。主要场景包括:封装业务逻辑、访问私有数据、性能专项优化、功能定制扩展。发布到 Smithery 平台可以让全世界的开发者都能使用你的服务。

4. 编写高质量的工具描述

MCP 的工具发现机制依赖 LLM 理解工具描述的质量。清晰、准确的工具名称、功能说明和参数定义至关重要。这直接决定了 LLM 是否会使用以及如何使用该工具。

5. 协议目前仍处于早期发展阶段

无需花费太多精力去造轮子,重点是理解协议的设计理念和应用场景。MCP 生态相对成熟,A2A 有 Google 背书,ANP 还需要时间发展。选择有生态支持的协议,降低长期维护风险。

学习进度:Day 13/32 ✅ | 第十章完成 | 距离终点还有 19 章,继续加油!🚀

评论

此博客中的热门博文

OpenClaw 救援机器人建设与演进全记录 - 从单点故障到双实例自愈体系

Lossless Claw:无损上下文管理插件分析报告

[Hello-Agents] Day 2: 第一章 初识智能体