Function Call、MCP和A2A

167 阅读18分钟

大模型的Function Call、MCP和A2A协议代表了AI模型与外部世界交互的三个关键范式。Function Call专注于模型与工具的直接交互,MCP致力于标准化工具调用接口,而A2A则解决了智能体间协作的通信问题。这三种协议共同构建了一个让AI模型"动起来"的技术生态系统,使大语言模型能够突破知识固化限制,实时获取数据并完成复杂任务。本文将深入解析这三种协议的技术架构、通信机制,并提供具体的实战实现样例,帮助读者理解它们如何让AI模型真正连接现实世界。 一、Function Call:大模型与工具的直接交互 Function Call(函数调用)是OpenAI推动的一项技术,旨在让大语言模型能够通过调用外部函数或API,与外部系统进行交互。这一技术解决了传统大模型知识更新停滞的问题,使其能够获取实时信息并执行原本无法完成的任务。

  1. 技术架构与通信机制 Function Call采用模型-应用-工具的三层架构。模型负责理解用户需求并生成函数调用指令,应用层负责执行这些指令并获取结果,工具层则提供具体的外部功能。通信机制主要依赖JSON格式的数据交换,模型通过自然语言理解生成结构化的函数调用请求,应用层解析并执行这些请求。 具体实现流程包括以下步骤:
  2. 函数定义:开发者定义一组函数,以JSON格式描述函数名称、参数和返回值等信息
  3. 模型解析:当用户提出需要执行特定任务的问题时,模型会解析问题并判断是否需要调用外部函数
  4. 参数生成:模型生成调用函数所需的参数,以JSON格式返回
  5. 外部执行:应用层接收JSON格式的函数调用请求,解析参数并执行相应的函数或API
  6. 结果整合:应用层将执行结果返回给模型,模型根据上下文整合信息生成最终回答
  7. 实现原理详解 Function Call的核心在于模型对自然语言的理解能力和结构化输出能力。当模型接收到包含函数描述的提示时,它会将这些函数信息融入其推理过程中,判断何时需要调用外部函数。 模型生成的函数调用请求必须符合JSON Schema规范,包含函数名称和参数。例如,一个天气查询函数的JSON Schema描述如下: json { "name": "get_weather", "description": "查询指定城市的实时天气状况", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "要查询的城市名称" }, "date": { "type": "string", "description": "要查询的日期,格式为YYYY-MM-DD" } }, "required": ["city"] } } 模型会根据这个Schema生成结构化的调用请求: json { "name": "get_weather", "arguments": { "city": "北京", "date": "2025-06-24" } } 应用层接收到这个请求后,会执行实际的天气API调用,获取数据后返回给模型,模型再将数据整合到自然语言回答中。
  8. 实战样例:天气查询与邮件发送 以下是一个使用Function Call实现天气查询并发送邮件的Python示例:
import openai
import smtplib
from email.mime.text import MIMEText
配置OpenAI API密钥
openai.api_key = os.getenv("OPENAI_API_KEY")
定义可用函数列表
functions = [
 {
 "name": "get_weather",
 "description": "查询指定城市的实时天气状况",
 "parameters": {
 "type": "object",
 "properties": {
 "city": {
 "type": "string",
 "description": "要查询的城市名称"
 },
 "date": {
 "type": "string",
 "description": "要查询的日期,格式为YYYY-MM-DD"
 }
 },
 "required": ["city"]
 }
 },
 {
 "name": "send_email",
 "description": "发送邮件给指定收件人",
 "parameters": {
 "type": "object",
 "properties": {
 "recipient": {
 "type": "string",
 "description": "收件人邮箱地址"
 },
 "subject": {
 "type": "string",
 "description": "邮件主题"
 },
 "body": {
 "type": "string",
 "description": "邮件正文"
 }
 },
 "required": ["recipient", "subject", "body"]
 }
 }
]
天气查询函数实现
def get_weather(params):
 # 这里可以调用实际的天气API
 city = params.get("city", "北京")
 date = params.get("date", "今天")
 return {
 "temperature": "25°C",
 "condition": "晴朗",
 "date": date,
 "city": city
 }
邮件发送函数实现
def send_email(params):
 recipient = params["recipient"]
 subject = params["subject"]
 body = params["body"]
# 发送邮件逻辑
 msg = MIMEText(body)
 msg['Subject'] = subject
 msg['From'] = "your_email@example.com"
 msg['To'] = recipient
with smtplib.SMTP('smtp.example.com', 587) as server:
 server.starttls()
 server.login("your_email@example.com", "your_password")
 server.sendmail("your_email@example.com", recipient, msg.as_string())
return {"status": "邮件发送成功"}
主函数
def main():
 # 用户查询
 user_query = "帮我查一下明天上海的天气,然后给张三发邮件告诉他结果"
# 调用GPT模型
 response = openai ChatCompletion.create(
 model="gpt-3.5-turbo",
 messages=[{"role": "user", "content": user_query}],
 functions=functions,
 function_call="auto"
 )
# 处理模型回复
 if response.choices[0].message.get("function_call"):
 function_name = response.choices[0].message["function_call"]["name"]
 function_args = json.loads(response.choices[0].message["function_call"]["arguments"])
# 执行函数
 if function_name == "get_weather":
 result = get_weather(function_args)
 # 将结果返回给模型
 response = openai ChatCompletion.create(
 model="gpt-3.5-turbo",
 messages=[
 {"role": "user", "content": user_query},
 {"role": "assistant", "content": None,
 "function_call": {
 "name": "get_weather",
 "arguments": json.dumps(function_args)
 }}
 ],
 functions=functions,
 function_call="auto",
 tools=[{
 "type": "function",
 "function": {
 "name": "get_weather",
 "description": "查询指定城市的实时天气状况",
 "parameters": functions[0]["parameters"]
 }
 }]
 )
# 处理天气查询结果
 if response.choices[0].message.get("function_call"):
 # 处理邮件发送函数调用
 if response.choices[0].message["function_call"]["name"] == "send_email":
 email_args = json.loads(response.choices[0].message["function_call"]["arguments"])
 send_email(email_args)
 # 将邮件发送结果返回给模型
 final_response = "已查询到明天上海的天气是25°C,晴朗,并已发邮件告知张三。"
 else:
 final_response = response.choices[0].message["content"]
print(final_response)
if name == "main":
    main()

在这个示例中,模型首先识别出需要查询天气,生成get_weather函数调用请求;获取天气结果后,模型进一步识别出需要发送邮件,生成send_email函数调用请求;应用层执行这两个函数后,模型整合结果生成最终回答。 二、MCP:标准化工具调用协议 MCP(Model Context Protocol,模型上下文协议)是由Anthropic提出的通信协议,旨在解决多模型、多工具对接时标准缺失的问题。MCP通过标准化接口让不同大模型与不同工具统一对接,极大降低了集成成本,被誉为AI界的"USB Type-C"。

  1. 技术架构与通信机制 MCP采用客户端-服务器(C/S)架构,其中大模型作为客户端,工具服务作为服务器,通过MCP Router实现标准化连接。通信机制基于JSON-RPC 2.0协议,支持HTTP/SSE传输,定义了list_tools(获取工具列表)和call_tool(调用工具)等标准方法。 MCP Router作为中间层,负责将模型的函数调用请求转换为工具服务可以理解的格式,并将结果返回给模型。这种设计使得模型无需知道具体工具的实现细节,只需通过标准化接口即可调用各种工具。
  2. 实现原理详解 MCP的核心理念是标准化和解耦。通过定义统一的JSON-RPC接口,MCP使得不同大模型(如Claude、GPT、LLaMA)能够以相同的方式调用不同工具。MCP Router在其中扮演关键角色,它维护工具服务的注册信息,并在模型需要时提供工具列表。 当模型需要调用工具时,它通过call_tool方法发送JSON-RPC请求,包含工具名称和参数。MCP Router接收请求后,将其转发给对应的工具服务。工具服务执行请求后,返回JSON格式的结果,MCP Router再将结果传递给模型。 MCP还支持工具动态注册机制,开发者可以通过注解或代码手动注册工具到MCP Server,MCP Router从注册中心(如Nacos)拉取注册信息并代理请求。这种机制使得工具可以"即插即用",无需模型重新适配。
  3. 实战样例:高德地图地理查询 以下是一个使用MCP协议实现高德地图地理查询的实战示例: 首先,注册高德地图MCP服务到Nacos: json { "mcpServers": { "amap-maps": { "command": "npx", "args": ["-y", "@amap/amap-maps-mcp-server"], "env": { "AMAP_MAPS_API_KEY": "" } } } } 然后,通过Nacos-MCP-Router客户端调用服务:
from mcp.client import McpClient
import os
设置Nacos连接信息
NACOS_ADDR = os.getenv("NACOS_ADDR", "localhost:8848")
NACOSUSERNAME = os.getenv("NACOSUSERNAME", "nacos")
NACOS_PASSWORD = os.getenv("NACOS_PASSWORD", "nacos")
创建MCP客户端
client = McpClient(
 name="地理查询助手",
 version="1.0",
 nacos_addr=NACOS_ADDR,
 nacos_username=NACOSUSERNAME,
 nacos_password=NACOS_PASSWORD
)
查询工具列表
tools = client.list_tools()
print("可用工具:", tools)
调用高德地图工具
response = client.call_tool(
 tool_name="amap-weather",
 arguments={
 "city": "北京",
 "date": "2025-06-24"
 }
)
处理响应
if "result" in response:
 print("天气结果:", response["result"])
else:
 print("错误:", response["error"])

在这个示例中,Nacos-MCP-Router充当了服务发现和请求转发的角色,客户端只需配置Nacos信息,即可自动发现并调用注册的MCP服务。这种方式避免了手动维护工具列表和API端点的复杂性。 三、A2A:智能体间的协作通信 A2A(Agent-to-Agent,智能体到智能体)协议是由Google推出的,专注于不同智能体之间的通信和协作。A2A旨在解决智能体"孤岛"问题,使它们能够像人类团队一样分工合作,共同完成复杂任务。

  1. 技术架构与通信机制 A2A采用客户端-服务器架构,但更强调智能体间的平等协作。核心概念包括Agent Card(智能体能力卡片)、任务生命周期管理和流式通信。 Agent Card是一个标准化的JSON文件,通常托管在/.well-known/agent.json路径,描述智能体的能力、支持的操作和认证要求。通信机制基于HTTP/HTTPS,支持SSE流式传输,消息格式为JSON-RPC 2.0。A2A还定义了任务状态(如submitted、working、input-required、completed等)和消息类型(TextPart、DataPart、FilePart等)。 A2A的通信流程包括:
  2. 发现:客户端通过获取Agent Card了解其他智能体的能力
  3. 启动:客户端发送任务请求(tasks/send或tasks/sendSubscribe)
  4. 处理:服务器处理请求,可能通过SSE发送流式更新
  5. 交互:若任务需要更多信息,客户端可发送后续消息
  6. 完成:任务达到最终状态(completed、failed等)
  7. 实现原理详解 A2A的核心是任务管理和智能体协作。它不关注智能体内部如何执行任务,而是定义了智能体间协作的标准流程。A2A特别适合处理长时间运行的任务,如招聘流程、项目管理等需要多步骤协作的场景。 A2A与MCP形成互补关系:MCP关注单个智能体如何调用工具,A2A关注多个智能体如何协作完成任务。一个智能体可以通过MCP获取执行任务的工具,然后通过A2A与其他智能体协同完成多步骤任务。 A2A的任务分配算法基于Agent Card中的技能(skills)和模态(modalities)匹配任务需求,结合优先级和负载均衡选择最优智能体。例如,招聘任务会分配给具备"筛选简历"技能的智能体,日程安排任务则分配给具备"日历管理"技能的智能体。
  8. 实战样例:招聘流程智能体协作 以下是一个使用A2A协议实现招聘流程协作的实战示例: 首先,定义招聘智能体的Agent Card: json { "name": "招聘助手", "description": "协助完成招聘流程的智能体", "skills": ["发布职位", "筛选简历", "安排面试", "背景调查"], "modalities": ["text", "data"], "auth": { "type": "OAuth2", "Provider": "Google" }, "tasks": { "create Job Posting": { "description": "创建并发布职位描述", "inputSchema": { "type": "object", "properties": { "jobDescription": {"type": "string"}, "location": {"type": "string"}, "requirements": {"type": "array"} }, "required": ["jobDescription", "location"] }, "outputSchema": { "type": "object", "properties": { "jobId": {"type": "string"}, " postingUrl": {"type": "string"} } } } } } 然后,实现招聘流程的智能体协作:
import requests
import json
from a2a.client import A2AClient
配置A2A客户端
client = A2AClient(
 base_url="https://recruitment-agent.example.com",
 auth_type="OAuth2",
 auth_token(os.getenv("Google_OAuth_TOKEN"))
)
创建招聘任务
task_id = client.create_task(
 description="招聘软件工程师",
 initial_message={
 "parts": [
 {"type": "text", "content": "寻找在上海精通Python和K8s的候选人"}
 ]
 }
)
监听任务状态
def on_status_update(event):
 if event["status"] == "input-required":
 # 处理需要额外信息的情况
 client.send_message(
 task_id=task_id,
 message={
 "parts": [
 {"type": "text", "content": "预算为每月30,000元人民币"}
 ]
 }
 )
订阅任务更新
client.subscribe_task(
 task_id=task_id,
 on_update=on_status_update,
 on Artifacts=on Artifacts
)
等待任务完成
final Artifacts = client.get Final Artifacts(task_id)
print("招聘结果:", final Artifacts)

在这个示例中,招聘智能体作为客户端,创建了一个招聘任务,并与其他专门负责筛选简历、安排面试和背景调查的智能体协作。通过A2A协议,这些智能体能够互相通信,共享任务进展和工件,最终完成复杂的招聘流程。 四、三种协议的对比分析 以下是Function Call、MCP和A2A三种协议的详细对比: 对比维度 Function Call MCP A2A 技术定位 模型与工具的直接交互 标准化工具调用协议 智能体间协作通信协议 通信机制 JSON格式的函数调用请求 JSON-RPC 2.0协议 JSON-RPC 2.0 + SSE流式传输 适用场景 简单同步任务(如天气查询) 工具调用(如数据库、API) 复杂异步任务(如招聘流程) 任务执行方式 同步阻塞式 同步或异步 异步非阻塞式 跨模型兼容性 差(各厂商接口不同) 好(标准化协议) 好(标准化协议) 复杂任务支持 有限(需手动管理流程) 中等(支持多工具调用) 强(支持任务队列和状态管理) 部署复杂度 低(直接集成API) 中(需部署MCP Router) 高(需部署A2A Server) 典型应用 天气查询、股票价格获取 代码编辑器集成、IDE工具链 项目管理、客户服务系统

  1. Function Call的优缺点 优点: ● 入门简单,只需定义好JSON接口即可 ● 与单一大模型、少量功能的简单应用集成方便 ● 几乎可以"一键"将大模型输出对接到代码逻辑中 缺点: ● 缺乏跨大模型的一致性,各厂商接口格式不同 ● 平台依赖性强,通常依赖于特定平台或框架 ● 扩展性有限,复杂任务需手动管理调用流程 ● 不支持长时间运行的任务,调用是同步阻塞的 Function Call最适合简单、同步的API调用场景,如实时数据查询、单步骤操作等。例如,查询天气、获取新闻摘要、执行简单计算等。
  2. MCP的优缺点 优点: ● 标准化程度高,支持多种大模型和工具 ● 降低集成成本,工具可"即插即用" ● 支持多语言工具开发,社区生态丰富 ● 提供安全机制,支持TLS加密和身份验证 ● 支持工具动态注册,便于管理 缺点: ● 仍需手动管理工具注册和维护 ● 不支持智能体间协作,仅限于模型与工具交互 ● 主要面向单个智能体的工具调用,而非多智能体协作 ● 生态成熟度有待提高,部分工具链不完善 MCP最适合需要连接多种工具的AI应用,如代码编辑器、开发工具、文档处理系统等。例如,Cursor代码编辑器通过MCP协议集成AI功能,支持自动化代码管理和开发任务优化。
  3. A2A的优缺点 优点: ● 解决智能体"孤岛"问题,促进协作 ● 支持长时间运行任务,如招聘、项目管理 ● 提供任务状态管理和生命周期管理 ● 支持多模态内容传递(文本、文件、结构化数据等) ● 与MCP互补,形成完整AI协作生态 缺点: ● 实现复杂度高,需要处理任务队列和状态管理 ● 部署成本大,需要专门的A2A Server ● 目前生态尚不成熟,工具数量有限 ● 对系统资源要求较高,特别是长时间运行任务 A2A最适合复杂、多步骤的协作任务,如企业级应用、客户服务系统、项目管理等。例如,一个统一的客户服务系统,可以协调多个专门处理不同问题的智能体,共同解决客户复杂需求。 五、协议选择与集成策略 在实际应用中,选择合适的协议取决于具体场景和需求。以下是三种协议的适用场景和集成策略:
  4. Function Call的应用场景 Function Call最适合简单、同步的API调用场景,如: ● 实时数据查询(天气、股票、新闻等) ● 单步骤操作(发送邮件、创建文件等) ● 与特定平台API的集成(如OpenAI的API) ● 快速原型开发和小规模应用 集成策略: ● 直接使用OpenAI等平台提供的API客户端 ● 定义清晰的函数Schema,确保模型能正确生成调用请求 ● 实现参数验证和错误处理逻辑 ● 对于复杂任务,可结合多个函数调用,但需手动管理流程
  5. MCP的应用场景 MCP最适合需要连接多种工具的AI应用,如: ● 开发工具链集成(代码编辑器、IDE插件等) ● 多工具协作场景(如结合数据库查询和API调用) ● 跨平台工具调用 ● 降低工具集成成本 集成策略: ● 部署Nacos-MCP-Router作为服务发现和路由中心 ● 使用MCP SDK开发工具服务 ● 通过Agent Prompt传递工具信息 ● 结合Nacos实现工具动态注册和发现
  6. A2A的应用场景 A2A最适合复杂、多步骤的协作任务,如: ● 企业级应用(招聘、项目管理、客户服务等) ● 长时间运行任务(如需要几天完成的深度研究) ● 多智能体协作场景 ● 需要任务状态管理和进度跟踪的场景 集成策略: ● 部署A2A Server作为任务管理中心 ● 为每个智能体实现Agent Card并托管在标准路径 ● 使用HTTP/SSE实现流式通信 ● 结合MCP实现智能体与工具的交互 ● 实现任务状态管理和生命周期管理 六、未来发展趋势与挑战 随着AI技术的发展,Function Call、MCP和A2A协议也在不断演进。未来,这些协议将更加标准化、智能化和安全化,推动AI模型与外部世界的深度交互。
  7. 技术趋势 ● 标准化:随着更多厂商加入支持,协议将更加统一,降低跨平台集成成本 ● 智能化:协议将引入更智能的推荐和匹配机制,如基于语义理解的工具推荐 ● 安全增强:加强数据加密、身份验证和访问控制,确保智能体协作的安全性 ● 多模态支持:扩展对音频、视频等非文本内容的支持,丰富智能体交互方式 ● 边缘计算集成:支持在边缘设备上部署智能体,实现低延迟本地交互
  8. 面临挑战 ● 生态成熟度:目前协议的生态尚不完善,工具数量和质量有待提高 ● 性能优化:长时间运行任务和大规模协作场景下的性能问题 ● 跨厂商兼容:不同厂商对协议的实现可能存在差异,影响互操作性 ● 用户体验:如何在复杂协作中保持良好的用户体验和交互流畅性 ● 法律与伦理:智能体协作可能带来的责任归属、隐私保护等问题 七、总结与建议 Function Call、MCP和A2A协议代表了大模型与外部世界交互的三个关键范式。Function Call解决了模型调用工具的问题,MCP实现了工具调用的标准化,A2A则解决了智能体协作的通信问题。这三种协议共同构建了一个让AI模型真正"动起来"的技术生态系统。 对于开发者而言,建议根据具体场景选择合适的协议: ● 对于简单API调用,可直接使用Function Call ● 对于需要连接多种工具的场景,应优先考虑MCP ● 对于复杂协作任务,如企业级应用,应使用A2A 在实际应用中,可以将这三种协议结合使用,形成完整的AI应用架构。例如,一个智能客服系统可以使用Function Call调用实时数据API,通过MCP连接多种工具(如数据库查询、文件处理等),并通过A2A协调多个智能体(如问题分类、解决方案生成、用户反馈处理等)共同完成服务。 随着AI技术的发展和这些协议的不断成熟,我们期待看到更多创新应用的出现,让AI模型真正成为连接数字世界与现实世界的桥梁。 说明:报告内容由通义AI生成,仅供参考。