MCP 与 Function Calling的前世今生

111 阅读5分钟

Function Calling的起源

系统提示词

我们使用常规提示词时通常这样提问

用户:我肚子疼
大模型:如有不适请就医

为了让大模型回答的更符合我们的要求,可以在用户提示词里加入一些角色限定

用户:你是我的直男男朋友,我肚子疼
大模型:多喝热水

为了避免用户在提示词里输入繁琐的角色限定,可以给大模型加入系统提示词

System Prompt: 你是我的直男男朋友
用户:我肚子疼
大模型:多喝热水

在系统提示词里可以加入角色性格、背景知识、能力、语气等等

image.png

智能体的出现

当给大模型加入了丰富的系统提示词后,大模型能做的事情就很多了,比如我现在有两个工具,一个list_files能列目录,一个read_file能读文件。将能列目录和能读文件这两个能力(工具)作为系统提示词给到大模型,系统提示词如下:

System Prompt:你现在有两个工具,list_files能列目录,read_file能读文件,如果想使用就返回我要调用+工具名

当用户提问:帮我找wps安装目录,我们将用户的提问给到大模型,大模型会思考后回答"我要调用list_files",这个时候我们从大模型的回答解析出工具名称“list_files”,然后我们调用工具“list_files”,将调用结果给到大模型,大模型组织好语言后返回给我们,最终呈现给用户。

上述的“我们”就是一个智能体,能集成各种工具,将集成后的工具作为系统提示词给到大模型,根据大模型的回答调用相应的工具,并将工具调用结果给到大模型,最后大模型组织后语言后呈现最终结果。

image.png

系统提示词的弊端

当用System Prompt告诉大模型有哪些工具可以调用时主要有以下缺点

-指令遵循性不足
-缺乏标准化,容易失控
-更新麻烦

Function Calling

Function Calling的出现就是为了解决System Prompt的弊端

Function Calling(函数调用)核心是通过生成结构化指令,引导外部程序执行特定任务,并将结果反馈给模型

智能体通过结构化的指令来告诉大模型有哪些工具可以调用,当需要调用工具时大模型以结构化的指令输出给智能体,智能体可以很方便的解析出需要调用的工具。Function Calling 是一种大模型的能力,有些大模型支持有些可能不支持,并且Function Calling由大模型厂商各自定义,没有统一标准。

image.png

比如 OpenAI 的 function calling(即 tools)应为如下格式,每个 tool 是一个JSON 对象

tools = [
    {
        "type": "function",
        "function": {
            "name": "search_projects",
            "description": "根据项目名称在gitee代码平台上进行模糊搜索",
            "parameters": {
                "type": "object",
                "properties": {
                    "project_name": {
                        "type": "string",
                        "description": "要进行模糊搜索的项目名称"
                    }
                },
                "required": ["project_name"]
            }
        }
    },
    # 其他函数同理
]

Claude(Anthropic)Function Calling规范应为如下格式

tools = [
    {
        "name": "search_projects",
        "description": "根据项目名称在gitee代码平台上进行模糊搜索",
        "input_schema": {
            "type": "object",
            "properties": {
                "project_name": {
                    "type": "string",
                    "description": "要进行模糊搜索的项目名称"
                }
            },
            "required": ["project_name"]
        }
    }
]

为什么需要MCP

有了Function Calling,为什么还需要 MCP 呢?MCP也是一种规范,Function Calling只是解决了智能体平台如何告知大模型有哪些工具调用的规范,但是各个智能体平台有各自的接入工具的规范,比如,一个工具在coze平台上使用,但是不能在 Dify 平台上使用,这时候同一种工具就得开发多种来适配不同的智能体平台。

image.png

MCP就是定义了一种规范,它统一了函数调用的运行规范和统一MCP客户端和服务器的运行规范,只要遵循这种规范开发工具,就能在多个平台使用

image.png

MCPServer 除了定义工具还定义了Resources、Prompts等

image.png

举个例子

image.png

在初始化的时候,智能体(MCP Client)会调用MCP Server获取工具列表,然后按照当前接入的大模型的Function Calling规范给到大模型,大模型知道了有哪些工具调用,当用户问明天深圳的天气,由于大模型训练的数据在大模型的问世的时候就已经停止了,不知道最近发生的一些事情,大模型思考后以结构化的形式告知智能体需要调用查询天气的工具,智能体解析出工具后调用工具,拿到结果后给到大模型,大模型再组织语言给到智能体,最后呈现给用户。

总结

Function Calling和 MCP都是规范,前者相当于是规范了System Prompt,以结构化的形式告诉大模型有哪些工具可以用,并以结构化的形式告诉智能体如何调用工具,它的弊端是由大模型厂商各自定义,没有统一标准。后者相当于是规范了智能体平台,按照 MCP 规范开发的智能体平台接入的 MCP server 是通用的。

由于Function Calling由大模型厂商各自定义,没有统一标准,大模型与MCP Client 交互的适配工作在 MCP Client 中完成,例如如果接入了一个不支持fucntion calling的模型,在客户端做的适配工作类似以提示词的方式告诉大模型有哪些工具可以调用,当需要调用工具时按照xxx格式返回,客户端再从大模型的返回中解析出要调用的工具,不管大模型有没有支持fucntion calling,支持什么形式的fucntion calling,适配工作在客户端完成。