



在正式讲解MCP的技术原理之前,有必要梳理清楚与MCP密切相关的几个概念(Function Call、RAG),以及它们之间的关系和异同。
2023年6月13日,OpenAI对外正式发布了Function Call API,这一功能被集成到Chat Completions API中,允许开发者将大语言模型(如GPT-4)与外部函数或工具相连接,从而扩展模型的能力边界,实现动态任务处理(查询数据库、调用API等)。需要注意的是,这个能力只集成在Open AI的API产品中,ChatGPT的用户是无法直接使用和感知到的,因为这个功能主要面向开发者,而且需要开发者通过编码来实现工具的对接和调用。参考下面这个代码示例。
注: 下述代码使用了OpenAI早期的Function Call API规范。随着2024年5月13日GPT-4o模型的发布,Function Call API统一升级为Tool Use API。由于OpenAI的影响力,这也成为事实上的行业标准。此处仅用于阐述背后原理,如需进行开发,请参考各家模型最新的API文档。
1 // 定义天气查询函数
2 const functions =[
3 {
4 name:"get_weather",
5 description:"获取指定城市的天气信息",
6 parameters:{
7 type:"object",
8 properties:{
9 city:{ type:"string",description:"城市名称" },
10 date:{ type:"string",format:"date",description:"查询日期(格式:YYYY-MM-DD)" }
11 },
12 required:["city"]
13 }
14 }
15];
16
17 // 实际函数实现(可替换为API调用)
18 function getWeather(city,date){
19 return "晴,气温25°C";
20}
21
22 async function main(){
23 const response = await openai.chat.completions.create({
24 model:"gpt-4o",
25 messages:[{ role:"user",content:"今天北京的天气怎么样?" }],
26 functions:functions,
27 function_call:"auto" // 允许模型选择是否调用函数
28 });
29
30 const functionCall = response.choices[0].message.function_call;
31 // {"name":"get_weather",arguments:"{\"city\":\"北京\",\"date\":\"xxxx-xx-xx\"}"}
32 if(functionCall?.name === "get_weather"){
33 const args = JSON.parse(functionCall.arguments);
34 const weather = await getWeather(args.city,args.date);// 调用真实函数
35 console.log(`天气信息:${weather}`);
36 }
37}
38
39 main();
可以看到,这里有两个关键的实现。
该定义指的是对模型提供的工具清单进行定义,通过JSON Schema语言规范描述这个工具的基本信息,包括名称、描述以及调用参数的规格等。比如,这里定义了两个参数:城市名称和查询日期,其中城市名称是必选项。
这个函数的逻辑需要开发者自行实现,例如调用第三方天气网站的在线API来完成天气查询,此处仅作为示范,所以直接提供了结果示例。
基于这两个实现,当OpenAI的Chat Completions API被调用时,会把functions定义传给模型,模型的输出中会包含一个名为function_call的JSON对象,该对象描述了模型推理后决定需要调用的工具信息(包括name和arguments)。至此,Function Call API的工作就结束了,至于getWeather函数要怎么调用,完全交由开发者自行处理。不同的开发者针对同一个getWeather函数的实现方式,可能截然不同,如下代码所示:
1 // 实现A:根据城市和日期查询
2 function getWeather(city,date){
3 return thirdPartWeatherAPIA(city,date);
4 }
5
6 // 实现B:根据经纬度查询
7 function getWeather(latitude,longitude){
8 return thirdPartWeatherAPIB(latitude,longitude);
9 }
从上述代码中可以得出两个关键的洞察:
□ Function Call只解决了模型要选择哪个工具来调用的问题,并没有真正地完成对这个工具的调用。
□ 对于同样的功能,如果没有标准,其实现方式可以非常多样,不同开发者可以有截然不同的实现方式,而且这些实现方式均深藏在各自的代码仓库中,无法被他人拿来即用。
OpenAI在2023年11月6日的DevDay上首次对外发布了名为GPTs的产品,这是最早的AI Agent产品形态。该产品主要依托Function Call API的能力,允许GPTs的开发者通过其产品界面开发自定义工具,以实现远程的工具调用。例如,一个旅游网站的开发者开发了一个查询低价机票的远程API,并将该API的调用封装到一个名为“低价机票助手”的GPTs中,如图2-1所示。
图2-1展示了如何通过UI和JSON Schema的方式来定义远程API,以便模型输出一个完整的工具调用。
图2-1 “低价机票助手”GPTs的“添加操作”界面
OpenAI的Agent构建思路是中心化的。所有GPTs对工具的选择、调用与执行都托管在OpenAI的服务器上。这种模式带来了很多问题:
□ 开发者需要将自己的API调用的Token密钥配置在OpenAI的服务器上,存在将隐私信息泄露给平台的风险。
□ 开发者无法人为干预工具调用的人机协同机制,譬如调用工具之前寻求用户的授权。这些逻辑都只能由OpenAI来决定。
□ GPTs的生态只能和OpenAI绑定,普通用户需要购买Pro会员才可以使用GPTs。如果需要更换其他模型厂商的产品,由于GPTs无法完成迁移,因此用户会被死死地绑定在OpenAI的生态里。
Anthropic的工程师们敏锐地察觉到上述这些问题,他们试图定义一种开源的、去中心化的标准化AI Agent通信协议来解决这些问题,这就是于2024年11月发布的MCP。需要注意的是,MCP和Function Call这两个技术并不是取代的关系,而是协作的关系。下面的例子生动形象地展示了MCP和Function Call要解决的问题域的差异。
1 // assistant代表模型的回复
2 1.你(user):我饿了,想吃比萨,美团饿了么都可以点
3 2.你妈(assistant):你上美团点个外卖吧
4 3.你(toolcall):好,我用美团点一个[一顿操作]
5 4.你(toolResult):点完了
Function Call指的是第二步,由大模型决定选择用哪种工具来完成,它主要规范化了工具选择的输入/输出格式,但并不具体调用这个工具。第三步才是真正调用这个工具的过程,MCP主要用于解决这一步的标准化协议。它们是上下游协作的关系,一个负责通过LLM决策使用哪个工具,一个负责调用这个工具并返回工具执行的结果。
上面提到Function Call并没有解决工具的调用问题,那么有哪些方法可以调用工具呢?很显然,MCP的初衷就是提供一种标准化的方式来解决这个问题。而在MCP之前,行业里最早的工具调用实践是通过编写代码直接调用某个服务提供商提供的API。LangChain、GPTs等多种支持工具调用的AI产品,都遵循了API对接的方案。单从解决工具调用问题的角度讲,API和MCP产生的作用确实可以理解为是对等的,这也是很多人经常讨论API和MCP差异的一个主要原因。
实际上,MCP服务器也需要通过API来完成服务的对接,只是MCP是一个更大的概念,远非调用一个工具这么简单。因为MCP是一个标准,所以工具开发者们可以遵循这个标准开发各种工具,然后以软件包的方式将工具发布到NPM、PIP、Docker Hub等开源软件仓库中,这样其他开发者或者用户就可以直接复用这个工具,做到真正的拿来即用。而API服务一般都部署在由某个企业掌控的云主机上,并且通常都是需要登录鉴权的有偿服务。MCP则提供了更为灵活的部署方式,既可以在个人计算机上部署个人专属的MCP服务器,也可以部署在远程云主机上。除此之外,MCP还提供了Prompt模板、Resourc等功能。我们可以简单形象地理解它们的关系:MCP是一个多功能读卡器,为不同接口的存储卡(类比API)提供了标准化的套壳适配,让所有计算机都可以自由读取各种类型的存储卡。
RAG(Retrieval Augmented Generation,检索增强生成)是一种结合信息检索与文本生成的LLM增强技术。其核心思想是在模型生成回答之前,先从外部知识库中检索与用户查询相关的信息,然后将这些信息作为Prompt的上下文提供给模型,以生成更准确的回答。RAG的工作原理如图2-2所示。
图2-2 RAG的工作原理
RAG主要用于解决LLM在生成回答时存在的几个问题:
□ 知识局限性:LLM的知识来源于训练数据,它可能无法回答超出训练数据范围的问题。
□ 信息时效性:LLM可能无法获取最新的信息,导致回答过时。
□ 幻觉:LLM可能生成不准确或无关的回答,导致幻觉问题。
RAG技术专注于通过检索外部信息来提供更准确、高质量的上下文信息,以增强最终的文本生成质量。与LLM的协作和集成既可以通过自由编码(按个人喜好自研、使用类似LangChain这样的开发框架等)的方式进行,也可以与MCP协作,通过开发一个专门的MCP服务器,使基于某个专有知识库的检索能力变成一个标准件。RAG既可以被封装成一个MCP服务器供所有人使用,也可以被开发者灵活地集成在自己的AI应用流程中,它和MCP是一种协作关系。