掘金 人工智能 07月25日 10:33
AI 应用开发的陷阱:MCP 的致命问题
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入探讨了将大语言模型(LLM)与外部工具连接的主流方法——MCP(Model Context Protocol)模式。该模式通过集中的工具服务简化了开发者工作,但牺牲了模型上下文的精确控制权,可能导致一系列问题,如控制权旁落、上下文浪费、工具质量无法保证以及安全稳定性风险。文章详细分析了MCP模式在特定场景下的优势,如简化本地工具集成和构建开放生态,并强调开发者应根据产品目标和应用场景,权衡利弊,做出最适合的技术决策。

📦 **MCP模式简化了工具集成,但牺牲了开发者对模型上下文的控制权。** MCP模式将工具服务集中化,开发者无需直接管理工具,应用直接调用服务即可。然而,这种分离模式使得开发者失去了精确定义模型可调用工具的能力,工具的增减或描述变更可能在开发者不知情的情况下影响应用,增加了不可控性。

⏳ **MCP模式可能导致宝贵的模型上下文窗口被不相关工具定义占据。** 当一个应用连接多个外部工具服务时,MCP模式下获取的工具列表可能包含大量与当前任务无关的工具描述。这些冗余信息被一并传入大模型,不仅增加了推理成本和时间,还可能干扰模型做出正确的工具选择。

🛠️ **MCP模式下工具描述的质量无法保证,限制了精细化调优。** 工具的名称和描述对模型能否正确使用至关重要。在MCP模式中,客户端开发者无法修改由服务器开发者提供的工具描述。如果描述含糊不清,客户端开发者只能接受或放弃使用该工具,失去了根据自身业务场景“精雕细琢”工具描述的能力。

⚠️ **MCP模式存在严重的安全性和稳定性风险,将应用安全置于外部依赖。** 由于客户端开发者无法控制工具集,应用的安全和稳定高度依赖于外部工具服务的实现。若服务器端引入漏洞或不安全的实现(如文件操作权限过大),所有连接的应用都可能面临灾难性风险,因为开发者无法有效限制或审查外部工具的行为。

💡 **正确的做法是客户端开发者在应用代码中自主构建工具列表,并仅在模型决定调用时才执行后端逻辑。** 开发者应将工具定义权牢牢掌握在自己手中,通过代码精确构建传递给模型的工具列表。当模型确定调用某个工具时,再由客户端代码去调用实际的后端服务或API执行具体操作,从而确保完全的控制权。

将大语言模型(LLM)与外部工具连接,是扩展其能力的主流方法。通过给模型提供工具,它就能查询数据、调用 API,完成更复杂的任务。

提供工具时,可以使用 MCP 模式,简单来说:由一个外部的、集中的工具服务来提供所有工具,开发者写的应用直接调用这个服务,让它去和模型沟通。

这样做表面上简化了开发,开发者不用自己管理工具了。但问题也恰恰出在这里:应用的开发者,失去了对模型上下文的精确控制权。

这是一个根本性的问题,会引发一连串的麻烦。

一个具体的例子:MCP 架构

我们来看看 MCP(Model Context Protocol)这个框架的实现方式。它清楚地展示了这种分离模式。

在 MCP 的世界里,开发者分为两类:

    Server 开发者:他们负责创建工具。Client 开发者:他们负责写真正面向用户的应用,并调用 Server 提供的工具。

在 /weather.py 这个 Server 示例中,Server 开发者用一个 @mcp.tool() 的修饰符来定义一个工具:

@mcp.tool()async def get_alerts(state: str) -> str:    """Get weather alerts for a US state.    Args:        state: Two-letter US state code (e.g. CA, NY)    """    # ... function logic here

工具的名称 get_alerts、它的描述和参数,都由 Server 的开发者在这里定义好了。

然后,一个完全不同的 Client 开发者,在他的应用 client.py 中需要使用工具。他并不会自己定义工具,而是通过代码去“询问”Server 有哪些可用的工具。

## Client开发者写的代码## 向Server询问有哪些可用的工具response = await self.session.list_tools()# 将Server返回的工具列表转换成模型需要的格式available_tools = [{    "name": tool.name,    "description": tool.description,    "input_schema": tool.inputSchema} for tool in response.tools]# 把这个从Server拿到的工具列表,直接传给大模型response = self.anthropic.messages.create(    model="claude-3-5-sonnet",    messages=messages,    tools=available_tools  # <--- 工具在这里被传入)

这段代码清楚地显示了问题所在。Client 开发者写的代码,只是一个搬运工。它从 Server 获取工具列表,然后原封不动地交给大模型。

这就是我们要讨论的核心风险。

1. 控制权交给了别人

AI 应用的核心,是开发者与大模型之间的交互。开发者应该精确地告诉模型在当前场景下,它能做什么。

在上面的例子中,Client 开发者完全放弃了这种控制。如果 weather-server 的开发者某天在服务器上增加了一个新工具,或者修改了 get_alerts 工具的描述,所有使用这个 Server 的 Client 应用,都会在不知情的情况下立刻受到影响。

2. 浪费了宝贵的上下文

大模型的“上下文窗口”是有限且有成本的。

MCP 官方的示例中,就罗列了大量的“即插即用”型 Server,比如 Filesystem、Git、PostgreSQL。一个 Client 应用可能会连接多个 Server。

想象一下,你的应用只是想问个天气,但因为连接了多个 Server,list_tools() 可能会返回十几个不相关的工具(比如文件读写、数据库查询等)。这些多余的工具定义会被全部发送给大模型,不仅增加了推理成本和时间,还会像噪音一样干扰模型,让它难以选择正确的工具。

3. 工具的质量无法保证

工具的名称和描述对模型能否正确使用至关重要。最了解应用需要什么样工具的人,是 Client 开发者自己。

但是,在 MCP 模式下,Client 开发者无法修改 Server 提供的工具描述。如果 Server 的工具描述写得含糊不清(比如一个叫 process_data 的函数),Client 开发者要么只能忍受,要么就得放弃使用整个 Server。他失去了根据自己业务场景,“精雕细琢”工具描述的能力。

4. 安全性和稳定性的风险

这是最严重的问题。由于 Client 开发者无法控制工具集,应用的安全和稳定就依赖于外部的 Server。

以 mcp-server-filesystem 这个官方工具为例,它能执行文件操作。如果一个 Client 应用连接了它,就等于把文件操作的潜力暴露给了大模型。Client 开发者必须完全信任这个 Server 的实现是绝对安全、没有漏洞的。

如果 Server 的开发者在一次更新中,不小心引入了一个允许删除任意文件的 Bug,那么所有连接到这个 Server 的 Client 应用,都可能在用户不知情的情况下,执行危险的操作。这种风险是灾难性的。

正确的做法是什么?

结论很直接:开发者必须在每一次调用大模型时,都拥有对工具集的完全控制权。

这意味着,工具的 JSON 定义应该由 Client 开发者在自己的应用代码中明确构建,而不是通过 session.list_tools() 从外部获取。

当模型决定调用 get_weather_forecast 时,Client 代码再去调用后端服务或 API 来执行具体逻辑。这样一来,决定权始终在 Client 开发者手中。

优势面:无与伦比的易用性和扩展性

话分两头说,尽管 MCP 架构存在上述风险,但我们也必须看到它解决了哪个核心问题:如何让一个已有的、封闭的应用程序(如一个桌面聊天软件),能够轻松地、动态地使用外部工具?

MCP 的易用性在“为 AI 聊天工具集成本地工具”这个场景下,体现得淋漓尽致。

我们可以从官方文档中“Testing your server with Claude for Desktop”这个例子得到启发:

    开发者创建了一个工具:比如 weather.py,它能在本地查询天气。用户有一个现成的聊天工具:Claude for Desktop。用户想让聊天工具用上这个天气功能,他需要做什么?他不需要修改 Claude for Desktop 的任何一行代码。他只需要打开一个名为 claude_desktop_config.json 的配置文件,在里面加上几行:
{    "mcpServers": {        "weather": {            "command": "uv",            "args": ["run", "C:\\path\\to\\weather.py"]        }    }}
    保存文件,重启 Claude for Desktop。然后,这个聊天工具就奇迹般地拥有了调用 weather.py 里 get_alerts 和 get_forecast 工具的能力。

这就是 MCP 模式的魅力所在。 它在这里扮演了一个“热插拔”的插件系统角色。

在这种场景下,“控制权外移”反而成了一种优点,因为它实现了应用核心功能与扩展功能之间的解耦,带来了巨大的灵活性和生态潜力。

结论

所以,MCP 模式及其代表的架构思想,本身并不是一个绝对的好与坏,而是需要开发者清醒认识它并做出抉择。

最终,选择哪条路,取决于你的产品目标和应用场景。理解这背后的利弊,才能做出最适合自己项目的技术决策。

扩展链接:

MCP快速入门—快速构建自己的服务器

MCP 核心架构解析

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

大语言模型 LLM 工具连接 MCP模式 AI应用开发
相关文章