假设你是一位美食家,想去一家顶级餐厅吃饭。最早的“点菜方式”是你直接冲进后厨,对厨师喊:“给我来一份红烧肉!”——这就是 Function Calling 的浪漫与混乱:AI 直接调用本地函数,快速、直接,但每次都要重新沟通,换个餐厅(换个工具)就得重新喊一次。后来,餐厅引入了“标准菜单 + 服务生”模式——你想吃什么,只要告诉服务生,服务生按标准流程去后厨下单、上菜,这就是 MCP 的核心思想:把“点菜”这件事标准化、协议化,让 AI 不需要关心后厨(工具)的细节。而现在,我们迎来了 A2A 时代——餐厅与餐厅之间开始联网,形成美食联盟。你在一家餐厅,可以点另一家餐厅的招牌菜,甚至可以让两家餐厅的主厨直接对话、联手创作一道新菜。这就是 A2A:Agent 与 Agent 之间直接协作,无需人类反复“传话”。从“喊话”到“菜单”再到“餐饮生态”,这是工具调用协议的演进史诗。
掌握这条演进脉络,你将在技术选型时拥有“上帝视角”:知道什么时候该用 Function Calling 快刀斩乱麻,什么时候该上 MCP 建立标准,什么时候该让 A2A 连接生态——这是 AI 架构师和技术决策者的核心竞争力。
目录
可视化演示
动态演示协议演进的核心机制,通过架构/数据/状态/性能四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
协议演进:工具调用 工具调用协议演进总览与三代脉络 Function Callin 核心机制可视化 协议演进整体架构与关键组件
本地直呼阶段:Function Calling 的动机与能力边界
回到美食家冲进后厨喊话的场景——他为什么非要进后厨?因为菜单上写着“今日推荐”,但他想知道“现在还有没有新鲜的空运三文鱼”。这就是 Function Calling 的设计动机:让大模型在需要实时数据、私有数据或执行动作时,“喊一嗓子”调用一个预设的本地函数。它是大模型从“只能聊天”进化到“能干活”的第一次跃迁。
在技术上,开发者会在系统提示词中声明工具清单(名称、描述、参数 JSON Schema),模型在推理时判断“该调哪个工具”,然后输出一个结构化的函数调用请求。框架层拦截这个请求,执行对应函数,再把结果“回填”给模型继续生成。这套“声明-识别-执行-回填”的闭环,相当于厨师听到喊话后切菜下锅,再把菜端出来。
Function Calling 的核心公式是:模型根据输入和工具描述,决定是否返回一个函数调用请求。
然而,后厨喊话终究是“私人暗号”:每个餐厅(应用)的喊法(工具声明格式)都不一样,换个餐厅就得重新学。Function Calling 的能力边界正在于此——它解决的是“能不能调”,而不是“好不好调”。开发者需要为每个工具手写声明、为每次调用处理异常,且模型偶尔会“喊错菜名”(幻觉参数)。当工具数量从几个增长到几十上百个时,维护成本指数级上升。
- 输入与工具集
x是用户输入,\mathcal{T}是所有可用工具的集合 - 分支判断模型判定当前任务是否需要外部工具
- 调用动作选定工具
t_i并生成参数\text{args}_i执行
标准菜单:MCP 的诞生与设计哲学
后厨喊话的问题在于“没有标准菜单”。2024 年末,Anthropic 发布了 Model Context Protocol(MCP),一举把“喊话点菜”升级为“看菜单点菜”。MCP 的设计动机非常朴素:整个行业都在为“AI 接工具”这件事重复造轮子——OpenAI 有 Function Calling,谷歌有 Function Calling,各云厂商也各有各的插件规范。这种碎片化让“一次接入、处处可用”成为奢望。
MCP 的设计哲学可以概括为“菜单标准化”:它定义了 AI 应用(Host)与工具服务(Server)之间的标准交互方式,包括服务发现(看菜单)、工具调用(点菜)、上下文管理(忌口备注)等。最关键的突破是“双向连接”和“动态发现”——Agent 不需要提前知道有哪些工具,而是运行时去 Server 查询能力清单,就像客人落座后扫桌上的二维码打开菜单一样。
这套哲学隐含了一个重要取舍:用标准化的“慢”换生态化的“快”。虽然单个工具接入比本地调用多了一层协议开销,但工具方只需实现一次 MCP Server,所有支持 MCP 的 AI 应用都能自动使用。先写一次协议,之后处处复用。MCP 对应着“技术标准化是生态繁荣的前提”这条铁律——正如 USB 接口统一了设备连接,MCP 统一了 AI 与工具的连接。
MCP = 标准菜单格式 + 点菜流程 + 后厨联动规范服务生模式:MCP 核心架构与治理
MCP 的架构像一个训练有素的餐厅服务团队。Host(如 Claude Desktop、IDE 插件)是餐厅经理,负责理解客人需求;Client 是具体跑腿的服务生,负责在 Host 和 Server 之间传话;Server 是后厨,拥有真正的厨艺(工具和数据)。三者各司其职,互不越权。
通信上,MCP 采用 JSON-RPC 2.0 作为“传话暗语”。服务生和后厨之间的每一句对话都遵循统一格式:查菜单(tools/list)、点菜(tools/call)、备注忌口(上下文管理)。其中,服务发现是 MCP 的精髓——Host 启动时会向 Server 发送能力清单请求,Server 返回所有可用工具的描述,全程动态、无需重启。
MCP 的“治理”理念体现在三个层面。会话管理上,Client 为每次对话创建独立会话,像服务生记住每桌的忌口;工具组织上,Server 可以按域分组(如数据库组、文件组),像后厨分热菜、凉菜、甜品各个档口;安全治理上,MCP 允许控制“哪些菜能点”——API key 管理、权限拦截、审计日志,确保服务生不能私自下单最贵的菜。
- 查看菜单
list\_tools查询 Server 暴露的全部工具能力 - 下达指令
call\_tool带上工具名t和参数\text{args}发起调用 - 结果回传Server 返回结构化结果,Host 将结果交给模型续写
餐饮联盟:A2A 与 Agent 互联
如果说 MCP 统一了“AI 点菜、工具做菜”,那 A2A(Agent-to-Agent)协议则是让“餐厅之间联网”的餐饮联盟。A2A 是 Google 于 2025 年 4 月开源的开放协议,目标是解决 Agent 之间的互联互通。试想:你是一个旅行规划 Agent,需要订机票、订酒店、安排行程——如果每个环节都有一个独立的 Agent 服务(航司 Agent、酒店 Agent、攻略 Agent),你如何找到它们、如何与它们协作?A2A 给出了答案。
A2A 的核心机制是 Agent Card——每个 Agent 发布一张“电子名片”,上面写着:我的 ID(全局唯一)、我的能力(能干什么)、我的通信端点(去哪找我)、我的认证方式(怎么验明正身)。其他 Agent 可以通过注册中心(Agent Directory)发现这些名片,然后直接对等通信、任务协作。
A2A 与 MCP 不是替代关系,而是互补关系。MCP 解决“Agent 怎么用工具”,A2A 解决“Agent 怎么找 Agent”。一个 Agent 可以同时是 MCP Client(调工具)和 A2A Participant(与别的 Agent 协作),就像一家餐厅既用标准菜单服务客人,也加入美食联盟与同行互通。A2A 的终极愿景是打破“每家 AI 公司一个孤岛”的现状,让跨组织、跨平台的 Agent 协作成为常态——这是通向通用 Agent 生态的必由之路。
- 身份标识
ID为每个 Agent 分配全局唯一标识,类似餐厅的营业执照号 - 能力声明
capabilities定义 Agent 能提供的服务类型与输入输出格式 - 通信端点
endpoint是其他 Agent 发起协作的 URL 地址 - 认证与会话
auth与context保证协作的安全性与连续性
选型矩阵:三代协议对比与决策
面对三代协议,技术决策者最常问的问题是“我该用哪个?”答案藏在“场景”二字里。我们用一张对比矩阵厘清它们的核心差异。
| 维度 | Function Calling | MCP | A2A |
|------|-----------------|-----|-----|
| 通信拓扑 | 应用内直连 | Host-Client-Server 星型 | Agent 对等网状 |
| 标准化程度 | 各厂商私有 | 开放协议 | 开放协议 |
| 服务发现 | 静态声明 | 动态 list_tools | Agent Card 注册/发现 |
| 核心抽象 | 函数调用 | 工具服务 | Agent 能力 + 任务协作 |
| 适用规模 | 单应用、少量工具 | 中大型工具集成 | 跨 Agent/跨组织协作 |
选型决策可以概括为三条路径。路径一:单体快跑——如果你在做 PoC 或内部小工具,工具只有三五个,选 Function Calling 准没错,它最快、最直接、零额外依赖。路径二:标准集成——当你的 Agent 需要接入数据库、第三方 SaaS、内部 API,且未来可能有更多工具加入时,果断上 MCP。路径三:生态互联——当你要构建多个 Agent 协同的复杂系统,或需要与外部组织的 Agent 交互时,用 A2A 让 Agent 互相发现、对等协作。
一个重要原则是“以场景驱动选型,而非追逐热点”。MCP 再火,你只有两个工具也未必需要它;A2A 再前瞻,你只有一个 Agent 也无从谈起。决策的本质是匹配:让协议的复杂度匹配系统的复杂度,让生态的广度匹配业务的广度。
平滑升级:迁移路径与兼容策略
从 Function Calling 迁移到 MCP 再到 A2A,看起来是“推倒重来”,但聪明的架构师会优雅过渡。迁移的第一原则是兼容存量,渐进演进,别学那些为了“用新架构”而把系统重写一遍的愣头青。
具体的迁移路径分三步。第一步:存量封装——以 Function Calling 实现的工具,用一个“适配器层”包装成 MCP Server。每个已有函数用一个 @mcp.tool 装饰器暴露,函数签名自动映射为工具 Schema。这样存量代码零改动,就获得了 MCP 标准接入能力。第二步:协议融合——在 Agent 侧同时保留 MCP Client 和 A2A Participant。所有内部工具走 MCP,外部 Agent 协作走 A2A。两者通过统一的能力路由层调度——路由层先查 A2A Agent 目录,再查 MCP 工具清单,决定请求发给谁。第三步:渐进替换——随着 MCP 生态成熟,逐步将适配器层升级为原生 MCP Server,去掉中间层。
避坑指南同样重要。第一大坑是“一次性大爆炸迁移”,正确做法是先用适配器扛住业务,再逐步替换;第二大坑是“忽视协议语义差异”,MCP 的 list_tools 返回的是工具描述而非函数指针,迁移时要改的是调用方式而非业务逻辑;第三大坑是“治理机制缺失”,无论是 MCP 还是 A2A,权限和审计都要在设计期就纳入,否则协议越标准、越容易被滥用。记住:协议演进是加法,不是替换——让每一代协议都成为新一代基础设施的基石。
AI 应用场景
场景一:企业 Agent 平台统一工具接入
阶段:工具调用与集成
解决的问题:一家大型企业有 CRM、ERP、工单系统等十余个内部系统,每个系统都有自己的 API。传统做法是给每个系统写一套 Function Calling 的提示词声明,模型很容易混淆、API 变更后维护量巨大。引入 MCP 后,每个系统只需实现一个 MCP Server,企业 Agent 平台通过统一 Client 连接所有 Server,工具发现变成“运行时查菜单”,新增系统只需开发一个 Server,零改动接入。
具体案例:某电商公司的客服 Agent 需要同时查订单、退款、物流、优惠券四个系统。原来四套私有工具声明让提示词膨胀到 8000 token,还经常调错参数。迁移到 MCP 后,四个系统各实现一个 MCP Server,客服 Agent 通过 tools/list 动态发现 20+ 工具,参数校验由 Server 侧完成,调用准确率从 82% 提升到 97%。
场景二:跨组织 Agent 协同的供应链调度
阶段:Agent 间协作与任务编排
解决的问题:制造企业的供应链调度需要协调多个外部合作伙伴的系统。传统方式是通过人工邮件/API 接洽,效率低且难以自动化。A2A 协议让内部调度 Agent 和供应商的库存 Agent、物流 Agent 互相注册、自动发现、直接协作,形成动态的供应链网络。
具体案例:某汽车厂商的排产 Agent 发现某种零部件库存不足,自动通过 A2A 发现三家供应商的库存 Agent,分别发送询价和交期确认请求,综合比对后自动下单,并将交期回写生产计划。整个过程无需人工介入,从原来的 3 天缩短到 10 分钟。
Python 演示
# -*- coding: utf-8 -*-"""演示如何用 MCP 封装一个普通函数,并通过 Client 动态发现和调用工具。""" import asyncioimport jsonfrom mcp.server.fastmcp import FastMCP # 1. 定义 MCP Server,等价于餐厅的"后厨"mcp = FastMCP("InventoryServer") @mcp.tool()def query_stock(sku: str) -> str: """查询某个SKU的实时库存(模拟真实库存系统)。""" stock_map = {"A1001": 150, "B2002": 0, "C3003": 78} stock = stock_map.get(sku, -1) if stock < 0: return json.dumps({"sku": sku, "error": "SKU不存在"}) if stock == 0: return json.dumps({"sku": sku, "stock": 0, "status": "缺货"}) return json.dumps({"sku": sku, "stock": stock, "status": "有货"}) @mcp.tool()def create_order(sku: str, quantity: int) -> str: """根据SKU和数量创建补货订单。""" return json.dumps({"order_id": "PO2025" + sku, "sku": sku, "quantity": quantity, "status": "已创建"}) async def main(): # 2. 启动 MCP Server 子进程,等价于"后厨开工" from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client server_params = StdioServerParameters( command="python", args=["-m", "mcp.server.fastmcp", "实验脚本名"] # 实际运行时替换为当前文件名 ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: # 3. 动态发现工具:等价于"查看菜单" tools = await session.list_tools() print("菜单(工具清单):") for t in tools.tools: print(f" - {t.name}: {t.description}") # 4. 调用工具:等价于"点菜下单" result = await session.call_tool("query_stock", {"sku": "B2002"}) print("查询缺货SKU:", result.content[0].text) order = await session.call_tool("create_order", {"sku": "B2002", "quantity": 50}) print("创建订单结果:", order.content[0].text) if __name__ == "__main__": asyncio.run(main())
from mcp.server.fastmcp import FastMCP导入 FastMCP 框架,让普通函数变成标准 MCP 服务@mcp.tool()装饰器把函数暴露为 MCP 工具,参数 Schema 自动生成,等价于“写入菜单”async with stdio_client(server_params) as (read, write)建立与 Server 子进程的标准输入输出通道tools = await session.list_tools()动态查询 Server 的能力清单,等价于“客人扫码看菜单”await session.call_tool("query_stock", {"sku": "B2002"})标准化的工具调用,不再依赖硬编码声明
常见误区
误区“MCP 出来了,Function Calling 应该被淘汰了,我要把所有代码全部重写成 MCP。”很多初学者把 MCP 和 Function Calling 对立起来,认为新协议一定会完全替代旧协议。
正解MCP 是对 Function Calling 的补充和标准化,不是“革命”。用餐厅比喻来说,Function Calling 是“直接进后厨喊话”,MCP 是“建立标准菜单和点菜流程”——后者提升了体验,但“喊话”在某些场景依然高效。MCP 的作用是封装工具调用、提供发现机制,而模型底层触发工具的能力依然依赖 Function Calling 或等价机制。对于只有两三个工具的轻量场景,直接用 Function Calling 完全合理。
为何常见:技术媒体偏好“颠覆式创新”的叙事,加上许多教程标题强调“告别 Function Calling”,让学习者误以为新协议必然淘汰旧技术,忽略了架构选型要匹配场景复杂度的基本原则。
误区“既然 A2A 支持 Agent 互联,那我不需要学 MCP 了,直接上 A2A 一步到位。”这是对 A2A 定位最典型的误读。
正解A2A 和 MCP 是两个层面的东西。MCP 规定“Agent 如何调用工具”,A2A 规定“Agent 如何与其他 Agent 协作”。一个专注于工具层,一个专注于智能体层。实际系统中两者通常配合使用:Agent 通过 MCP 获取数据,通过 A2A 协调其他 Agent 的任务,这种混合架构在大型 AI 系统中已经出现。
为何常见:A2A 发布时间较晚,很多文章把它安排在“MCP 之后”,容易让读者误以为它是"MCP 2.0"。实际上两者同处一个生态,各司其职。
误区“A2A 是趋势,我的系统应该立刻全量迁移到 A2A,否则就落后了。”技术选型中最常见的焦虑性决策。
正解协议成熟度与业务需求的匹配远比“新”重要。A2A 适合多 Agent 协作、跨组织互联的场景;如果你的系统只有一个 Agent 调用几个内部工具,迁移到 A2A 是纯粹增加复杂度,如同在家庭厨房里建立完整的餐厅供应链体系。正确的路径是:先用 Function Calling 验证业务,工具多了引入 MCP 标准化,真正出现跨 Agent 协作需求再引入 A2A,保持演进耐心。
为何常见:技术决策者容易把“采用新协议”等同于“保持技术先进性”,忽略了技术债务和迁移成本。新协议往往伴随着生态不成熟、文档不全面、踩坑成本高。
误区“上了 MCP,我的模型就能完美调用所有工具了。”把协议当成万能药,忽视了工具调用中的许多实际问题。
正解MCP 解决的是“接入标准化”问题,但工具调用质量还受多重因素制约:模型能力(能否生成正确的参数)、工具描述质量(Schema 是否清晰)、服务可靠性(Server 是否稳定)。MCP 是“高速公路”,但你还需要一辆好车(模型)和一把好方向盘(工具描述)。在落地时,工具描述的书写质量、异常处理逻辑和权限治理,往往比协议本身更能决定成败。
为何常见:协议本身提供了“标准”,让人误以为“标准”就等于“质量”。实际上标准解决的是互通问题,与单个工具的好坏无关。
面试题
Q1. MCP 协议的全称是什么?
- A.Model Context Protocol← 正确答案
- B.Model Control Protocol
- C.Multi-Chain Protocol
- D.Machine Communication Program
答案:A。MCP 是 Model Context Protocol(模型上下文协议)的缩写,核心是让 AI 模型获取外部工具的上下文与能力。B 把 Context(上下文)错写成 Control(控制),C 和 D 则完全是编造的干扰项。我们可以把 MCP 理解为“标准菜单协议”——它规定的是“如何传递点菜上下文”,而非“如何控制后厨”。
Q2. Function Calling 最早主要由哪家厂商提出并广泛应用?
- A.Anthropic
- B.OpenAI← 正确答案
- C.Google
- D.Meta
答案:B。虽然现在多家厂商都支持类似能力,但“Function Calling“这一叫法和标杆实现是 OpenAI 于 2023 年 6 月提出的。在餐厅比喻中,OpenAI 是第一个让”客人(AI)可以进后厨喊话”的餐厅。Anthropic 后来提出了 MCP 加强标准化,但那已经是协议演进的下一篇章。
Q3. 在 MCP 架构中,哪个组件负责维护工具列表并响应 Client 的调用请求?
- A.Host
- B.Client
- C.Server← 正确答案
- D.Model
答案:C。MCP 采用 Host-Client-Server 三层架构。Host 是 AI 应用主体(相当于餐厅经理),Client 是协议会话管理方(相当于服务生),Server 是工具提供方(相当于后厨)。后厨(Server)掌管家传菜谱(工具列表),服务生(Client)来问菜单(list_tools)时就照单展示,点菜(call_tool)时就去执行烹饪。Model 只是 Host 内部的推理引擎,不直接参与协议交互。
Q4. A2A 协议中,Agent 通过什么机制实现能力的注册与发现?
- A.Function Calling 提示词
- B.Agent Card 注册表← 正确答案
- C.JSON Schema 校验
- D.Webhook 回调
答案:B。A2A(Agent-to-Agent)协议的核心机制是 Agent Card——每个 Agent 发布一张“电子名片”,包含身份、能力、端点、认证方式等信息,并注册到 Directory(注册中心)。其他 Agent 通过查询注册中心发现可以协作的对象。这正如美食联盟中的餐厅名册:各餐厅提交名片信息,其他餐厅翻阅名册就能找到合作伙伴。Function Calling 是工具层机制,与 Agent 发现无关。
Q5. 关于 MCP 与 A2A 的关系,下列说法中正确的是?
- A.A2A 取代 MCP,成为唯一的协议标准
- B.MCP 方案优于 A2A,后者只是概念炒作
- C.MCP 管“Agent 调工具”,A2A 管“Agent 间协作”← 正确答案
- D.二者功能完全重叠,只需任选其一
答案:C。MCP 与 A2A 是互补而非替代的关系。MCP 定义了 Agent 与工具之间的标准化调用(AI 点菜、工具做菜),A2A 定义了 Agent 与 Agent 之间的对等协作(餐厅之间互通有无)。在实际系统中,一个 Agent 可以同时通过 MCP 调用内部工具,并通过 A2A 与外部 Agent 协作,两者不会冲突。
Q6. 下面哪项是 Function Calling 的主要局限性?
- A.大模型无法识别任何外部工具
- B.工具声明格式碎片化,缺乏统一标准← 正确答案
- C.不支持 JSON 格式的参数传递
- D.每次调用都需要人工干预
答案:B。Function Calling 的瓶颈在于它是由各厂商各自定义的私有规范——OpenAI 有一份 JSON Schema 声明方式,Anthropic 有另一份,各家对参数约束和工具描述都有不同要求。这就像每家餐厅各自发明喊话暗号,客人换一家餐厅就得重新学一遍。MCP 的诞生正是为了解决这个碎片化问题。大模型能识别工具、支持 JSON 参数、调用无需人工——A、C、D 都不是正确的局限描述。
Q7. 关于 A2A 协议中 Agent Card 包含的信息,以下哪些正确?
- A.Agent 的唯一身份标识← 正确答案
- B.Agent 能提供的能力列表← 正确答案
- C.Agent 的可访问通信端点← 正确答案
- D.Agent 的模型训练参数
答案:ABC。Agent Card 相当于 Agent 的“营业名片”,包含身份(ID)、能力(capabilities)、端点(endpoint)、认证(auth)等关键信息。模型训练参数是 Agent 的内部细节,与对外协作无关,就像餐厅名片不会印后厨灶台的功率一样。A、B、C 都是名片上必须公开的“招聘信息”。
Q8. 以下哪些属于从 Function Calling 迁移到 MCP 的合理路径?
- A.使用适配器层将旧工具封装为 MCP Server← 正确答案
- B.一次性重写所有工具代码和业务逻辑
- C.保持 MCP 与 Function Calling 共存,渐进替换← 正确答案
- D.直接禁用旧工具,等待新生态成熟
答案:AC。平滑迁移的核心是“兼容存量、渐进演进”。用适配器封装旧函数为 MCP Server 是零改造的过渡方案,而让新旧协议共存可以降低迁移风险。一次性重写(B)风险高、成本大;直接禁用旧工具(D)则可能导致业务断档。正确姿势是“楼梯式下楼”而不是“跳楼式迁移”。
Q9. MCP 的 Client 在会话中的核心职责是什么?
- A.直接执行业务逻辑和算法计算
- B.维护请求生命周期并管理协议会话← 正确答案
- C.替代大模型进行推理和决策
- D.存储所有工具的历史调用数据
答案:B。MCP Client 扮演“服务生”角色,负责管理一次工具调用的完整生命周期——发起会话、封装请求、传输结果、处理错误。它不执行业务逻辑(那是 Server 的工作),不替代模型推理(那是 Host 的事),也不做数据仓库(那是存储层的事)。可以说 Client 是连接 Host 与 Server 的“信使协议机”。
Q10. 在设计大规模 MCP 系统时,以下做法中正确的是?
- A.全部工具放在一个 Server 中,减少通信开销
- B.按业务域拆分 Server,实现故障隔离和独立治理← 正确答案
- C.禁止所有工具的外部访问权限
- D.用 Function Calling 替代 MCP
答案:B。生产级 MCP 的最佳实践是按业务域拆分 Server,比如“库存域”“订单域”“物流域”各自独立。这样当一个 Server 故障时只影响局部服务,权限治理也更精细(每个 Server 独立控制 API Key 范围)。把所有工具塞进一个 Server 虽然省了通信开销,但会形成单点故障和权限混滥,得不偿失。