一文搞懂 MCP、Function Calling 和 A2A

[!info] 阅读导览
全文 7 节:三个关键武器总览(1.1)→ AI Agent(1.2)→ MCP 协议(1.3,含实战搭建 MCP Server)→ Function Calling(1.4,拆解 Cline System Prompt)→ Context Engineering(1.5)→ A2A 协议(1.6)→ 总结(1.7)

flowchart LR
    M[LLM 大模型] ---|Function Calling<br>工具调用协议| A[AI Agent]
    A ---|MCP<br>发现/注册/调用| T[AI Tools<br>MCP Server]
    A ---|A2A<br>发现/任务分配| A2[其他 AI Agent]

单纯的大模型是一个只会聊天的"学霸",而配上 Agent 的大模型将是"万能助手"。你让它"关掉客厅的灯",它不再只是礼貌地回答你"好的,已为您关闭客厅的灯",而是真的动手把灯关了。

1. 一文搞懂 MCP、Function Calling 和 A2A

1.1. 引言:三个关键"武器"

在这场关于智能体(AI Agent)的进化革命中,背后隐藏着三个关键"武器":MCP(Model Context Protocol)、Function Calling 和 A2A(Agent to Agent protocol)。简单来说,MCP、Function Calling 和 A2A 分别代表三种 AI Agent 和外界不同的协作方式:

  • MCP:AI Agent 与 AI Tools 之间的工具发现、注册和调用协议。注意:MCP 并不会和 LLM 直接交互,不要被名字中的 Model 误导了,看完文章你就明白了。
  • Function Calling:AI Agent 与 AI Model 之间的工具调用协议
  • A2A:AI Agent 与 AI Agent 之间的发现与任务分配协议

本文会深入解析 MCP、Function Calling 和 A2A 的协议细节,揭示其背后的本质,以便我们在工作中可以更好地开发、使用 Agent 技术。

1.2. AI Agent

首先,让我们了解一下什么是 AI Agent(人工智能体)?AI Agent 是一种能自主感知环境、自主规划并执行动作,以完成特定任务的智能系统。关于 LLM 和 Agent 的关系,有个形象的比喻——LLM 是 AI Agent 的"大脑",而 AI Agent 是 LLM 的"身体"。

  • 没有 Agent 的 LLM,能力被禁锢在对话和文本生成中,是"思想的巨人,行动的矮子"。
  • 没有 LLM 的 Agent,会退化为一个僵硬的、按固定流程行事的自动化脚本,缺乏应对不确定性的智慧和灵活性。

AI Agent 区别于传统的 SOP(Standard Operation Procedure)和 workflow(工作流),其不同之处在于:传统的方式是基于规则的自动化,有明确的、预设的"如果-那么"规则;而 AI Agent 是基于目标的自主性,能自主规划、执行、调整,能感知环境变化,动态调整策略,能处理模糊、不确定的任务。其本质在于大模型本身所具备的强大语言理解、推理和泛化能力。

一个完整的 Agent 除了大脑(LLM)外,还需要:

  • 感知模块:“眼睛和耳朵”,通过 API、搜索引擎、文件系统等获取外部信息。
  • 工具集:“手和脚”,可以调用各种函数、API、软件等来影响现实。这就是 Function Calling、MCP 等技术的用武之地。
  • 记忆模块:“工作日志和经历”,通过向量数据库或记忆流记录过去的历史,用于长期规划和参考。

接下来,让我们一起看看 AI Agent 是如何用 MCP、Function Calling 和 A2A 技术让大模型从"思想的巨人,行动的矮子"变成"万能助手"的。

1.3. MCP 协议

为了更好的理解 MCP(Model Context Protocol,模型上下文协议),我们需要先实现一个特殊的 Agent,它能自动记录 MCP client 和 server 之间的通信内容。通过解析通信内容,无需多言,你就能明了 MCP 的真谛。

1.3.1. 实现一个 Agent

1.3.1.1. 准备工作

  • 安装 Cline Agent,目前只有 VS Code 的插件
  • 安装 Python,以及 uv 工具(Python 包安装器和解析器),设置镜像源,在环境变量中设置 UV_INDEX_URL=https://repo.huaweicloud.com/repository/pypi/simple/
  • 可用的大模型服务,比如 OpenAI、DeepSeek、OpenRouter 等

1.3.1.2. 创建 Python 项目

mkdir mcpserver
cd mcpserver
# 初始化项目
uv init
# 创建虚环境
uv sync
# 安装 mcp
uv add mcp
# 激活虚拟环境(Windows)
.venv\Scripts\activate

1.3.1.3. 创建 MCP Server

这个 MCP Server 很简单,模拟一个获取天气信息的工具。其代码如下:

from mcp.server.fastmcp import FastMCP

# 一、创建 FastMCP 类
mcp = FastMCP("获取天气信息")

# 二、自定义工具(Stdio 模式)
@mcp.tool("获取天气信息")
def get_forecast(city: str) -> str:
    """
    获取天气信息
    参数:
    city (str): 城市名称
    返回:
    city_forecast : 当前城市的天气信息
    """
    # 这里只是简单的返回一个 Mock,真实场景会调用天气 API
    return city + "明天有大暴雨!"

# 三、初始化 MCP Server
if __name__ == '__main__':
    print("MCP Server is running...")
    mcp.run(transport='stdio')
    print("MCP exited")

除了上面这个 MCP Server 之外,我们还需要一个日志记录工具 mcp_logger.py 用来截获 mcp client 和 mcp server 之间的通信(仅限于 stdio 方式),这个工具可以把通信内容写入到当前目录下的 mcp_io.log 日志文件。

1.3.1.4. 在 Cline 中配置 MCP Server

  1. 在 VSCode 的 Cline 插件上点击"Configure MCP Servers"
  2. 在配置文件中写入启动 MCP Server 的信息,这条配置的意思是:通过"python mcp_logger.py uv run mcp_weather_server.py"命令来运行 MCP Server
  3. 当看到配置界面的 get_forecast 工具为绿色时,表示 MCP Server 已经配置并启动成功了

1.3.1.5. 验证 Agent 使用工具

当我们在任务窗口输入"杭州明天的天气如何",会发现 Cline Agent 在大模型的帮助下,会主动调用 get_forecast 工具,然后成功完成任务。

此时查看 mcp_io.log,会发现它记录了完整的 MCP Client 和 MCP Server 之间的通信内容。

== 初始化阶段 ==
MCP Client发送:
{
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {
},
"clientInfo": {
"name": "CodeMate",
"version": "25.2.200"
}
},
"jsonrpc": "2.0",
"id": 0
}
MCP Server发送:
{
"jsonrpc": "2.0",
"id": 0,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {
"experimental": {
},
"prompts": {
"listChanged": false
},
"resources": {
"subscribe": false,
"listChanged": false
},
"tools": {
"listChanged": false
}
},
"serverInfo": {
"name": "获取天气信息",
"version": "1.16.0"
}
}
}
MCP Client发送:
{
"method": "notifications/initialized",
"jsonrpc": "2.0"
}
== 工具注册阶段 ==
MCP Client发送:
{
"method": "tools/list",
"jsonrpc": "2.0",
"id": 1
}
MCP Server发送:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "获取天气信息",
"description": "\n    获取天气信息\n\n     参数:\n    city (str): 城市名称\n\n    返回:\n    city_forecast : 当前城市的天气信息\n    ",
"inputSchema": {
"properties": {
"city": {
"title": "city",
"type": "string"
}
},
"required": [
"city"
],
"title": "get_forecastArguments",
"type": "object"
},
"outputSchema": {
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "get_forecastOutput",
"type": "object"
}
}
]
}
}
MCP Client发送:
{
"method": "resources/list",
"jsonrpc": "2.0",
"id": 2
}
MCP Server发送:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"resources": [
]
}
}
MCP Client发送:
{
"method": "resources/templates/list",
"jsonrpc": "2.0",
"id": 3
}
MCP Server发送:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"resourceTemplates": [
]
}
}
== 工具调用阶段 ==
MCP Client发送:
{
"method": "tools/call",
"params": {
"name": "获取天气信息",
"arguments": {
"city": "杭州"
}
},
"jsonrpc": "2.0",
"id": 4
}
MCP Server发送:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [
{
"type": "text",
"text": "杭州明天有大暴雨!"
}
],
"structuredContent": {
"result": "杭州明天有大暴雨!"
},
"isError": false
}
}

1.3.2. 解析 MCP 协议

通过日志我们可以看到,MCP 通信内容是基于 JSON-RPC 协议的,JSON-RPC 是我见过最简洁的协议,就像其口号说的,simple is better。

我们把日志转换成时序图,不难发现,整个通信过程分为 3 个阶段:

  • 初始化阶段:也就是 MCP Client 和 MCP Server 的握手过程。通常,MCP Client 是以内置组件的形式存在于 Agent 内部。
  • 工具注册阶段:MCP Client 会询问 MCP Server,你有哪些可用的 tools(工具)、resources(资源)、templates(模板)。MCP Server 会按照规定的格式返回对应的能力描述。
  • 工具调用阶段:当大模型需要调用工具时,会告诉 Agent,你需要用 {"city": "杭州"} 这个参数,去调用下 get_forecast 这个工具。MCP Client 知道这个工具是"获取天气信息"这个 MCP Server 提供的,调用即可。

这就是 MCP,其本质就是支持 AI Agent 用一种通用的方式发现、注册、调用外部的工具,从而协助 LLM 完成用户任务。等等,大模型怎么知道要在什么时候调用工具,以及用什么方式调用工具呢?

1.4. Function Calling(大模型为什么知道要调用哪个工具)

当我问"杭州明天的天气如何"的时候,大模型为什么知道要调用 get_forecast 这个工具呢?实际上,这就是大模型的 Function Calling,而这个能力需要我们通过 prompt 的方式来教大模型。这个能力正是大模型区别传统 SOP 的关键:用非结构化的"柔性",完美克服了传统规则的"刚性"

我们可以通过查看 Cline 的源码来理解 Agent 是如何"指导"大模型进行 Function Calling 的。你可以在此查看:Cline 的完整 system prompt,整个 prompt 有 600 行,将近 50K 大小,总共 13000 个字符,会消耗 5000 个 tokens。这就是为什么很多人吐槽 Cline Agent 烧 Token 的原因。内容比较多,我们截取里面部分内容分析一下,你就明白为什么大模型有能力调用工具了。

1.4.1. 身份声明

首先给模型戴个高帽子,你是个软件高手!因为 Cline 是 coding agent,当然要如此声明。可能还有个附加好处,直接激活 MoE,帮服务端省点电费。

You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.

1.4.2. 能力声明

亮明身份之后,还要声明所具备的能力(capabilities),即告诉大模型:

  1. 你能推理任务,并且 step-by-step 地使用工具,完成任务。这是客户端能变成 Agent 的关键,即让模型遵循 ReAct(Reasoning+Acting)模式,处理用户任务。
  2. 你能使用工具,且会用 XML 的格式与我沟通。不同的 Agent 会选择不同的格式,Cline 是用 XML,也可以是 JSON。
TOOL USE
You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
# Tool Use Formatting
Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
<tool_name>
<parameter1_name>value1</parameter1_name>
<parameter2_name>value2</parameter2_name>
...
</tool_name>

1.4.3. 系统工具能力

Cline 作为 coding agent,已经内置了一些工具,主要是和写代码相关的。包括 execute_command(执行命令)、read_file(读文件)、write_to_file(写文件)等。这里有一个工作目录(working directory)的概念,为了安全性考虑,文件操作只被允许在 working directory 下面。因此,在实际使用 Cline 之前,我们需要搞清楚当前的 working directory 是在哪里。

## execute_command
## read_file
## list_files
## write_to_file
Description: Request to write content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
Parameters:
- path: (required) The path of the file to write to (relative to the current working directory ${cwd.toPosix()})
- content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified.
Usage:
<write_to_file>
<path>File path here</path>
<content>Your file content here</content>
</write_to_file>

1.4.4. MCP 扩展工具能力

除了 Cline 的内建工具之外,当然少不了用户自定义的扩展工具,比如我们案例中的 get_forecast 工具,之所以我们的 Agent 会调用 MCP Server 的 get_forecast 工具"获取天气信息",正是因为我们在 1.3 章节中注册了 get_forecast MCP 工具。对于 Cline Agent 而言,所谓的工具注册,就是在 Cline 发送给大模型的 prompt 中加入了如下的功能描述信息。这些提示词和内建工具的提示词类似,都是在"指导"大模型,教它有这些工具的能力(capabilities),从而实现 Function Calling。

# Connected MCP Servers
When a server is connected, you can use the server's tools via the `use_mcp_tool` tool, and access the server's resources via the `access_mcp_resource` tool.
## weather (python mcp_logger.py uv run mcp_weather_server.py)
### Available Tools
- get_forecast: 获取天气信息
Args: city: 城市名称
Input Schema:
{
"type": "object",
"properties": {
"city": {
"title": "city",
"type": "string"
}
},
"required": [
"city"
],
"title": "get_forecastArguments"
}

1.4.5. 完成任务

当完成所有 subtask、迭代执行完所有 tools、达成任务目标后,大模型需要通过 attempt_completion 通知 Agent 任务完成,并在最终回复中呈现任务执行结果。如果需要演示(demonstrate),也可以提供演示的 CLI,但这是可选的。

## attempt_completion
Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. Optionally you may provide a CLI command to showcase the result of your work. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again.
IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in code corruption and system failure. Before using this tool, you must ask yourself in <thinking> tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool.
Parameters:
- result: (required) The result of the task. Formulate this result in a way that is final and does not require further input from the user. Don't end your result with questions or offers for further assistance.
- command: (optional) A CLI command to execute to show a live demo of the result to the user. For example, use `open index.html` to display a created html website, or `open localhost:3000` to display a locally running development server. But DO NOT use commands like `echo` or `cat` that merely print text. This command should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions.
Usage:
Your final result description here
Command to demonstrate result (optional)

1.5. Context Engineering

通过上文对 Cline System Prompt 的解读,你会发现,Agent 的本质就是一个精心设计的 Prompt。因为大模型本质上是"上下文学习者":它们没有长期的记忆,每次交互都是独立的。你提供的上下文就是它此次交互的全部世界。

因此,要想实现完整的 Agent 功能,在传递给 LLM 的信息中,除了 System prompt、user message 之外,还要包括 Docs(领域知识,工作对象等)、工作记忆(Message history)等。把这些内容都汇总起来就是 LLM 需要的 Context(上下文),而这个汇总(精炼、压缩)的工作就叫 Context Engineeringhttps://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents)。

这也是 Context Engineering 和 Prompt Engineering 的主要区别。

回过头来,你应该就能理解我在开篇说的,MCP 是和模型无关的协议。MCP 只是一个为了 Model 的 Context 而服务的 Protocol。它既不和 Model 交互,也和 Model 无关。它只是给 Context Engineering 服务的一环。

1.6. A2A 协议

Agent 的本质是 Context,像 Cline 这样的 Agent,通过 MCP 扩展的工具能力使用说明,都是放在 prompt 里,工具不多还好,如果很多,可能会撑爆 Context Window,即使不会撑爆,过长的 Context,也会引发 Context Rot(https://research.trychroma.com/context-rot)问题。这和我们人类的认知类似,信息越多,越难 focus,越难抓住重点。

关于如何提供有效的、长度适中的 Context,是 Context Engineering 的关键。在 Context Engineering 一文中有详细阐述。常用的技术有 Compaction(压缩)、Structured Note-taking(结构化笔记),以及 Multi-Agent architectures(多 Agent 架构)。所谓的 Multi-Agent,就是从 Agent 层面做分而治之,从而控制单个 Agent 的 Context 长度。

而多 Agent 之间的协作,就涉及到 A2A 协议,即 Agent to Agent 协议。

A2A 是 Google 开源的开放协议。其包含如下核心概念:

概念 描述
Agent Card(卡片) 位于 /.well-known/agent.json,描述能力、技能、端点 URL 和认证要求,用于发现
A2A Server(服务器) 实现协议方法,管理任务执行
A2A Client(客户端) 发送请求如 tasks/send 或 tasks/sendSubscribe,消费 A2A 服务
Task(任务) 核心工作单位,有唯一 ID,状态包括 submitted、working 等
Message(消息) 通信单位,角色为 user 或 agent,包含 Parts
Parts(部分) 内容单位,包括 TextPart、FilePart、DataPart
Artifacts(工件) 任务输出,包含 Parts
流式传输 使用 SSE 事件更新长期任务状态
推送通知 通过 webhook 发送更新

和 MCP 一样,A2A 采用的也是 JSON-RPC 协议,其工作机制也很类似,主要包括 Agent 的发现、注册和使用,通信细节不再赘述,大致流程如下:

  • 发现:客户端从 /.well-known/agent.json 获取 Agent Card,了解智能体的能力。
  • 启动:客户端发送任务请求。
  • 处理:服务器处理任务,可能涉及流式更新或直接返回结果。
  • 交互(可选):若任务状态为 input-required,客户端可发送更多消息,使用相同 Task ID 提供输入。
  • 完成:任务达到终端状态(如 completed、failed 或 canceled)。

1.7. 总结

单纯的大模型,只能对话和生成文本,是"思想的巨人,行动的矮子"。配上 Agent 的大模型,能感知环境、使用工具、执行任务,成为"万能助手"。AI Agent 的核心在于 Context Engineering,背后需要依赖三大关键技术:MCP、Function Calling 和 A2A。这三项技术,并不是有你无我的排斥关系,而是可以通力协作的互补关系。大模型通过 Prompt 学习工具使用,实现非结构化任务处理,克服传统规则的"刚性",使得 AGI(Artificial General Intelligence,通用人工智能)成为可能。

[!success] 核心要点

  • 三大协议定位:MCP 连接 Agent↔Tools(发现/注册/调用),Function Calling 连接 Agent↔LLM(工具调用),A2A 连接 Agent↔Agent(发现/任务分配),三者互补协作
  • MCP 本质:基于 JSON-RPC,三段式通信(初始化握手 → 工具注册 → 工具调用);MCP 不直接与 LLM 交互,只为 Model 的 Context 服务
  • Function Calling 真相:Agent 把工具描述写进 System Prompt,"教"大模型何时调用、如何调用——Cline 的 prompt 600 行、近 50K 就是例证
  • Agent = Context:把 System prompt、User message、Docs、记忆等汇总精炼,就是 Context Engineering
  • A2A 核心:Agent Card(/.well-known/agent.json)发现 → tasks/send 任务分配 → SSE 流式更新 / webhook 推送