大模型Agent的 “USB”接口!| 一文详细了解MCP(模型上下文协议)
如果你真的想学习大模型,请不要去网上找那些零零碎碎的教程,真的很难学懂!你可以根据我这个学习路线和系统资料,制定一套学习计划,只要你肯花时间沉下心去学习,它们一定能帮到你!
引言
之前的时候,让大模型做外部工具调用基本上都是通过Function Calling的方式,最近随着大模型Agent工作流的兴起,有一个新的概念:MCP逐渐进入大家的视野,基于MCP,它可以让非开发人员在不需要编辑Agent逻辑的情况下,为代理添加工具。为此,今天作者带大家了解一下MCP到底是什么?文章内容安排如下:
- 什么是MCP?
- MCP工作机制
- MCP 实际使用案例
- Function calling和MCP的区别
- 关于MCP的争议
- 参考
什么是MCP?
MCP英文名:Model Context Protocol,中文名:模型上下文协议 。MCP最早于2024年11月底,由 Anthropic 推出的一种开放标准,旨在统一大语言模型(LLM)与外部数据源和工具之间的通信协议,为大型语言模型(LLM)应用提供标准化接口,使其能够连接和交互外部数据源和工具。打个比方,MCP 可以被视为 AI-Agent 系统的“USB”。通过创建USB接口协议,基于这个协议,任何 USB 设备都可以连接到具有USB端口的设备。同理,MCP的出现相当于为 AI 应用程序创建了一种标准化方式,让AI应用可以连接各种数据源和工具。
其实,在 USB 出现之前,每个设备都需要自己的专有连接器。同样,在 MCP 出现之前,开发人员必须为 AI 应用程序和数据源的每种组合创建自定义集成。MCP 建立了一个通用的“即插即用”协议,允许任何兼容 MCP 的客户端与任何兼容 MCP 的服务器协同工作,从而大大降低了集成复杂性和开发时间。
MCP工作机制
MCP 遵循客户端-服务器架构,有五个主要组件:MCP Hosts:希望通过 MCP 访问数据的 AI 工具(聊天客户端、IDE、Agent、Agentic Workflows);
MCP Client:与服务器保持 1:1 连接的协议客户端,负责发送请求给 MCP 服务器,服务器则将这些请求转发给相应的资源;
MCP Severs:通过标准化模型上下文协议,为 Client 端提供上下文、工具和提示;
Local Data Sources:包含信息的本地数据库、文件和API服务;
Remote Services:MCP 服务器可以连接到的外部 API 或者数据库;
下面是一个MCP的基本流程:其实整个 MCP 协议核心的在于 Server, Host 和 Client 相信熟悉计算机网络的都不会陌生,非常好理解,但是 Server 如何理解呢?对于MCP 服务器来说,其主要提供以下的三个方面的服务(当然也可以是其它定制内容):
- 资源:可以引用和检索的数据对象。这些包括文档、图像、数据库架构和其他结构化数据。
- 提示:用于生成与语言模型的有效交互的模板,针对特定任务或领域进行了优化。
- 工具:语言模型可以执行的函数,用于执行查询数据库、调用 API 或处理数据等操作。 下面举个Text-to-SQL的例子来让大家更好的理解MCP 的工作机制。
在没有 MCP的情况下,每个 SQL 客户端都需要为每个对应的的数据库实现这一点。下面是典型的Text-to-SQL任务,示意图如下:当用户问:“帮我查一下所有年龄大于 30 岁的客户的姓名”。那么LLM首先需要知道数据库的结构信息,例如:表名、列名、主键等;然后基于LLM的理解将客户问题映射到SQL查询语句上,接着给到SQL客户端进行执行并拿到结果;最后LLM结合客户问题以及SQL查询结果给出回复。
有了 MCP,SQL 客户端只需实现 MCP 客户端协议,每个数据库供应商只需实现一次 MCP 服务器。下面是有MCP的Text-to-SQL任务的示意图,其实本质上是通过引入一个中间层——MCP,将一个 M×N 的问题转化为 M+N 的问题。
对于大模型Agent来说,通过MCP客户端,可以告诉 AI Agent 目前存在哪些服务,哪些 API,哪些数据源,AI Agent 可以根据Server提供的信息来决定是否调用某个服务,然后通过 Function Calling 来执行函数。单领出来上图的MYSQL MCP Server出来,套用MCP 服务器提供的三个方面的能力:资源、提示、工具,则有下图。其中资源(Resources):从数据库中提取的架构信息;提示(Prompts):帮助模型生成正确 SQL 的数据库域特定提示;工具(Tools):针对数据库执行 SQL 命令;
MCP 实际使用案例
假设我们想让 AI Agent 完成自动搜索 GitHub Repository,接着搜索 Issue,然后再判断是否是一个已知的 bug,最后决定是否需要提交一个新的 Issue 的功能。那么我们就需要创建一个 Github MCP Server,这个 Server 需要提供查找 Repository、搜索 Issues 和创建 Issue 三种能力。
直接来看以下代码:
// 创建mcp server
const server = new Server(
{
name: "github-mcp-server",
version: VERSION,
},
{
capabilities: {
tools: {},
},
}
);
// 定义mcp server 的工具及其描述
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "search_repositories",
description: "Search for GitHub repositories",
inputSchema: zodToJsonSchema(repository.SearchRepositoriesSchema),
},
{
name: "create_issue",
description: "Create a new issue in a GitHub repository",
inputSchema: zodToJsonSchema(issues.CreateIssueSchema),
},
{
name: "search_issues",
description: "Search for issues and pull requests across GitHub repositories",
inputSchema: zodToJsonSchema(search.SearchIssuesSchema),
}
],
};
});
// 定义mcp server 的工具函数的参数
server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
if (!request.params.arguments) {
thrownewError("Arguments are required");
}
switch (request.params.name) {
case"search_repositories": {
const args = repository.SearchRepositoriesSchema.parse(request.params.arguments);
const results = await repository.searchRepositories(
args.query,
args.page,
args.perPage
);
return {
content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
};
}
case"create_issue": {
const args = issues.CreateIssueSchema.parse(request.params.arguments);
const { owner, repo, ...options } = args;
const issue = await issues.createIssue(owner, repo, options);
return {
content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
};
}
case"search_issues": {
const args = search.SearchIssuesSchema.parse(request.params.arguments);
const results = await search.searchIssues(args);
return {
content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
};
}
default:
thrownewError(`Unknown tool: ${request.params.name}`);
}
} catch (error) {}
});
// 启动cp server服务
asyncfunction runServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("GitHub MCP Server running on stdio");
}
runServer().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});
上面的代码中,我们通过 server.setRequestHandler
来告诉 Client 端我们提供了哪些能力,通过 description
字段来描述这个能力的作用,通过 inputSchema
来描述完成这个能力需要的输入参数。
我们再来看一下具体的实现代码:
export const SearchOptions = z.object({
q: z.string(),
order: z.enum(["asc", "desc"]).optional(),
page: z.number().min(1).optional(),
per_page: z.number().min(1).max(100).optional(),
});
exportconst SearchIssuesOptions = SearchOptions.extend({
sort: z.enum([
"comments",
...
]).optional(),
});
exportasyncfunction searchUsers(params: z.infer<typeof SearchUsersSchema>) {
return githubRequest(buildUrl("https://api.github.com/search/users", params));
}
exportconst SearchRepositoriesSchema = z.object({
query: z.string().describe("Search query (see GitHub search syntax)"),
page: z.number().optional().describe("Page number for pagination (default: 1)"),
perPage: z.number().optional().describe("Number of results per page (default: 30, max: 100)"),
});
// 查找 Repository
exportasyncfunction searchRepositories(
query: string,
page: number = 1,
perPage: number = 30
) {
const url = new URL("https://api.github.com/search/repositories");
url.searchParams.append("q", query);
url.searchParams.append("page", page.toString());
url.searchParams.append("per_page", perPage.toString());
const response = await githubRequest(url.toString());
return GitHubSearchResponseSchema.parse(response);
}
可以很清晰的看到,最终实现是通过了 https://api.github.com
的 API 来实现和 Github 交互的,我们通过 githubRequest
函数来调用 GitHub 的 API,最后返回结果。
在调用 Github 官方的 API 之前,MCP 的主要工作是描述 Server 提供了哪些能力(给 LLM 提供),需要哪些参数(参数具体的功能是什么),最后返回的结果是什么。
如果我们想要实现一个更强大的 AI Agent,例如我们想让 AI Agent 自动的根据本地错误日志,自动搜索相关的 GitHub Repository,然后搜索 Issue,最后将结果发送到 Slack。
那么我们可能需要创建三个不同的 MCP Server,一个是 Local Log Server,用来查询本地日志;一个是 GitHub Server,用来搜索 Issue;还有一个是 Slack Server,用来发送消息。
AI Agent 在用户输入 我需要查询本地错误日志,将相关的 Issue 发送到 Slack
指令后,自行判断需要调用哪些 MCP Server,并决定调用顺序,最终根据不同 MCP Server 的返回结果来决定是否需要调用下一个 Server,以此来完成整个任务。
Function calling和MCP的区别
MCP(Model Context Protocol)和 Function Calling(函数调用)都是用于增强大型语言模型(LLM)能力的机制,但它们的设计目标和应用方式有所不同。其中Function Calling 更适合 结构化 API 调用,MCP 更适合 开放式 AI 代理生态,它可以让使 LLM 可以动态发现、扩展工具,适用于更复杂、通用的 AI 助手场景。
两者并不互斥,而是可以结合使用。例如,一个支持 MCP 的 AI 代理可以同时支持 Function Calling,以增强工具调用能力。下面是两者质检的对比比较:
Function Calling | MCP | |
---|---|---|
调用方式 | 由 LLM 直接调用预定义的函数,返回结构化数据 | 代理或 LLM 通过协议与工具交互,可动态发现工具 |
数据格式 | JSON(带有方法名称和参数) | 采用标准化协议,可扩展性更强 |
灵活性 | 需要在模型 API 级别定义函数 | 允许开发者动态添加、修改工具 |
适用场景 | 适合固定的 API 交互,如数据库查询、调用外部 API | 适合开放代理生态,用户可自由扩展工具 |
厂商依赖 | 由 OpenAI、Google 等公司定义,适用于其特定模型 | 开放标准,可用于多个 LLM(Claude、GPT 等) |
关于MCP的争议
MCP是昙花一现,还是未来人工智能的标准。在最近的推文中,LangChain 官方发起了一项投票,结果显示 40% 的人支持 MCP。LangChain 首席执行官Harrison和 LangGraph 领导人Nuno就 MCP展开了激烈的讨论。
其中,Harrison认为MCP是有用的,尤其是在用户无法控制底层代理的情况下,例如在Claude Desktop、Cursor等工具中,用户可以通过MCP为这些代理添加默认不支持的工具,并可以让非开发人员(如主题专家)在不需要编辑代理逻辑的情况下,为代理添加工具,使代理构建更易于普及。
尽管当前的MCP代理可能不够可靠,但随着底层模型的改进,代理的性能会提升。哈里森认为MCP的价值在于其能够实现的长尾连接和集成,类似于Zapier的工作流自动化功能。
Nuno 对MCP的实用性持怀疑态度。他认为,代理的其他部分(如系统消息和架构)需要根据提供的工具进行调整,否则很难实现理想的性能。他指出,即使在为特定工具量身定制的代理中,当前模型调用正确工具的成功率也只有一半。努诺引用贝索斯的话,强调用户的期望是不断上升的。
只有完全控制整个堆栈(包括用户界面、提示、架构和工具)的团队,才能满足这些不断提高的期望。此外,Nuno 认为MCP目前的形式因素存在缺陷,如需要在本地终端运行服务器,且仅与桌面应用程序兼容。他还指出,尽管MCP的生态系统可能在增长,但实际应用并不广泛。
普通人如何抓住AI大模型的风口?
领取方式在文末
为什么要学习大模型?
目前AI大模型的技术岗位与能力培养随着人工智能技术的迅速发展和应用 , 大模型作为其中的重要组成部分 , 正逐渐成为推动人工智能发展的重要引擎 。大模型以其强大的数据处理和模式识别能力, 广泛应用于自然语言处理 、计算机视觉 、 智能推荐等领域 ,为各行各业带来了革命性的改变和机遇 。
目前,开源人工智能大模型已应用于医疗、政务、法律、汽车、娱乐、金融、互联网、教育、制造业、企业服务等多个场景,其中,应用于金融、企业服务、制造业和法律领域的大模型在本次调研中占比超过 30%。
随着AI大模型技术的迅速发展,相关岗位的需求也日益增加。大模型产业链催生了一批高薪新职业:
人工智能大潮已来,不加入就可能被淘汰。如果你是技术人,尤其是互联网从业者,现在就开始学习AI大模型技术,真的是给你的人生一个重要建议!
最后
如果你真的想学习大模型,请不要去网上找那些零零碎碎的教程,真的很难学懂!你可以根据我这个学习路线和系统资料,制定一套学习计划,只要你肯花时间沉下心去学习,它们一定能帮到你!
大模型全套学习资料领取
这里我整理了一份AI大模型入门到进阶全套学习包,包含学习路线+实战案例+视频+书籍PDF+面试题+DeepSeek部署包和技巧,需要的小伙伴文在下方免费领取哦,真诚无偿分享!!!
vx扫描下方二维码即可
加上后会一个个给大家发
部分资料展示
一、 AI大模型学习路线图
整个学习分为7个阶段
二、AI大模型实战案例
涵盖AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,皆可用。
三、视频和书籍PDF合集
从入门到进阶这里都有,跟着老师学习事半功倍。
四、LLM面试题
五、AI产品经理面试题
六、deepseek部署包+技巧大全
😝朋友们如果有需要的话,可以V扫描下方二维码联系领取~
更多推荐
所有评论(0)