模型上下文协议(MCP)
为什么 MCP 是一个突破
我先来画一个饼,我认为未来的 AI 是这个样子的,以我熟悉的软件工程领域举例:
未来,AI 可以完全自动化应用开发流程,例如:
- 设计阶段:可以连接设计工具,基于用户需求生成 UI 和功能设计。
- 编码和测试:AI 编写代码,期间可以随时在浏览器或者各类模拟器中运行应用并获取运行日志来帮助自己 debug 开发过程中的各种错误。以及检查编写的 UI 是否和设计稿一致。并根据业务需求生成各类自动化测试。
- 部署: 自动 push 代码,持续集成部署,并根据 CI 平台的测试反馈自动触发 bug fix,再次提交部署。
- 维护和更新:自动监控应用,自动修复错误,并根据需求更新功能。
- ……
这个饼现在看来可能画的有点大,可能其中的部分功能单独拉出来很好实现,但是当他们组成一个系统提供能力时,你能想象用起来多爽吗?
当然,上面谈到的这些功能,通过 MCP 目前正在逐步变成现实,就比如第二步中的从浏览器获取日志来 debug 应用的例子,你可以试试用 Cursor MCP + browsertools 插件来体验一下在 Cursor 中自动获取 Chrome dev tools console log 的能力。
为什么 AI 集成已有服务的进展这么缓慢?这里面有很多的原因,一方面是企业级的数据很敏感,大多数企业都要很长的时间和流程来动。另一个方面是技术方面,我们缺少一个开放的、通用的、有共识的协议标准。
什么是 MCP(Model Context Protocol)
MCP 起源于 2024 年 11 月 25 日 Anthropic 发布的文章:Introducing the Model Context Protocol。
MCP (Model Context Protocol,模型上下文协议)定义了应用程序和 AI 模型之间交换上下文信息的方式。这使得开发者能够以一致的方式将各种数据源、工具和功能连接到 AI 模型(一个中间协议层),就像 USB-C 让不同设备能够通过相同的接口连接一样。MCP 的目标是创建一个通用标准,使 AI 应用程序的开发和集成变得更加简单和统一。
这里还是要多提一句,这个协议的发布最好机会应该是属于 OpenAI 的,如果 OpenAI 刚发布 GPT 时就推动协议,相信大家都不会拒绝,但是 OpenAI 变成了 CloseAI,只发布了一个封闭的 GPTs,这种需要主导和共识的标准协议一般很难社区自发形成,一般由行业巨头来主导。
可以看出,MCP 就是以更标准的方式让 LLM Chat 使用不同工具,更简单的可视化如下图所示,这样你应该更容易理解“中间协议层”的概念了。Anthropic 旨在实现 LLM Tool Call 的标准。
为什么是 MCP?
看到这里你可能有一个问题,在 23 年 OpenAI 发布 GPT function calling 的时候,不是也是可以实现类似的功能吗?AI Agent 不就是用来集成不同的服务吗?为什么又出现了 MCP。
function calling、AI Agent、MCP 这三者之间有什么区别?
Function Calling
- Function Calling 指的是 AI 模型根据上下文自动执行函数的机制。
- Function Calling 充当了 AI 模型与外部系统之间的桥梁,不同的模型有不同的 Function Calling 实现,代码集成的方式也不一样。由不同的 AI 模型平台来定义和实现。
如果我们使用 Function Calling,那么需要在 AI 应用中通过代码实现一组 function(目前主流的是通过插件方式提供以支持灵活扩展),并且提供清晰的函数描述、函数输入和输出(通过系统提示词)结合用户输入给到 LLM,那么 LLM 就可以根据输入输出清晰的结构化数据以供主机应用执行函数,最终将执行结果转换为自然语言输出。
整个问答的调用如下:
{ |
Function Calling 的缺点在于处理不好多轮对话和复杂需求,适合边界清晰、描述明确的任务。如果需要处理很多的任务,那么 Function Calling 的代码比较难维护。以及没有一个统一的标准,应用各自有各自的实现方式,最明显的就是其中调用 function 的结构化输出,以及系统 prompt 都很难统一。
AI Agent
- AI Agent(AI 代理)是一种能够自主执行任务、与外部系统交互并根据目标做出决策的智能软件。它不仅能理解用户输入,还能调用工具、访问数据源(如数据库、API)并完成复杂工作流。例如,一个 AI Agent 可以帮你预订机票、管理日程或自动化代码调试。这里的调用外部服务的方式主要依赖于定制化的 API 调用或硬编码的工具集成,而不是像 MCP 这样标准化的协议,是深度集成到应用的,各自 agent 有各自的实现,
- AI Agent 可以利用 MCP 提供的功能描述来理解更多的上下文,并在各种平台/服务自动执行任务。
Model Context Protocol (MCP)
- MCP 是一个标准协议,如同电子设备的 Type C 协议(可以充电也可以传输数据),使 AI 模型能够与不同的 API 和数据源无缝交互。
- MCP 旨在替换碎片化的 Agent 代码集成,从而使 AI 系统更可靠,更有效。通过建立通用标准,服务商可以基于协议来推出它们自己服务的 AI 能力,从而支持开发者更快的构建更强大的 AI 应用。开发者也不需要重复造轮子,通过开源项目可以建立强大的 AI Agent 生态。
- MCP 可以在不同的应用/服务之间保持上下文,从而增强整体自主执行任务的能力。
可以理解为 MCP 是将不同任务进行分层处理,每一层都提供一个或多个特定的能力、描述和限制。而 MCP Client 端根据不同的任务判断,选择是否需要调用某个能力,然后通过每层的输入和输出,构建一个可以处理复杂、多步对话和统一上下文的 Agent。
同时,我认为 MCP 的出现是 prompt engineering 发展的产物。更结构化的上下文信息对模型的 performance 提升是显著的。我们在构造 prompt 时,希望能提供一些更 specific 的信息(比如本地文件,数据库,一些网络实时信息等)给模型,这样模型更容易理解真实场景中的问题。
想象一下没有 MCP 之前我们会怎么做?我们可能会人工从数据库中筛选或者使用工具检索可能需要的信息,手动的粘贴到 prompt 中。随着我们要解决的问题越来越复杂,手工把信息引入到 prompt 中会变得越来越困难。
为了克服手工 prompt 的局限性,许多 LLM 平台(如 OpenAI、Google)引入了 function call
功能。这一机制允许模型在需要时调用预定义的函数来获取数据或执行操作,显著提升了自动化水平。
但是 function call 也有其局限性(我对于 function call vs MCP 的理解不一定成熟,欢迎大家补充),我认为重点在于 function call 平台依赖性强,不同 LLM 平台的 function call API 实现差异较大。例如,OpenAI 的函数调用方式与 Google 的不兼容,开发者在切换模型时需要重写代码,增加了适配成本。除此之外,还有安全性,交互性等问题。
数据与工具本身是客观存在的,只不过我们希望将数据连接到模型的这个环节可以更智能更统一。Anthropic 基于这样的痛点设计了 MCP,充当 AI 模型的”万能转接头”,让 LLM 能轻松的获取数据或者调用工具。更具体的说 MCP 的优势在于:
- 生态 - MCP 提供很多现成的插件,你的 AI 可以直接使用。
- 统一性 - 不限制于特定的 AI 模型,任何支持 MCP 的模型都可以灵活切换。
- 数据安全 - 你的敏感数据留在自己的电脑上,不必全部上传。(因为我们可以自行设计接口确定传输哪些数据)
用户如何使用 MCP?
对于用户来说,我们并不关心 MCP 是如何实现的,通常我们只考虑如何更简单的用上这一特性。
具体的使用方式参考官方文档:For Claude Desktop Users。这里不再赘述,配置成功后可以在 Claude 中测试:Can you write a poem and save it to my desktop?
Claude 会请求你的权限后在本地新建一个文件。
并且官方和社区也提供了非常多现成的 MCP Servers,你只需要选择你希望接入的工具,然后接入即可,我在文章后面列出了相关的资源。
比如官方介绍的 filesystem
工具,它允许 Claude 读取和写入文件,就像在本地文件系统中一样。
MCP Architecture
MCP 由三个核心组件构成:Host、Client 和 Server。让我们通过一个实际场景来理解这些组件如何协同工作:
假设你正在使用 Claude Desktop (Host) 询问:”我桌面上有哪些文档?”
- Host:Claude Desktop 作为 Host,负责接收你的提问并与 Claude 模型交互。
- Client:当 Claude 模型决定需要访问你的文件系统时,Host 中内置的 MCP Client 会被激活。这个 Client 负责与适当的 MCP Server 建立连接。
- Server:在这个例子中,文件系统 MCP Server 会被调用。它负责执行实际的文件扫描操作,访问你的桌面目录,并返回找到的文档列表。
整个流程是这样的:你的问题 → Claude Desktop(Host) → Claude 模型 → 需要文件信息 → MCP Client 连接 → 文件系统 MCP Server → 执行操作 → 返回结果 → Claude 生成回答 → 显示在 Claude Desktop 上。
这种架构设计使得 Claude 可以在不同场景下灵活调用各种工具和数据源,而开发者只需专注于开发对应的 MCP Server,无需关心 Host 和 Client 的实现细节。
原理:模型是如何确定工具的选用的?
在学习的过程中,我一直好奇一个问题:Claude(模型)是在什么时候确定使用哪些工具的呢?好在 Anthropic 为我们提供了详细的解释:
当用户提出一个问题时:
- 客户端(Claude Desktop / Cursor)将你的问题发送给 Claude。
- Claude 分析可用的工具,并决定使用哪一个(或多个)。
- 客户端通过 MCP Server 执行所选的工具。
- 工具的执行结果被送回给 Claude。
- Claude 结合执行结果构造最终的 prompt 并生成自然语言的回应。
- 回应最终展示给用户!
MCP Server 是由 Claude 主动选择并调用的。有意思的是 Claude 具体是如何确定该使用哪些工具呢?以及是否会使用一些不存在的工具呢(幻觉)?
(原谅我之前解释的过于简单)为了探索这个问题让我们深入源码。显然这个调用过程可以分为两个步骤:
- 由 LLM(Claude)确定使用哪些 MCP Server。
- 执行对应的 MCP Server 并对执行结果进行重新处理。
先给出一个简单可视化帮助理解:
模型如何智能选择工具?
先理解第一步模型如何确定该使用哪些工具?这里以 MCP 官方提供的 client example 为讲解示例,并简化了对应的代码(删除了一些不影响阅读逻辑的异常控制代码)。通过阅读代码,可以发现模型是通过 prompt 来确定当前有哪些工具。我们通过将工具的具体使用描述以文本的形式传递给模型,供模型了解有哪些工具以及结合实时情况进行选择。参考代码中的注释:
# 省略了无关的代码 |
那 tool 的描述和代码中的 input_schema
是从哪里来的呢?通过进一步分析 MCP 的 Python SDK 源代码可以发现:大部分情况下,当使用装饰器 @mcp.tool()
来装饰函数时,对应的 name
和 description
等其实直接源自用户定义函数的函数名以及函数的 docstring
等。这里仅截取一小部分片段,想了解更多请参考原始代码。
|
总结:模型是通过 prompt engineering,即提供所有工具的结构化描述和 few-shot 的 example 来确定该使用哪些工具。另一方面,Anthropic 肯定对 Claude 做了专门的训练(毕竟是自家协议,Claude 更能理解工具的 prompt 以及输出结构化的 tool call json 代码)
工具执行与结果反馈机制
其实工具的执行就比较简单和直接了。承接上一步,我们把 system prompt(指令与工具调用描述)和用户消息一起发送给模型,然后接收模型的回复。当模型分析用户请求后,它会决定是否需要调用工具:
- 无需工具时:模型直接生成自然语言回复。
- 需要工具时:模型输出结构化 JSON 格式的工具调用请求。
如果回复中包含结构化 JSON 格式的工具调用请求,则客户端会根据这个 json 代码执行对应的工具。具体的实现逻辑都在 process_llm_response
中,代码,逻辑非常简单。
如果模型执行了 tool call,则工具执行的结果 result
会和 system prompt 和用户消息一起重新发送给模型,请求模型生成最终回复。
如果 tool call 的 json 代码存在问题或者模型产生了幻觉怎么办呢?通过阅读代码 发现,我们会 skip 掉无效的调用请求。
执行相关的代码与注释如下:
# 省略无关的代码 |
结合这部分原理分析:
- 工具文档至关重要 - 模型通过工具描述文本来理解和选择工具,因此精心编写工具的名称、docstring 和参数说明至关重要。
- 由于 MCP 的选择是基于 prompt 的,所以任何模型其实都适配 MCP,只要你能提供对应的工具描述。但是当你使用非 Claude 模型时,MCP 使用的效果和体验难以保证(没有做专门的训练)。
总结
MCP (Model Context Protocol) 代表了 AI 与外部工具和数据交互的标准建立。通过本文,我们可以了解到:
- MCP 的本质:它是一个统一的协议标准,使 AI 模型能够以一致的方式连接各种数据源和工具,类似于 AI 世界的”USB-C”接口。
- MCP 的价值:它解决了传统 function call 的平台依赖问题,提供了更统一、开放、安全、灵活的工具调用机制,让用户和开发者都能从中受益。
- 使用与开发:对于普通用户,MCP 提供了丰富的现成工具,用户可以在不了解任何技术细节的情况下使用;对于开发者,MCP 提供了清晰的架构和 SDK,使工具开发变得相对简单。
MCP 还处于发展初期,但其潜力巨大。更重要的是生态吧,基于统一标准下构筑的生态也会正向的促进整个领域的发展。
MCP 的一些资源
MCP 官方资源
社区的 MCP Server 的列表
MCP 官方集成教学:
- Git - Git 读取、操作、搜索。
- GitHub - Repo 管理、文件操作和 GitHub API 集成。
- Google Maps - 集成 Google Map 获取位置信息。
- PostgreSQL - 只读数据库查询。
- Slack - Slack 消息发送和查询。
🎖️ 第三方平台官方支持 MCP 的例子
由第三方平台构建的 MCP 服务器。
🌎 社区 MCP 服务器
下面是一些由开源社区开发和维护的 MCP 服务器。
- AWS - 用 LLM 操作 AWS 资源。
- Atlassian - 与 Confluence 和 Jira 进行交互,包括搜索/查询 Confluence 空间/页面,访问 Jira Issue 和项目。
- Google Calendar - 与 Google 日历集成,日程安排,查找时间,并添加/删除事件。
- Kubernetes - 连接到 Kubernetes 集群并管理 pods、deployments 和 services。
- X (Twitter) - 与 Twitter API 交互。发布推文并通过查询搜索推文。
- YouTube - 与 YouTube API 集成,视频管理、短视频创作等。