大模型AI经常要用到的function calling和mcp,是什么,有什么关系。
一段话说重点:总的来说,function calling是一种大模型调用外部工具函数的能力,而mcp则是对这些工具函数约定的协议。
开头
AI比较火,大模型主要能力还是基于文字输入给文字输出,有些大模型支持多模态输入。最近agent更火了,到处都提到要用function calling&mcp,那么这俩是啥呢,有啥区别呢。

function calling
Function Calling(函数调用),定义大概是,可以将其视为大语言模型(LLM)与外部工具(如函数、API)交互的桥梁,这样当模型无法直接回答问题时,会主动调用预设的工具函数,获取外部信息或执行操作,再将结果整理成自然语言回答用户。
Function Calling让大语言模型突破了"仅靠内部知识回答"的局限,能像人类一样"调用工具"解决问题。无论是计算、查数据,还是操作软件,都能通过这种机制实现人机协同。
这是一个用function calling调用加法函数的例子,时序图。

这是一个function calling的python示例代码
for tool_call in tool_calls:
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments or "{}")
print(f"[Demo] 处理工具调用: {function_name},参数: {arguments}")
if function_name == "add_numbers":
print("[Demo] 执行 add_numbers")
result = add_numbers(arguments["a"], arguments["b"])
elif function_name == "subtract_numbers":
print("[Demo] 执行 subtract_numbers")
result = subtract_numbers(arguments["a"], arguments["b"])
else:
result = "未实现的函数调用"
print("[Demo] 遇到未实现函数:", function_name)
print(f"[Demo] 工具 {function_name} 返回结果: {result}")
messages.append(
{
"role": "tool",
"tool_call_id": tool_call.id,
"name": function_name,
"content": json.dumps({"result": result}, ensure_ascii=False),
}
)
核心代码就是类似这样的,基于返回结果,ai说调用谁就调用谁,也类似dubbo的泛化调用。
因为大模型大部分情况就是文本输入文本输出,不能直接调用外部函数,我们通过一个中间层,封装一下来做函数调用,function calling是中间层对外提供的一种能力,封装到api协议中了。
我觉得大白话就是,先写了个加法函数,add(a:number, b:number),跟ai说:如果你要算加法,就返回一行文本,叫 "call id555 add 1 1"。其中id555表示这个任务的id,用来做链路追踪。
然后当我们问ai:5+8等于几啊?ai真的就返回了一行文本,"call id666 add 5 8",我们解析了一下,就调用add(5, 8),然后算出来13,就跟ai说,刚才id是id666的那个任务,5+8等于13。
这时候ai知道了,就跟我们说,刚刚调用了一次函数,算出来5+8等于13。
如果我们故意把5+8返回乘法40,那ai返回的也会是错误的40。
下面是function calling的大概调用流程,打了日志。可以看看大概什么样的调用流程。如果有兴趣也可以拿代码实际跑一下。
python function_call_demo.py
用户提问:请帮我计算 12 加上 7,然后再计算 20 减去 5。
[Demo] 当前可用的工具: ['add_numbers', 'subtract_numbers']
[Demo] === 第 1 轮请求开始 ===
[Demo] 请求前消息: {'role': 'user', 'content': '请帮我计算 12 加上 7,然后再计算 20 减去 5。'}
[Demo] 收到模型响应。
[Demo] 模型文本回复:
[Demo] 模型请求调用 2 个工具。
[Demo] 处理工具调用: add_numbers,参数: {'a': 12, 'b': 7}
[Demo] 执行 add_numbers
[Demo] 工具 add_numbers 返回结果: 19
[Demo] 处理工具调用: subtract_numbers,参数: {'a': 20, 'b': 5}
[Demo] 执行 subtract_numbers
[Demo] 工具 subtract_numbers 返回结果: 15
[Demo] === 第 1 轮结束(工具调用完成,继续下一轮)===
[Demo] === 第 2 轮请求开始 ===
[Demo] 请求前消息: {'role': 'tool', 'tool_call_id': 'call_IqoD62Fq29NMe3VOsRX2OnWw', 'name': 'subtract_numbers', 'content': '{"result": 15}'}
[Demo] 收到模型响应。
[Demo] 模型文本回复: 12 加上 7 的结果是 19,20 减去 5 的结果是 15。
[Demo] 模型未请求任何工具。
助手回复:
12 加上 7 的结果是 19,20 减去 5 的结果是 15。
[Demo] === 第 2 轮结束 ===
MCP
MCP 是一种开放协议,它规范了应用程序如何为大型语言模型提供上下文。
如果服务端做的多一些,大概理解为mcp就是一种协议定义,类似dubbo,做好了一系列的封装,工具定义和发现这些,这样开发mcp的tool以及注册到mcp client时,就更标准,更方便。
下面就是基于FastMcp来定义的mcp函数。

而使用的时候,还是当function calling的tools参数传给大模型,和function calling差不多,只不过基于返回结果,会根据协议去调用mcp的函数。
这是mcp的一个示例执行过程,其中加法我还是直接使用函数调用作为mcp传入,减法是单独起了一个mcp server。
python function_mcp_demo.py
[Main] 减法服务器线程已启动。
用户提问:请作为 MCP 客户端,先调用 mcp_add 计算 42 和 58 的和,再调用 mcp_subtract 计算 100 减 37。
减法服务器已启动:http://127.0.0.1:8725/subtract
[Main] 当前可用的 MCP 工具: ['mcp_add', 'mcp_subtract']
[Main] === 第 1 轮 AI 请求开始 ===
[Main] 请求前最后一条消息: {'role': 'user', 'content': '请作为 MCP 客户端,先调用 mcp_add 计算 42 和 58 的和,再调用 mcp_subtract 计算 100 减 37。'}
[Main] 收到 AI 响应。
[Main] AI 返回内容: ''
[Main] AI 发起工具调用: 2 个
[Main] 处理工具调用: mcp_add,参数: {'a': 42, 'b': 58}
[Main] 使用本地函数处理 mcp_add
[Main] 工具 mcp_add 返回结果: 100
[Main] 已写入工具响应消息,tool_call_id=call_66GVxRsnrvgdlMdt9zVuIFgy
[Main] 处理工具调用: mcp_subtract,参数: {'a': 100, 'b': 37}
[Main] 调用减法服务器处理 mcp_subtract
[SubtractServer] 收到 HTTP 请求: POST /subtract
[SubtractServer] 请求参数: {'a': 100, 'b': 37}
[SubtractServer] 返回结果: {'result': 63}
[Main] 工具 mcp_subtract 返回结果: 63.0
[Main] 已写入工具响应消息,tool_call_id=call_D8TsFUymRqM0SzoMBHnteIm8
[Main] === 第 2 轮 AI 请求开始 ===
[Main] 请求前最后一条消息: {'role': 'tool', 'tool_call_id': 'call_D8TsFUymRqM0SzoMBHnteIm8', 'name': 'mcp_subtract', 'content': '{"result": 63.0}'}
[Main] 收到 AI 响应。
[Main] AI 返回内容: '计算结果如下:\n- 42 和 58 的和是 100。\n- 100 减去 37 的结果是 63。'
[Main] 本轮 AI 未请求任何工具。
助手回复:
计算结果如下:
- 42 和 58 的和是 100。
- 100 减去 37 的结果是 63。
[Main] === 第 2 轮结束 ===
减法服务器已关闭。
结语
总的来说,function calling是一种大模型调用外部工具函数的能力,而mcp则是对这些工具函数约定的协议,都是为了让大模型能对客观世界造成影响,提供的能力。后面再讨论A2A以及更多的agent框架吧。