引言
应用越智能,背后的设计会越复杂。软件的本质是解决复杂性问题,MCP 虽打开了智能的创意上限,但也给后端的设计带来了无限的复杂度。本文旨在从 MCP 的技术原理、降低 MCP Server 构建复杂度、提升 Server 运行稳定性等方面出发,分享我们的一些实践心得。文章内容较长,以下是导读大纲。(公众号:硬核隔壁老王,获取 78 页完整版 PPT)
1、介绍 MCP 的概念及其运作机制。
2、解释 MCP 和 Function Calling 之间的区别。
3、讲述 MCP 的本质和挑战,包括描述 MCP 信息的系统提示词的挑战,MCP Client 与 MCP Server 之间协同关系的挑战,快速构建 MCP Server,自建 Dify 的痛点等。
4、分析如何解决 MCP 的各个挑战,包括 MCP Register、MCP Server 和 Promt 的统一管理、MCP 效果验证体系和安全性保障、MCP 网关、MCP Server 的动态服务发现、Streamable HTTP、弹性效率、可观测等。
5、最后探讨 MCP 对 AI 应用架构新范式的影响,并介绍 MCP Server First 的理念。
AI Agent 现状及架构
人工智能(AI)在商业领域的应用正日益成为推动创新和效率提升的核心力量。其核心在于多个 AI Agent 的协作,这些 AI Agent 通过分工与合作,共同承载 AI 应用所支持的业务需求。这种协作模式不仅优化了企业运营,还展现了 AI 在解决高影响力挑战中的潜力。
当前的 AI Agent,无论是和各种 Tools(各类业务服务接口)交互,还是和各类 Memory(各类存储服务接口)交互,亦或是和各类 LLMs(各类大语言模型)交互,都是通过 HTTP 协议的,除了 LLM 因为基本都遵循 OpenAI 范式以外,和其他的 Tools 和 Memory 交互都需要逐一了解它们的返回格式进行解析和适配。当一个 AI 应用包含多个 AI Agent 时,或者一个 AI 应用需要和多个业务服务接口和存储服务接口交互时,整体的开发工作量是很大的,主要体现在 3 个方面:
找适合该 AI 应用的业务接口和存储服务接口:
- 找三方服务接口。在公司内部找合适的服务的接口。找不到就自己先开发接口。
解析接口的返回格式:无论是三方服务接口还是公司内部的服务接口,返回格式可能都千奇百怪,需要逐一进行了解和解析。
编排多个 AI Agent:
- 有 Dify 这类流程可视化的工具辅助编排,减轻了很多编排工作,但复杂度依然不低,且运行效率和性能方面还是有瓶颈的。通过编码方式做编排(比如使用 Spring AI Alibaba 或 LangChain 等),虽然性能上更优,但是复杂度更高,编排效率和灵活性都有不足。
所以目前很多 AI 应用就只有少数几个 AI Agent,甚至很多 AI 应用背后就只有一个 AI Agent。这也是目前 AI 应用背后的 AI Agent 依然还处在第一个阶段(Siloed, Single-Purpose Agents)的原因。
为了能使 AI Agent 进入到第二阶段(Platform-Level Agents),我们使用云原生 API 网关做了统一的接入层,通过一个网关三种不同角色的方式,解决了一部分复杂度:
作为南北向流量网关,统一管理 AI Agent 的入口流量,核心做转发、负载、鉴权认证、安全、流控等。
作为 AI 网关,代理各类 LLMs,向 AI Agent 屏蔽了繁杂的接入,并且解决了很多生产级的问题,比如多模型切换、模型 Fallback、多 API Key 管理、安全、联网搜索等。
- AI 网关代理 LLMs 的详细文章参见:mp.weixin.qq.com/s/tZ0wsTlZK…
作为东西向网关,统一管理来自不同源(ACK、ECS、函数计算 FC、SAE、三方服务)的各类服务,供 AI Agent 使用。
但如我所说,这只解决了一部分复杂度问题,更核心的找接口 和解析接口这两个问题依然没有解决。直到 MCP(Model Context Protocol)的出现,让我们看到了真正通往第二阶段(Platform-Level Agents)的路,甚至可以尝试触摸第三阶段(Universal Agents, Multi-Agents)。
MCP 是什么
MCP 是模型上下文协议(Model Context Protocol)的简称,是一个开源协议,由 Anthropic(Claude 开发公司)开发,旨在让大型语言模型(LLM)能够以标准化的方式连接到外部数据源和工具。它就像 AI 应用的通用接口,帮助开发者构建更灵活、更具上下文感知能力的 AI 应用,而无需为每个 AI 模型和外部系统组合进行定制集成。MCP 被设计为一个通用接口,类似于 USB-C 端口,允许 LLM 应用以一致的方式连接到各种数据源和工具,如文件、数据库、API 等。
MCP 目前一共有 3 个核心概念:
MCP Server:
- 基于各语言的 MCP SDK 开发的程序或服务。基于某种神秘的机制将现存的程序或服务进行了转换,使其成为了 MCP Server。
MCP Tool:
- MCP Tool 所属于 MCP Server,一个 MCP Server 可以有多个 MCP Tool。可以理解为一个类里有多个方法,或者类似一个服务里有多个接口。
MCP Client:当一段代码,一个 Agent,一个客户端,基于 MCP 的规范去使用、去调用 MCP Server 里的 MCP Tool 时,它就是 MCP Client。
MCP 的运作机制
要真正理解 MCP 是什么,我们需要了解它的运作机制,然后你就能知道 MCP 的调用方式和传统的 HTTP 调用方式有什么不同,可能也能隐约体会到为什么我说 MCP 可以让 AI Agent 进入第二阶段。
如上图所示,一次基于 MCP 的调用,一共有 6 个核心的步骤。我们先拟定一个前提:
- 我要开发一个获取时间的 AI Agent,用户在使用这个 AI Agent 时,只需要问类似 "现在几点了?" 这种问题即可。我已经有了一个关于处理时间的 MCP Server,这个 MCP Server 里有 2 个 MCP Tool,一个负责获取当前时区,一个负责获取当前时间。
调用步骤解析:
第一步:用户向 AI Agent 问 "现在几点了?",此时 AI Agent 就是 MCP Client,它会把用户的问题和处理时间的 MCP Server 以及 MCP Tool 的信息一起发送给 LLM。
第二步:LLM 拿到信息后开始推理,基于用户的问题和 MCP Server 的信息,选出解决用户问题最合适的那个 MCP Server 和 MCP Tool,然后返回给 AI Agent(MCP Client)。
- 这里 LLM 返回给 AI Agent 的信息是:"你用 time 这个 MCP Server 里的 get_current_time 这个 MCP Tool 吧,它可以解决用户的问题"
第三步:AI Agent(MCP Client)现在知道该使用哪个 MCP Server 里的哪个 MCP Tool 了,直接调用那个 MCP Tool,获取结果。
- 调用 time 这个 MCP Server 里的 get_current_time 这个 MCP Tool。
第四步:Time MCP Server 返回结果(当前的时间)给 AI Agent(MCP Client)。
第五步:AI Agent(MCP Client)也很懒啊,把用户的问题和从 Time MCP Server 处拿到的结果再一次给了 LLM,目的是让 LLM 结合问题和答案再规整一下内容。
第六步:LLM 把规规整整的内容返回给 AI Agent(MCP Client),最后 AI Agent(MCP Client)再原封不动的返回给了用户。
在 MCP 的整个调用过程中有一个非常核心的点就是 MCP Server 以及 MCP Tool 的信息。从第一步,第二步可以看出,这个信息非常关键,是它让 LLM 知道了该如何解决用户的问题,这个信息就是 MCP 中最重要的 System Prompt,本质上就是 PE 工程。
MCP System Prompt
MCP 不像传统的协议定义,它没有一个确定的数据结构。它的核心是通过自然语言描述清楚有哪些 MCP Server,承担什么作用,有哪些 MCP Tool,承担什么作用,然后让大语言模型通过推理去选择最合适的 MCP Server 以及 MCP Tool。所以它的核心本质上还是提示词工程。
上面两张图是 Cline(一个 MCP Client)中的 System Prompt,可以清晰的看到它对 MCP Server 和 MCP Tool 都有明确的描述。
上图是流程中的第一步,将用户的问题和 System Prompt 一起发送给 LLM 的内容。
上图是流程中的第二步,LLM 返回了解决用户问题明确的 MCP Server 和 MCP Tool 信息。
MCP 和 Function Calling 之间的区别
看到这,我想大家应该对 MCP 是什么有一定感觉了。MCP 是不是解决了找接口 和解析接口的问题?因为这两个工作都交给了 LLM。
- LLM 负责帮 AI Agent 找到最合适的接口。AI Agent 调用接口,压根不用做返回结果的解析,原封不动再交给 LLM。LLM 结合用户问题和接口返回的结果,做内容规整处理。
那么可能有小伙伴会问,MCP 和 LLM 的 Function Calling 又有什么区别呢?核心区别是是否绑定模型或模型厂商:
- MCP 是通用协议层的标准,类似于 "AI 领域的 USB-C 接口",定义了 LLM 与外部工具 / 数据源的通信格式,但不绑定任何特定模型或厂商,将复杂的函数调用抽象为客户端 - 服务器架构。Function Calling 是大模型厂商提供的专有能力,由大模型厂商定义,不同大模型厂商之间在接口定义和开发文档上存在差异;允许模型直接生成调用函数,触发外部 API,依赖模型自身的上下文理解和结构化输出能力。
如上图所示,LLM Function Calling 需要 LLM 为每个外部函数编写一个 JSON Schema 格式的功能说明,精心设计一个提示词模版,才能提高 Function Calling 响应的准确率,如果一个需求涉及到几十个外部系统,那设计成本是巨大,产品化成本极高。而 MCP 统一了客户端和服务器的运行规范,并且要求 MCP 客户端和服务器之间,也统一按照某个既定的提示词模板进行通信,这样就能通过 MCP 加强全球开发者的协作,复用全球的开发成果。
MCP 的本质和挑战
根据上文的一系列解释,我们可以总结一下 MCP 的本质:模型上下文协议(Model Context Protocol)并不是一个确定的数据格式或数据结构,它是 描述 MCP Server/MCP Tool 信息的系统提示词和 MCP Server 与 LLM 之间的协同关系的结合 , 解决的是 找接口和 解析接口的问题。
明确了 MCP 本质之后,将其带入到企业级生产应用中,你就会发现,这两个核心点上会有很多挑战,或者说不足。
描述 MCP 信息的系统提示词的挑战
系统提示词的安全性如何保证?
- 这个最核心的系统提示词如果被污染了,LLM 就不能准确知道你有哪些 MCP Server,有哪些 MCP Tool,甚至可能告诉 LLM 错误的,有安全漏洞的 MCP Server 和 MCP Tool,那么对你的 AI 应用来说将是巨大的风险,会导致整个 MCP 流程的瘫痪。
系统提示词如何管理?
- MCP Server 或者 MCP Tool 有了新版本,系统提示词应该也许要有对应的版本管理策略。
系统提示词写的不好,如何方便的快速调试?能不能实时生效?
- 系统提示词是没有标准定义的,理论上每个企业可以定义自己的系统提示词模板,类似 PE 工程。提示词不可能一次性就能写好,需要反复调试,需要有机制做快速的调整,并且可以做到使其实时生效。
如果 MCP Server 很多,那么系统提示词会非常长,岂不是很消耗 Token?如何缩小或精确 MCP Server 和 MCP Tool 的范围?
- 如果你有几十个或更多 MCP Server,那么就有可能有上百个或更多 MCP Tool,所有的信息描述下来放在系统提示词后,这个提示词模板会非常大,显而易见的对 Token 消耗非常大,变相的就是成本高。应该需要一套机制,基于用户的问题,预圈选 MCP Server 和 MCP Tool 的范围,减少 Token,提高效率,很类似联网搜索里的意图识别。
MCP Client 与 MCP Server 之间协同关系的挑战
负责做协同的是 MCP Client,但目前 MCP Client 很少,比如 Cline, Claude,Cursor 等,而且都是 C/S 工具,支持的都是 SSE 协议,企业级的 AI 应用该如何结合?能不能结合?
- 基本上目前市面中的 MCP Client 都无法和企业级的 AI 应用做结合,SSE 这种有状态的协议有很多弊端,比如不支持可恢复性,服务器需要维持长期连接,仅支持服务器 → 客户端消息,无法灵活进行双向通信等。
现存的传统业务能快速转成 MCP Server 吗?能 0 代码改动的转换吗?
- 开发一个 MCP Server 是强依赖各语言的 MCP SDK 的,目前只支持 Python、Java、TS、Kotlin、C#。那如果是 Go 或者 PHP 技术栈的企业怎么办?并且那么多现存的业务全部用 MCP SDK 重构一遍,工作量巨大,也很不现实。
MCP Server 会很多,如何统一管理?
- 有自己开发的 MCP Server,有三方的 MCP Server,还有大量通过某种神秘机制将传统业务转换而来的 MCP Server。这些都应该有一个类似 MCP Hub 或 MCP 市场的东西统一管理起来,方便 MCP Client 去使用。
企业级 AI 应用中,身份认证、数据权限、安全这些如何做?
- 在企业级的应用中,无论哪种协议,哪种架构,哪种业务。身份认证、数据权限、安全防护这些问题都是永远绕不开的。那么在 MCP 这种协同方式下如何实现。