返回顶部
热门问答 更多热门问答
技术文章 更多技术文章

AI开发者必看:深度解析MCP,打造高效LLM应用的秘密武器!

[复制链接]
链载Ai 显示全部楼层 发表于 昨天 21:52 |阅读模式 打印 上一主题 下一主题

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;color: rgb(63, 63, 63);visibility: visible;">

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;color: rgb(63, 63, 63);visibility: visible;">

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">如果你活跃于技术影响者聚集的社交媒体平台,那么现在想必已经听说过模型上下文协议(MCP)了。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">诚然,它可能曾受到过度炒作,但了解它仍是十分必要的,因为MCP注定会成为未来AI流水线中的重要组成部分。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">MCP本身,抑或是基于其演进的各项改进,都将成为未来AI流水线中不可或缺的一环。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">在本文中,我们将探讨MCP的工作原理,并通过构建一个使用它的智能代理系统来加深理解。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;color: rgb(1, 155, 252);">让我们开始吧!

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;padding-left: 12px;color: rgb(63, 63, 63);border-radius: 6px;background: color-mix(in srgb, rgb(1, 155, 252) 8%, transparent);">为什么最初要构建MCP这样的东西?

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">假设现在是2024年初,你正在构建一个用于股票市场分析的LLM应用。

你可能需要:

  • • 为应用中使用的不同LLM编写特定代码。
  • • 如果数据存储在不同数据库中,需要为每个数据库编写特定代码。
  • • 为每个金融数据源(如Yahoo Finance、Bloomberg、SEC文件等)定义自定义API接口。
  • • 构建自定义数据预处理管道。

等等!

这无疑会带来诸多不便!

任何一个部分的微小改动都会迫使你重写代码,导致系统难以扩展。

正因如此,Anthropic开源了MCP,使得自2024年11月之后,基于LLM的应用开发变得更加便捷。

让我们来了解一下是如何实现的。

什么是MCP?

根据官方文档所述:

模型上下文协议(MCP)是一个开放协议,它规范了应用程序如何向LLM提供上下文。

以往,我们通过分散且不稳定的集成方式连接LLM与数据源,而MCP则以统一协议取代了这种局面,从而使连接更可靠,也大大简化了我们的工作。

以下是Anthropic对它的评价:

开发人员现在可以基于一个标准协议进行构建,而不必为每个数据源维护独立的连接器。
可以将MCP想象成AI应用的USB-C接口。
正如USB-C提供了一种标准化方式,将设备连接到各种外部设备和附件一样,MCP也提供了一种标准化的方式,将AI模型连接到不同的数据源和工具。
—— Anthropic 关于 MCP 的说明 (https://www.anthropic.com/news/model-context-protocol)

一言以蔽之:

模型上下文协议是一个“协议”,它允许“模型”获取相关的“上下文”。

使用MCP前后LLM与数据源连接的简化示意图

现在我们理解了MCP解决的问题,接下来学习它的组成部分。

MCP的运作机制

MCP主要由三个核心组件构成:

  1. 1. 主机(Hosts)
  2. 2. 服务器(Servers)
  3. 3. 客户端(Clients)

我们来逐一讲解。

MCP主机

这些是用户直接交互的应用程序。

例如,Claude桌面版、集成开发环境(如Cursor和VS Code),或其他由AI驱动的工具。

这是LLM运行的核心所在。

MCP服务器

这些是小巧、专用的程序,根据其用例公开特定的功能。

这些服务器可以通过可由MCP主机内的LLM调用的 工具(Tools)(https://modelcontextprotocol.io/specification/2025-06-18/server/tools) 安全地连接到 资源(Resources)(https://modelcontextprotocol.io/specification/2025-06-18/server/resources)。

这些资源可以是:

  • • 本地文件/服务/数据库
  • • 基于网络的各种服务,例如数据库、电子邮件、天气、日历等(通过API)

服务器还公开 提示(Prompt)(https://modelcontextprotocol.io/specification/2025-06-18/server/prompts) 模板,客户端可以使用这些模板从MCP服务器获取结构化响应。

MCP客户端

这是主机的一个组件,充当通信层。

每个客户端与一个MCP服务器保持专用连接,负责处理协议的请求-响应模式、错误处理以及 连接生命周期(https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle) 管理。

你可以把它们看作是能够理解主机语言和MCP协议的“翻译官”。

客户端如何与服务器通信?

传输机制(Transport)(https://modelcontextprotocol.io/docs/concepts/transports) 是一种通信通道,负责处理客户端与服务器间信息(消息)交换的底层原理。

MCP中交换的消息共有三种类型,它们均采用 JSON-RPC 2.0(https://www.jsonrpc.org/specification) 格式。

这些消息类型是:

  1. 1.请求(Requests):请求某项内容的消息,期望得到响应。

在下面的示例中,客户端请求服务器为查询“旧金山”调用“天气”工具,并期望得到响应。

{
"jsonrpc":"2.0",
"id":1,
"method":"tools/call",
"params":{
"name":"weather",
"arguments":{
"location":"San Francisco"
}
}
}

2. 响应(Responses):回复先前请求的消息。

在下面的示例中,服务器回复了ID为1的请求,提供了查询“旧金山”的具体天气数据:温度(temperature)和状况(condition)。

{
"jsonrpc":"2.0",
"id":1,
"result":{
"temperature":"72°F",
"condition":"sunny"
}
}

3. 通知(Notifications):告知某事的消息,不期望得到响应。

在下面的示例中,服务器发送了一个进度更新消息,但不期望任何回复(请注意没有id字段)。

{
"jsonrpc":"2.0",
"method":"$/progress",
"params":{
"message":"Processing data...",
"progress":0.8
}
}

MCP使用以下两种常见的通信机制来交换这些消息:

  1. 1.标准输入/输出(stdio)
    这种机制允许通过计算机上的标准输入和输出流进行通信。它是一种更简单的机制,最适用于:
  • 本地集成(当客户端和服务器位于同一台机器上时)
  • • 构建命令行工具和使用shell脚本
  • 2.流式HTTP(Streamable HTTP)
    这种机制使用:
    • •HTTP POST请求用于客户端到服务器的通信,以及
    • • 可选的服务器发送事件(SSE)流用于服务器到客户端的通信。
      它最适用于构建基于Web的集成,可以支持多个并发客户端和可恢复的连接。
    MCP用于交换信息的两种标准传输机制

    至此,关于MCP的理论知识讲解已告一段落。

    接下来,我们将进入代码实践环节!

    构建一个基于MCP的物理问答智能代理系统

    自MCP发布以来,MCP服务器的数量呈爆炸式增长。

    可以在这里找到这些服务器的完整列表:https://github.com/modelcontextprotocol/servers

    按照每个服务器的说明,将这些服务器与主机(如Claude桌面版或IDE)集成非常容易。

    但既然我们正在学习从基础构建事物,那就不妨自己实现一个MCP服务器吧。

    我们将构建一个服务器,其中包含多个用于计算物理问题解决方案的工具。

    以下是实现步骤:

    1. 使用“uv”创建新项目

    本教程中,我们将使用“ uv(https://docs.astral.sh/uv/) ”作为包管理器。

    如果你是新手,请按照 此页面上的说明(https://docs.astral.sh/uv/getting-started/installation/) 进行安装。

    uv init physics-solver-mcp

    cdphysics-solver-mcp

    uv venv .venv

    source.venv/bin/activate

    2. 安装依赖

    在完成项目初始化后,我们需要安装几个关键的依赖包,包括mcpcrewai-tools。我们通过以下命令安装mcpPython包:

    uvaddmcpcrewai"crewai-tools[mcp]"

    3. 设置环境变量

    我们在项目文件夹中创建一个名为.env的文件,其中包含我们的OpenAI API密钥。

    在调用基于gpt-4o-mini模型的代理时将使用此密钥。

    OPENAI_API_KEY="YOUR_KEY_GOES_HERE"

    4. 创建MCP服务器

    我们将使用 FastMCP (https://github.com/jlowin/fastmcp),它是用于在Python中处理模型上下文协议的标准框架。

    我们创建一个名为physics_server.py的文件,并编写一些与服务器相关的工具,每个工具都使用@mcp.tool()装饰器进行指定。

    """一个实现模型上下文协议的物理MCP服务器。
    此服务器提供物理公式作为工具,可供MCP客户端发现和使用。
    """

    frommcp.server.fastmcpimportFastMCP

    mcp = FastMCP("Physics-Server")

    # 计算动能的工具
    @mcp.tool()
    defkinetic_energy(mass:float, velocity:float) ->dict:
    """计算运动物体的动能。

    公式: KE = 1/2 × 质量 × 速度²

    参数:
    mass: 物体质量,单位千克 (kg)。必须为正值。
    velocity: 物体速度,单位米/秒 (m/s)。可为正或负。

    返回:
    动能,单位焦耳 (J)
    """
    ifmass <=0:
    raiseValueError("质量必须为正值")

    ke =0.5* mass * (velocity **2)

    returnke

    # 计算重力势能的工具
    @mcp.tool()
    defgravitational_potential_energy(mass:float, height:float, g:float=9.81) ->dict:
    """计算物体在特定高度处的重力势能。

    公式: PE = 质量 × 重力加速度 × 高度

    参数:
    mass: 物体质量,单位千克 (kg)。必须为正值。
    height: 物体相对于参考点的高度,单位米 (m)。必须为非负值。
    g: 重力加速度,单位米/秒²。默认为 9.81 (地球表面)。

    返回:
    重力势能,单位焦耳 (J)
    """
    ifmass <=0:
    raiseValueError("质量必须为正值")
    ifheight <0:
    raiseValueError("高度必须为非负值")
    ifg <=0:
    raiseValueError("重力加速度必须为正值")

    pe = mass * g * height

    returnpe

    # 减去两个数字的工具
    @mcp.tool()
    defsubtract(a:float, b:float) ->dict:
    """减去两个数字。

    参数:
    a: 第一个数字。
    b: 第二个数字。

    返回:
    a 和 b 之间的差值。
    """

    returna - b


    if__name__ =="__main__":
    mcp.run(transport="stdio")# 使用STDIO传输

    5. 创建MCP客户端

    接下来,我们用 CrewAI(https://www.crewai.com/) 框架搭建一个智能代理系统,该系统将使用我们的MCP服务器工具来解决给定的物理问题。

    如果你是CrewAI的新手,可以考虑查阅这篇 关于构建你的第一个AI代理的教程(https://intoai.pub/p/building-your-first-ai-Agent),了解如何使用这个框架。

    crewai-tools中的MCPServerAdapter(https://docs.crewai.com/en/mcp/overview#key-concepts-%26-getting-started) 类是连接MCP服务器并使其工具可供CrewAI代理使用的主要方式。

    使用Python上下文管理器(with语句)是此类的推荐方法,因为它会自动处理与MCP服务器连接的启动和停止。

    fromcrewaiimportAgent, Task, Crew
    fromcrewai_toolsimportMCPServerAdapter
    frommcpimportStdioServerParameters
    importos

    # 为物理服务器创建一个StdioServerParameters对象
    server_params=StdioServerParameters(
    command="python3",
    args=["physics_server.py"],
    env={"UV_PYTHON":"3.11", **os.environ},
    )

    # 使用StdioServerParameters对象创建MCPServerAdapter
    withMCPServerAdapter(server_params)astools:
    print(f"可用的物理工具:{[tool.namefortoolintools]}")

    agent = Agent(
    role="物理专家",
    goal="使用基本能量计算解决物理问题。",
    backstory="一位经验丰富的物理学家,对经典力学和能量原理有深入了解。能够应用动能和势能概念解决实际问题。",
    tools=tools,
    verbose=True,
    )

    task = Task(
    description="解决这个物理问题: {physics_problem}",
    expected_output="详细的分步解决方案,显示所有计算、中间值和带有正确单位的最终答案。使用可用的物理工具进行动能和势能计算。",
    agent=agent,
    )

    crew = Crew(
    agents=[agent],
    tasks=[task],
    verbose=True,
    )

    # 物理问题
    crew_inputs = {
    "physics_problem":"""
    一辆质量为800公斤的过山车从50米高的山顶静止启动。
    随后,过山车沿山坡下行,到达底部时速度达到25米/秒。

    已知:
    - 汽车质量: 800公斤
    - 初始高度: 50米
    - 最终速度: 25米/秒
    - 重力加速度: 9.81米/秒²

    问题:
    1. 计算过山车在山顶的初始重力势能。
    2. 计算过山车在山底的最终动能。
    3. 比较初始势能和最终动能,并解释任何差异。
    4. 如果过山车要爬上另一座山,如果其所有动能都转化回势能,它能达到的最大高度是多少?
    """
    }

    result = crew.kickoff(inputs=crew_inputs)

    print(result)

    我们通过以下命令运行MCP客户端。

    uvrunclient.py

    这是我们得到的结果,运行效果符合预期!

    1. Initial Gravitational Potential Energy: 392400 J
    2. Final Kinetic Energy: 250000 J
    3. The initial potential energy is greater than the final kinetic energy due to energy losses from friction and air resistance.
    4. Maximum Height: 31.87 m

    从日志中可以看到,我们的代理顺利调用了这些MCP服务器工具完成了任务。

    终端上的CrewAI日志

    关于MCP的讲解到这里就结束了。

    你是否在自己的应用程序中使用过它?请在下方评论区分享你的经验

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

链载AI是专业的生成式人工智能教程平台。提供Stable Diffusion、Midjourney AI绘画教程,Suno AI音乐生成指南,以及Runway、Pika等AI视频制作与动画生成实战案例。从提示词编写到参数调整,手把手助您从入门到精通。
  • 官方手机版

  • 微信公众号

  • 商务合作

  • Powered by Discuz! X3.5 | Copyright © 2025-2025. | 链载Ai
  • 桂ICP备2024021734号 | 营业执照 | |广西笔趣文化传媒有限公司|| QQ