2025-05-18 | 马克的技术工作坊 | MCP 与 Function Calling 到底什么关系,以及为什么我认为大部分人的观点都是错误的

Function Calling 与 MCP 的关系解析及共存原理

媒体详情

上传日期
2025-06-10 19:15
来源
https://www.bilibili.com/video/BV15YJTzkENC/
处理状态
已完成
转录状态
已完成
Latest LLM Model
gemini-2.5-pro-preview-06-05

转录

下载为TXT
speaker 1: 自anthro公司推出mcp之后,有很多人把function calling与mcp做了类比,其中流传最广、最为常见的一种说法便是mcp统一了function calling的协议,有了mcp之后,function calling便没有存在的必要了。 这种说法到处可见,流传极果甚至还会出现在各类专业的科普视频和科普文章中。 乍一看啊这种说法好像是对的,毕竟这两者做的都是调用工具相关的事情。 而mcp更加的标准,那肯定是mcp取代方申calling了。 但实际上这种说法其实是有很大问题的,function calling和mcp并不是互相替代的关系,而是互补的关系,他们在大模型领域所处的地位完全不同,在未来很长的一段时间里,function calling和mcp都将同时存在,各自发挥自己的价值。 实际上,在mp中极指南的基础篇中,我也提到过,function calling和P甚至可以同时出现在一个链路中,因为他们在链路中所扮演的角色完全不同。 为了帮助大家搞清楚function col和mcp之间的关系,我做了本期视频给大家全方位介绍一下function calling主要是覆盖了function calling的具体概念、使用方法和协议细节,让大家彻底明白function calling到底是个什么东西,与mp的关系呢到底是怎么样的。 最后在视频的结尾,为了验证我的说法,我将演示如何在一个链路中同时使用function col和M C P。 此外,本视频所有的代码均会放在这个get up仓库中,有需要的请自行查看。 在通常情况下,一个模型训练好了之后,它的知识库就有定格了。 对于超出知识库范围的答案,它无法给你满意的回复。 用经典的问答场景举例,用户问模型一个问题,模型就只能从自己的知识库里面寻找答案。 如果用户问的问题超出了模型的知识范围,模型要么回答不知道,要么就胡言乱语。 那现在试想一下,如果模型有一种方式能够调用天气接口,拿到纽约最近几天的天气信息的话,那模型是不是就可以回答这个问题了呢? 没错,这就是function calling所提供的能力了。 简单来说,function calling指的是模型与外部工具交互的一种能力。 在这些外部工具中,有些可以用来查询天气,有些可以用来查询新闻,有些可以用来发送邮件,这些呢都统称为外部工具。 不过这个图其实有些问题,因为模型自己其实是无法调用工具的,他想调用的话还需要一个中间人来帮他做这件事情,这个我们后面会详细展开,暂时你不必细究。 另外工具这种说法比较抽象,换一个词更合适一些,那就是函数。 没错,工具本质上就是编程语言里面的函数。 还是以我们前面的天气预告来举例,假如说我们想要使用查询天气的工具,那本质上可能就是要调用这个叫做get forecast的函数。 你传入所查地区的经纬度就可以拿到对应的天气预告结果。 在这个过程里面,我们既可以说是使用了查询天气的工具,也可以说是调用了查询天气的函数,这两种说法都是一样的。 再回头想想function calling这个词,那不就是函数调用吗? 所以使用工具就是调用函数。 说白了function col就是模型调用函数的一种能力。 在调用函数之后我们不是可以拿到函数的返回结果吗? 模型就可以从这个结果中总结答案,再告诉用户纽约明天的天气信息是不是还是感觉有些抽象。 没关系,我们可以拿check gt来举个具体点的例子辅助你理解。 首先在输入框中输入纽约明天的天气怎么样,然后我们点击发送。 此时从界面中可以看出,gbt先搜索了网络,搜索结束之后才给出了最终答案,我不清楚它背后是用什么原理完成这套流程的,毕竟是close AI嘛,除了早期的模型之外什么也没有open,不过我可以肯定的是,这套流程用function calling的方式是肯定可以完成的,而且呢它大概率用的就是function,因为这个技术就是OpenAI发扬光大的。 所以后面我假设他用的就是方声考里给你画一下整体的链路图,让你看看他整个链路是怎么运转的。 当然我要提前给大家打个预防针,如果OpenAI不是用方声call令来实现搜索功能的话,请你也不要喷我。 我不是来探讨OpenAI是如何实现搜索的,我是要以这个操作为例,讲一下方calling的具体流程。 后面我们还要用方calling的形式来做一个跟它一样的链路,先搜索再回答。 所以我向你保证这个链路用function calling来实现绝对是没有问题的。 首先整个链路至少有两个角色,用户和chat。 Gbt应用大致流程是,用户发送问题给check gbt应用,check gbt应用返回答案给用户,注意,我这里所说的check g应用不是指gbt 4O模型,而是包括gbt 4O模型在内的一个完整的用户产品,也就是我们前面演示的时候所使用的这整个的应用,它不仅能够调用模型,还能够搜索网络、存储历史对话内容等等,跟g 4O模型呢并不是一回事。 好,那说明完了g应用的概念,我们再回来继续看看链路,当用户的请求发送给chat gbt应用之后,会发生很多事情,chagbt应用会调用OpenAI的服务器,OpenAI的服务器又会调用gbt 4O的模型,还会搜索网络等等。 所以为了把事情解释清楚,我们需要把check g应用拆分为三个角色,分别是网络搜索函数、open服务器和GPT 4O模型。 到这里为止,我们的四大boss就算是集齐了。 下面我们就要研究下这四个boss在这段时间里面到底是干了些什么事情。 一开始用户的问题会发送给open服务器,open服务器接到问题之后,会把用户的问题转发给模型。 不过同时给到模型的不仅仅是用户问题,还有可用的工具,比如搜索网络、搜索文件之类的,这其实就是告诉模型用户想知道这个问题的答案,你看看你能不能直接回答,如果可以的话,就直接给我答案好了,否则我这里还有些工具,你看看能不能用上,想掉哪个跟我说。 模型接到了OpenAI服务器的请求之后,先评估了下用户。 要问明天的天气是吧? 那我自己肯定是回答不出来的。 我的知识到今年1月份就截止了。 不过好在这里有个搜索网络的工具啊,我要不就用它先搜索网络吧,于是模型就决定要使用这个工具了。 不过注意模型的功能呢只是接受用户的问题,返回对应的答案,它本身呢其实是没有使用工具的能力的那谁能使用工具呢? 当然是op服务器了,所以这里模型仅仅是返回了一个工具使用请求给到了opair服务器告诉他我想要使用搜索网络这个工具,工具参数是纽约明天的天气。 请帮我调用一下吧opai服务器接到请求之后调用了对应的网络搜索函数,函数执行完毕之后返回了对应的结果。 Op服务器拿到结果之后又紧接着把它发挥给了模型,模型接到结果后,根据用户问题总结了一份最终的答案,并把它发给了op服务器,op服务器再把答案返回给用户,整个对话到此就结束了,这就是我们刚才问完问题之后所发生的事情。 那你可能不禁要问,列路,我明白了,方calling在哪呢? 别着急,我们不妨先猜猜看。 首先function calling翻译成中文是函数调用,那这个链路里面哪个地方在调用函数呢? 没错,就是这个地方了。 那function calling肯定就发生在这个环节里面了,对吗? 不对,这个呢就是很多人理解上第一个错误了也正是这个想法让很多人认为mp会取代function calling,毕竟都在干调用函数的事情嘛。 实际上虽然function calling这个名字的含义呢是函数调用,但是它本身并没有规定对应的函数到底是如何调用的,所以它跟红色框里面的这一部分几乎没有什么关系。 Function calling这个名字呢有一定的误导性。 我们再回忆一下之前所说的function calling的概念。 Function calling是模型调用函数的一种能力,这种能力呢是需要一个中间人去参与的。 在我们的链路里面,这个呢是模型,这个呢是函数。 Open a服务器呢就是那个中间人。 不过光有这三个角色还不够,想要搞清楚方call令到底是什么,我们还需要把模型这个角色再具体细化一下。 首先我们这个链路用到了gp 4o模型,但这个地方写GPT 4O模型呢并不准确。 Op服务器调用的并不是gp 4o模型,它调用的其实是g 4O模型的api,这个api呢就是一个http接口,这个接口内部所调用的才是真正的g 4O模型。 在api拿到请求之后,他会把这个请求做个转换,发给真正的g p 4O模型gbd 4O模型返回结果之后,对应的api还会再把模型的结果再做一次转换,通过api接口发送出去。 解析工具调用结果的这一部分呢也是如此。 Api先将工具执行结果给到模型,模型解析之后再返回最终答案。 那你可能会问,模型的输入和输出还会跟模型api的输入和输出不同吗? 怎么中间还有个转换呢? 对,确实是不同。 由于模型训练方法的差异,每个模型能接受的参数格式以及它输出的内容格式都会有所不同,所以这一层转换是必须的那再回忆一下,我们前面说过function calling指的是模型调用函数的一种能力模型在这里函数呢也通过参数传给模型了。 所以严格来说function calling是作用在这一部分的。 具体来说,如果模型能够挑选函数解析函数执行结果,并且根据结果给出最终答案的话。 那么我们就称模型有function calling的能力。 不过啊我相信大家基本上都没有跟模型直接打过交道,顶多呢就是调用个模型的api实际上对于gp t 4O这种闭源模型,你也没法跟他打交道,你连模型都拿不到还打什么交道呢? 你能做的就是通过模型的api来间接的使用g 4O的模型。 所以在大部分情况下,我们会把方号令的概念稍微的变一变,把它变为模型api调用函数的能力。 具体指代的呢就是这一部分的内容。 仔细看一看,这两部分其实本质上是一样的,都是从函数列表里面挑选函数的能力。 只不过一个呢是用模型api在挑选,一个呢是用模型在挑选。 一般情况下只要模型有了function calling的能力,对应的模型api也必将有function calling的能力。 毕竟模型api与模型之间也仅仅只有一些转换逻辑而已。 由于大部分情况下我们调用的都是模型的api而并非直接调用模型,因此呢我们关注的更多是模型的api是否支持帮衬考领。 鉴于这个原因,在本视频中我们着重讲解的就是模型api的方生call能力,也就是图中正在闪烁的蓝色框的内容。 而对于红色框中涉及的与真实模型进行的一些交互,我们暂时不涉及。 所以呢我们就先把这一部分去掉,以简化流程。 我们现在终于得到了function calling的作用环节了,就是蓝色框显示的这一部分。 不过这个推导过程并不简单,如果你还是不太明白的话,建议你再把这段看一遍。 好,function calling呢作用在这一环节。 如果像很多人所说的那样,function calling和mp是互相替代的关系的话,那mp也必然是作用在蓝色框这一环节的。 但实际上并不是这样子的。 如果你看过我mp终极指南的基础片的话,你就会明白mcp本质上就是一套函数的发现与调用协议,它只作用在服务器和函数之间。 也就是这里mcp呢是规定了服务器如何发现函数,如何调用函数。 Mp本身呢其实跟模型并没有什么直接的关系,跟模型有直接关系的呢是function calling。 注意看这一部分是function calling,这一部分是M C P。 从这里就可以看出,mp与function col分别作用在链路的两个环节发挥的作用各不相同,根本就没有互相替代这一说。 另外,本视频着重讲的是function calling mcp的使用和相关原理将一带而过。 如果你对mcp的运行链路一知半解的话,建议到我的频道主页里面找一下mcp终极指南的基础篇、进阶篇和番外篇三个视频。 这三个视频看下来之后,我保证你可以对mp的使用和运行原理有一个彻底而清楚的了解。 Function calling背后是有一套协议的,这套协议规定了工具列表要怎么传给模型api,而模型api又如何返回所挑选的工具以及对应的参数,各个大模型厂商的function calling协议大致相同。 不过有些细微的区别想要彻底搞懂的话,那肯定还是要看一下这个协议到底写了些什么。 搞懂协议的最好办法就是截获模型api的输入和输出,不过对于前面那个事例,我们是没有办法截取模型api的输入和输出的,毕竟拆g应用又没有开源,所以呢,我借助大模型的力量,写了一个与大模型聊天的应用,我给它起了个名字叫做mark chat,在这个应用里面,我截取了模型api的输入输出,并且打印到了外部文件里。 所以通过分析这个外部文件,我们就可以得知function calling协议到底是个什么样子的。 首先我来给你演示一下mark cha的使用方法,先启动服务器,然后打开127.0.0.1冒号5000这个地址,输入我们的问题。 纽约明天的天气怎么样? 稍等一会儿我们就拿到了答案。 可以看到mark cha的返回一共是包含了两部分的内容。 第一部分是调用了一个叫做search的工具,在网上搜索了下纽约明天的天气预报,并且拿到了工具的调用结果。 第二部分则是模型根据工具的返回结果做出了最终的解答。 整个流程很简单,而且跟我们在chat pt里面看到的流程基本一致,先调工具再做总结。 既然了解了整个流程,我们不妨就进去看看代码,分析一下他到底写了些什么。 Mark chat的代码量其实还挺大的,毕竟前后端都有,不过好在大部分的代码我们根本就不用管,因为这里面绝大多数代码跟function calling都没什么关系,我们着重要看的就是这个back点文件。 打开这个文件之后,我们再找到其中的process user query函数。 当用户问题发给mark chat之后,mark chat便会去调用process user query函数来获取答案。 这个函数里面的代码便是function calling的核心逻辑了。 所以我们来仔细研究一下。 首先这里面的query参数代表的含义是用户的问题。 比如在我们这个例子里面,query的值就应该是纽约明天的天气怎么样。 在接到用户的问题之后,这个函数会把用户的请求内容放入到self点history列表里面。 相信从这个变量的名字里面你也可以看出,self点history代表的就是历史消息。 现在self点history中只有用户的问题,看起来内容比较少。 但是呢后面你就可以看到,我们还会把模型api的工具选择结果,工具的执行结果都放到self点history里面。 并在请求模型api的时候再发给他。 因为模型本身是没有记忆的,所以呢如果模型想要了解之前发生了什么,他就必须要从历史消息里面找。 在处理完了self点history之后,我们调用call model函数,这个函数主要是把用户问题发送给了模型api让他来解答。 模型api呢是从self点history这个变量里面获取到用户问题的,具体实现呢我们后面再看。 然后呢我们把模型ap的返回放入到first model response这个变量中。 First model response值呢大致是这个样子的,它代表的含义是第一次调用模型时,模型的返回结果,其中的核心内容是这里面的message,它里面包含了模型想要调用的函数以及调应的调用参数。 所以呢我们在代码里面先把message提取出来,然后再放到历史消息中。 然后我们检查一下模型是否想要调用工具,如果想的话,我们把工具名称和工具参数提取出来,然后调用self点execute to方法执行工具,再把执行结果放入到历史消息列表里。 再次请求模型api这个呢是第二次请求模型api了。 这次请求的时候,模型api就可以从历史消息列表里面获取到工具的执行结果,并且给出一个最终答案。 我们把这个最终答案抽取出来之后,放入到final message变量中,再把final message也加入到历史消息列表里。 最后我们把所有的信息都放在一起打包返回。 我们之前讲的是有工具调的场景,这个else分支呢便是处理没有工具调的情况。 我们的例子暂时不涉及,所以就不用管它了。 到这里整个方法就告一段落了让我们先复习一下总结总结整个链路里面最重要的几个部分。 第一调用模型A P I,第二提取工具名称和参数,第三调用工具,第四再次调用模型api这次调用的时候,模型api会拿到工具的执行结果,并根据结果做出判断。 第五,返回模型api给出的最终答案。 不知道你是否对这五步有一种似曾相识的感觉呢? 想想我们之前画的这个链路图,这五步其实跟我们前面所聊的这个链路图是一样的。 只不过我们用的不是open的服务器而已,我们用的是mark chat的本地服务器。 那再回来看看代码,在之前梳理链路的过程中,我们漏掉了三个函数的实现。 现在来看看这三个函数里面写了些什么。 第一个是call model,用于在第一次调用模型api的时候使用。 我们来打开看看。 它这里面主要是用post方法请求了open Roder的接口。 Open Roter呢是个大模型调用平台,在其中可以调用各个类型的模型api,包括OpenAI的、cloud的geminite等等,很有名,我在P中极指南的基础篇里面讲过。 当然这里直接换成OpenAI的api也是可以的,我们的方案与平台无关,因为open der可以非常方便的切换模型,所以呢我用open比较多,这里也用它进行演示。 这里面的self点base url对应的就是open Roder的url。 在这个类创建的时候,self点base l就已经设置好了。 而请求体呢也就是这里面的request body一共是包含四个部分,分别是model messages、to和stream,这些字段的含义我们后面会详细阐述,你先不用管。 之后呢我们会把模型api的请求和返回单独打印到一个文件中。 后面呢我们便会查阅这个文件的内容,来了解function calling协议的具体细节。 最后我们返回模型api给出的最终答案,整个方法就结束了。 这是我们漏掉的第一个函数。 第二个漏掉的函数叫做excto,它是用来执行工具的。 为了减少代码的复杂度,我这里直接造了一个假的数据返回。 正常情况下这里面是应该调用对应的搜索引擎api来做查询,比如可以调个http之类的。 第三个漏掉的函数呢是call model after to execu它, 是在第二次请求模型api的时候使用的,跟我们前面所见的call model函数差不多。 它呢也是先请求模型api再记录日志,最后返回。 我们就不细看了。 回想一下在每次调用模型api的时候,我们都会打两行日志。 一个是给模型api的请求,另外一个呢是模型api的返回。 所以呢我们到对应的日志文件里面就应该能够找到4个日志记录,分别对应第一个模型api的请求返回和第二个模型api的请求返回。 我们不妨去文件里面看看,这个就是日志文件的内容了。 你现在所看到的部分就是第一次的模型api请求,它一共有四个字段,分别是model messages tools,还有一个是stream。 我们的model设为了gpd 4O代表,我们用的就是这个模型了。 Messages代表的是目前发送或者接收到的消息列表。 第一次发送请求给模型ap的时候,只有一个用户问题在消息列表里面。 后面的tools呢则是我们讨论的重点,它是一个列表,其中包含了所有的可用工具。 我们只有一个叫做search,用于搜索网络。 后面的parameters呢则是一段json schema,用于描述工具的入参。 J 3Schma这个概念我们在mcp终极指南的进阶篇里面聊过了。 为了方便没有看过的同学,我这里再稍稍聊两句。 首先我相信你一定听说过json,json a呢其实就是对另外一个json结构的描述。 比如我们看看这个例子,它代表的json呢是一个对象里面有一个属性叫做的query,这个属性的值必须是string,代表的含义是需要搜索的内容,而且query这个属性还必须存在,不可缺少。 对应的J项有很多,比如说是这个或者是这个,这些J项都满足我们前面所说的那个J son scheema的要求。 换句话说,如果模型api像这两个例子这样返回工具的参数的话,那都是没有问题的。 最后的这个stream force代表我们不要流失返回内容,流式的返回结果太复杂,会对我们造成干扰。 如果你不知道流式返回是什么意思,那也没有关系,这跟我们学习方式靠令无关。 建议你不用管这个选项,我只是顺带给你提一下模型api的请求到这里就结束了,那它会返回什么呢? 就是这个样子了。 这个消息比较长,不过大部分都没什么用。 我们重点看看其中的to co这一部分。 这里表明模型想要调用一个叫做search的工具,调用的参数是这个样子的。 模型想要表达的信息呢就仅此而已了。 我们前面也说过,模型是不会真的去调用这个工具的,它只是会发出调用工具的请求而已。 调用函数的是我们mark chat服务器,也就是代码里面这一部分的内容。 执行完毕之后,我们把结果放到了self history变量中,并在下一次调用模型api的时候带给了他。 我们再回到日志文件里面,找到第二组模型api请求,看看模型是不是真的拿到了工具的执行结果。 第二次模型api的请求结构与第一次类似,model是模型名称,messages是历史消息列表。 第一次调用模型api的时候呢,它还只有用户问题一个消息。 不过这次呢他就会多出两个消息了,这两个都是我们在代码里面给他塞进去的。 其中第一个多出来的消息呢是之前模型所选择的工具,其中这一部分表示的就是所挑选的工具名称以及对应的参数,跟之前第一次模型api返回结果中的对应部分是一样的。 第二个多出来的消息呢则是工具的执行结果,也就是这一部分的内容。 对于模型来说,这也是一个非常关键的消息,因为只有有了它,模型才能够回答用户的问题。 To就是工具列表了,它跟我们第一次请求模型api的时候是一样的,这里就不再赘述了。 不过要注意一点,to虽然传给了模型,但是呢模型也可以选择不用工具,实际上模型第二次的返回结果中就不会再选择使用工具了。 我们再来看看模型api对第二次请求的响应。 同样大部分的内容都跟我们无关,我们就看这里,这里面的content所代表的就是模型给出的最终答案。 这个答案呢就是根据之前工具的执行结果总结出来的,整个日志到这里面也就结束了。 所以呢总结一下什么是function calling。 Function calling就是模型能够使用工具的一种能力。 想要再具体一点的话,我们可以用这个日志内容来举例。 让我们先把日志搬到第一次模型请求那里。 如果模型能够解析请求参数中的工具列表字段,能够从中挑选出要调用的工具名称和工具参数。 能解析工具的执行结果,那么我们就称这个模型是具有function col的能力。 当然正如我前面所说,你把这个定义中的模型换成模型api也是可以的。 这两个定义的本质是一样的,只不过是站在不同的角度去定义方。 那如果说我们希望让这条链路也用上mp的话,应该修改代码里面的哪个部分呢? 我们直接修改项目里面的excto这个函数就可以了。 之前说过为了简化代码,我们这里是返回了一段假的天气信息。 但是呢在真实的链路里面,这里可能是调用了一个hp接口,可能是调用了一个外部程序,也可能是调用了一个hdk的函数。 但不管怎么样,function calling呢是没有规定这个地方到底是如何来写的那究竟是谁规定了呢? 相信你已经想到答案了。 对,没错,就是mcp。 Mcp规定了一套统一的工具发现与调用协议。 如果你想让这个链路用上mp的话,你只需要按照mp的规范,在这个地方调用mp的工具就可以了。 其实这个调用mp工具的函数呢我也写好了,就叫做x two with M C P。 我们把原来的这个exctwo换成exctwo with mcp就行了。 Exctwo with mcp内部呢会启动一个mcp client,这个mcp client呢会连接一个我们项目目录里面写好的mcp server,对应的就是这个文件。 这个mcp server的返回数据呢也是假的。 但是呢前面有一个标识表明这个结果是从mp server这个地方调用过来的。 注意啊,虽然说这个数据是假的,但是呢这个链路确实是真的,我们改成mp工具调用之后呢,再次运行一下这个程序。 然后再回到页面中再问一下刚才的问题。 可以看到模型正常返回了。 看一下工具的调用信息,可以发现调用的确实是M C P server。 这样呢我们就实现了在一个链路里面同时使用mp和function calling的效果。 你可能会对mcp client和mcp server如何实现比较好奇。 但是呢因为视频长度的限制,我们这里就不细说了。 感兴趣的同学可以自己去看一下,代码并不复杂。 今天的视频呢就到此结束了,别忘了点赞关注我们,下期再见,拜拜。

最新摘要 (详细摘要)

生成于 2025-06-10 19:20

概览/核心摘要 (Executive Summary)

本视频的核心论点是,Function Calling 与 MCP (Model-centric Protocol) 并非相互替代的技术,而是互补关系,它们在大型模型应用链路中扮演着截然不同的角色。讲者(马克)旨在纠正“MCP将取代Function Calling”这一普遍存在的错误观点。

Function Calling 被定义为一种使模型能够根据用户问题,从预定义的工具列表中选择合适的工具并生成调用参数,然后解析工具的执行结果以形成最终答案的能力。讲者强调,这本质上是模型的内在能力,但在实践中(尤其是对于闭源模型),开发者通过模型API来间接使用,因此它通常被理解为模型API的一项核心功能。它构成了模型与应用服务器之间的“决策”和“理解”层。

MCP 则是一套工具的发现与调用协议,它作用于应用服务器与外部工具(函数)之间,旨在标准化工具的调用方式,与模型本身没有直接关系。

结论是,Function Calling 负责“决定调用哪个工具以及如何调用”,而 MCP 负责“如何标准化地执行这个调用”。在一个完整的应用链路中,两者可以无缝结合:模型通过 Function Calling 能力决定调用某个工具,应用服务器随后通过 MCP 协议去执行该工具。视频最后通过一个代码演示,成功地在同一流程中集成了这两种技术,验证了它们的互补性。


核心观点:Function Calling 与 MCP 是互补而非替代关系

讲者开篇即明确指出,将 MCP 视为 Function Calling 的替代品或统一协议是一种广泛流传但错误的看法。

  • 普遍误解:认为 MCP 作为更标准化的协议,会自然取代 Function Calling,使其失去存在价值。
  • 讲者核心论点
    > "function calling和mcp并不是互相替代的关系,而是互补的关系,他们在大模型领域所处的地位完全不同,在未来很长的一段时间里,function calling和mcp都将同时存在,各自发挥自己的价值。"
  • 根本区别:两者在AI应用链路中所处的位置和发挥的作用完全不同。
    • Function Calling:与模型直接相关。讲者强调,其本质是模型的一种内在能力,但在实际应用中,开发者通过模型API来间接使用,因此也常被视为模型API的一项功能。
    • MCP:与工具调用相关,是应用服务器与外部工具之间的通信协议,与模型无直接关联。

Function Calling 的概念与工作链路解析

为了厘清概念,讲者详细解释了 Function Calling 的定义及其在实际应用中的工作流程。

  • 基本概念

    • Function Calling 指的是模型与外部工具(本质上是编程语言中的函数)交互的一种能力,旨在解决模型知识库固化、无法回答范围外问题的局限。
    • 重要澄清:模型本身不直接执行函数调用,而是依赖一个“中间人”(通常是应用服务器)来完成。因此,Function Calling 的名字具有一定的误导性。
  • 工作链路拆解 (以查询天气的场景为例):

    1. 用户提问:用户向应用(如ChatGPT)提问:“纽约明天的天气怎么样?”
    2. 第一次模型交互(决策阶段)
      • 应用服务器将用户问题和一份可用工具列表(如网络搜索工具)发送给模型API。
      • 模型评估后,判断自身知识无法回答,决定使用“搜索网络”工具。
      • 模型API返回一个工具使用请求,包含要调用的工具名称和具体参数(如 {"query": "纽约明天的天气"})。
    3. 工具执行
      • 应用服务器接收到模型的工具使用请求后,实际调用对应的网络搜索函数,并获得返回结果(如天气数据)。
    4. 第二次模型交互(总结阶段)
      • 应用服务器将上一步获得的工具执行结果再次发送给模型API。
      • 模型接收并理解该结果,结合原始问题,总结出最终的自然语言答案。
    5. 返回答案:应用服务器将模型生成的最终答案呈现给用户。
  • Function Calling 的作用域

    • 讲者强调,Function Calling 并非指应用服务器实际执行函数(上文第3步)的过程。
    • 其真正作用域是模型API与应用服务器之间的交互部分,即模型如何选择工具、生成参数,以及如何解析工具返回结果
    • 相比之下,MCP 的作用域正是应用服务器与工具之间的调用过程。

    "从这里就可以看出,mp与function col[ling]分别作用在链路的两个环节发挥的作用各不相同,根本就没有互相替代这一说。"

Function Calling 协议深度分析

讲者通过自建的“Mark Chat”应用截获并分析了与模型API交互的完整日志,揭示了 Function Calling 的协议细节。

  • 第一次API调用(请求模型决策)

    • 请求体 (Request Body):
      • model: 指定使用的模型,如 "gpt-4o"。
      • messages: 消息列表,此时仅包含用户的原始问题 (role: "user")。
      • tools: 核心字段,一个包含所有可用工具定义的列表。每个工具包含:
        • name: 工具名称,如 "search"。
        • parameters: 一个 JSON Schema 对象,用于精确描述该工具所需的输入参数、类型和是否必需。
      • stream: false,表示非流式返回。
    • 响应体 (Response Body):
      • 响应的核心是 tool_calls 字段,表明模型决定调用工具。
      • tool_calls 是一个列表,包含要调用的工具ID、名称(如 "search")和具体的参数(如 {"query": "纽约明天的天气"})。
  • 第二次API调用(请求模型总结)

    • 请求体 (Request Body):
      • messages 列表被扩展,现在包含三个部分:
        1. 用户的原始问题 (role: "user")。
        2. 第一次API调用的返回结果,即模型的工具调用决策 (role: "assistant", 包含 tool_calls)。
        3. 工具的实际执行结果,以一个新消息的形式加入 (role: "tool")。
      • tools 列表通常会再次提供,尽管模型此次可能不会再选择调用工具。
    • 响应体 (Response Body):
      • 响应中不再包含 tool_calls
      • 核心是 content 字段,包含了模型根据工具结果总结出的最终文本答案。

实践演示:在同一链路中结合使用 Function Calling 与 MCP

为了证明两者的互补性,讲者在代码层面演示了如何将它们集成。

  • 集成点:修改应用服务器中负责执行工具的函数(在示例代码中为 execute_tool)。
  • 修改逻辑
    • 原逻辑可能是直接调用一个本地函数或HTTP API。
    • 修改后的逻辑 (execute_tool_with_mcp) 则是启动一个 MCP Client
    • 这个 MCP Client 按照 MCP 协议,去发现并调用一个作为 MCP Server 运行的外部工具。
  • 演示结果
    • 应用成功运行,并返回了由 MCP Server 提供的数据。
    • 返回信息中明确标识了结果来源于 MCP Server,验证了链路的成功。

      "这样呢我们就实现了在一个链路里面同时使用mp和function calling的效果。"

  • 开源代码:为方便观众理解和实践,讲者已将本次演示所用的全部代码开源至其 GitHub 仓库。

核心结论总结

  1. 角色分工明确:Function Calling 是模型的一种决策与理解能力,作用于模型与应用服务器之间;MCP 是一套工具调用与发现的标准化协议,作用于应用服务器与工具之间。
  2. 关系是互补:两者在AI应用的不同环节各司其职,共同构成一个完整的、功能强大的系统,不存在谁取代谁的问题。
  3. 实践可行性:通过修改工具执行层,可以非常自然地将 MCP 集成到使用 Function Calling 的工作流中,实现两者的协同工作。