本文从为什么需要Function calling和MCP、分别如何实现的、二者有什么关系三个角度来分析。

Function calling

传统的大模型本质上只是一个聊天机器,基于喂给她的训练知识对用户提出的问题进行预测,但无法感知周围环境的变化也无法改变周围环境(比如操作文件、数据等),为了把后端能力和大模型结合起来,人们设计的初步方案是硬编码:后端根据正则匹配判断需要调用的函数,基于字符串匹配提取调用参数:

但是这种硬编码的方式很容易误判,而这个匹配和提取这种功能正好是LLM所擅长的,所以提出将这部分任务前置给LLM,由模型判断调用什么函数、提取的参数是什么,并直接告诉后端如何去操作;后端只需要负责执行就ok。在该部分有两个阶段的设计:

1、基于提示词的Function Calling

想象一下我们刚开始与大模型进行交互的时候,那时候大得多的教程都是“每次对话开始前,你需要给定你的大模型一个角色,以便他给你更准确地的回复”,其实这就是prompt的口语化的使用方式,实际开发者在设计时,会写一个system prompt,会基于用户提供的这些内容提取关键信息,并作为后续给后端发送命令的参考。

System Prompt 示例:
```
# 你的角色
你是一个函数调用助手,我将提供多个函数的定义信息...

# 你的任务
- 根据用户的输入,判断是否需要调用某个函数
- 如果需要,请严格按照以下格式输出:
  {"name": "函数名", "arguments": {"参数名": "参数值"}}

# 函数定义信息
1. get_weather - 作用:查询指定城市的天气
   参数:city (string) - 城市名称
2. get_time - 作用:查询指定城市的当前时间
   参数:city (string) - 城市名称
```

存在的问题:但是其一,这个system prompt的模板是开发者自行编写的,很难避免遗漏关键信息或者调用格式不准确的问题;其二,即便提示词写的很完美,大模型也可能出现幻觉问题,编造原本不存在的函数名或者格式;其三,为了尽可能保证准确,设计prompt时可能需要加入大量规则说明,这些加入到后续的对话中可能造成很大的冗余,占用大量上下文空间。

2、基于API的Function Calling

针对可能出现幻觉的问题,大模型提供商通过有监督微调(supervised few shot, SFT)和强化学习(RL),提高模型本身的准确率;针对由开发者编写prompt可能带来的问题,在API层面设置了专门字段,统一规定函数描述格式和调用格式。

API 调用示例:
```json
{
  "messages": [
    {"role": "user", "content": "广州今天天气如何?"}
  ],
  "functions": [
    {
      "name": "getWeather",
      "description": "获取指定城市的天气",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {"type": "string", "description": "城市名称"},
          "date": {"type": "string", "description": "日期"}
        },
        "required": ["location", "date"]
      }
    }
  ]
}
```

存在的问题:各家大模型提供商API格式不统一,切换大模型时需要重新适配,所以出现了“MCP”。

 

MCP

官方定义:MCP 是一个开放协议,用于标准化应用程序向大语言模型(LLM)提供上下文的方式。你可以把 MCP 想象成 AI 应用的 USB-C 接口——正如 USB-C 提供了一种将设备连接到各种外设和配件的标准化方式一样,MCP 提供了一种将 AI 模型连接到不同数据源和工具的标准化方式。

MCP的出现不是为了解决function calling的问题的(幻觉,提取不准确等问题依然可能出现),而是为了解决针对多家API格式不统一导致的适配问题。

基于function calling的方式,工具的执行在AI应用程序的后端,每次接入新的(别人开发的)工具都需要重新写适配代码——补充工具描述、工具代码。

但是实际开发可能面临代码开发冗余,代码跨语言,开发商不提供源码等问题,可以看到这些问题都是由于copy源码时带来的问题,所以想到将这个工具/源码包装起来,将其当作一个黑盒而无需考虑代码语言等的差异,对外暴露一个统一的接口;AI应用后端能自动获取工具的描述信息、定位工具调用入口并执行调用。

工具调用分为两类:

  1. 本地:将代码拉到本地,另起一个进程执行,AI应用通过socket返回标准化返回结果;适合工具开发者提供安装包/源码的情况;
  2. 远程:工具开发者将工具独立部署,封装为标准化API,AI应用只需传入参数并解析返回结果即可得到标准返回结果;适合企业级工具(不暴露源码)。

 

完整架构如下:

组件

1、Host——承载MCPClient的AI应用程序(例如Claude Desktop、Cursor、自定义Agent);

2、client——Host内部实例化,负责与Server交互(每个Client与一个Server1:1连接);

3、server——工具提供方,独立运行的服务(文件系统服务、数据库服务、Web搜索服务等)。

传输协议

1、本地——基于stdio协议传输,通过管道标准输入输出(stdin/stdout),零网络开销,进程与本机同步,简单高效;但是不能多客户端共享(每个host要fork一个子进程)。

2、远程——http+sse,streamable http。一个MCP可以服务于多个客户端。

http+sse的模式下,针对同一个客户端上行和下行时两套独立的消息流,网络抖动时无法匹配;streamable http在同一个逻辑断电可以post也可以get,便于追踪调试。

二者区分

Function calling主要解决AI应用与LLM之间的交互,解析出更规范的调用指令明确工具调用的需求;MCP主要解决AI应用与工具之间的交互,主要针对工具开发商提供的API不统一、开发语言不统一导致的问题。

维度

Function Calling

MCP

关注点

AI应用与大模型的交互

AI应用与工具的交互

能力

解决如何返回调用指令

如何执行指令

定位

模型侧

模型基础设施侧

 

 

 

更多推荐