AI大模型学习
1、环境搭建
2、Embedding与向量数据库
3、RAG技术与应用
4、RAG高级技术与实践
5、LlamaIndex知识管理与信息检索
6、基于LlamaIndex开发的中医临床诊疗助手
7、LangChain多任务应用开发
8、Function Calling与Agent 智能体
9、Agent应用与图状态编排框架LangGraph
10、基于LangGraph实现智能分诊系统
11、MCP应用技术开发
12、AI 应用开发新范式 MCP 技术详解
本文档使用 MrDoc 发布
-
+
首页
11、MCP应用技术开发
# MCP应用技术开发 ## 1. MCP基本概念 **MCP(Model Context Protocol 模型上下文协议)** 是Anthropic开源的一种开放协议,可实现LLM应用程序与外部数据源和工具之间的无缝集成。 MCP官方简介:https://www.anthropic.com/news/model-context-protocol MCP文档手册:https://modelcontextprotocol.io/introduction MCP中文文档:https://mcp-docs.cn/introduction MCP官方服务器列表:https://github.com/modelcontextprotocol/servers PythonSDK的github地址:https://github.com/modelcontextprotocol/python-sdk ### 1.1 为什么出现MCP 若开发一个不论是ChatBot还是复杂的Agent的AI应用,都不会再局限于简单的聊天对话,而是需要与外部世界连接,以访问数据源或使用工具。如访问本地文件、访问数据库结构、调用第三方API服务等,那么就需要连接不同的对象,使用不同的接口协议,需要熟悉SQL、第三方开放API接口调用等,这都需要做大量的适配工作。  MCP(Model Context Protocol 模型上下文协议),Anthropic开源,就是用来帮助简化LLM应用与这些外部资源间的集成。它允许LLM应用使用统一的协议来连接到这些外部资源,而不必逐个适配。  MCP的做法是增加了一个中间层:LLM应用通过统一的MCP协议连接中间层(称为MCP Server),而这个中间层会处理与外部资源的对接。 ### 1.2 MCP有哪些好处 - LLM应用的简化:不用适配各种私有协议,只需要知道怎么连接MCP server - LLM应用的快速扩展:随时“插拔”新的MCP Server即可,一个不够就再来一个 - 快速适应变化:若一个外部资源的接口发生变化,只需要对它的MCP Server做修改,所有的LLM应用就可以无缝适应 - 新的AI能力共享生态:通过MCP Server的共享,新的LLM应用可以快速获得各种工具,形成了一种新的合作体系,提高整体效用 ### 1.3 基于MCP的集成架构 基于MCP将LLM应用与外部资源集成的架构可用下图表示:  **MCP Client** MCP Client是由LLM应用程序使用MCP SDK创建并维护的一个Server会话,就像在程序中维护一个数据库的Connection一样,借助MCP SDK可以与MCP Server通信,如查看Server的Tools。在本地模式下,Client与Server是一对一的关系。如果需要连接多个MCP Server,需要自行维护多个Session。 ## 2. MCP两大基础协议介绍 ### 2.1 消息协议:JSON-RPC 2.0 在MCP中规定了唯一的标准消息格式,就是JSON-RPC 2.0 JSON-RPC 2.0是一种轻量级的、用于远程过程调用(RPC)的消息交换协议,使用JSON作为数据格式 **注意:** 它不是一个底层通信协议,只是一个应用层的消息格式标准。这种消息协议的好处,与语言无关(还有语言不支持JSON吗)、简单易用(结构简单,天然可读,易于调试)、轻量灵活(可以适配各种传输方式) ### 2.2 传输协议 #### 2.2.1 STDIO模式 STDIO(Standard Input/Output)是一种基于标准输入(stdin)和标准输出(stdout)的本地通信方式 MCP Client启动一个子进程(MCP Server)并通过stdin和stdout交换JSON-RPC消息来实现通信 其基本通信过程如下:  **详细描述如下:** 1. **启动子进程(MCP Server)** - MCP Client以子进程形式启动MCP Server,通过命令行指定Server的可执行文件及其参数 2. **消息交换** - MCP Client通过stdin向MCP Server写入JSON-RPC消息 - MCP Server处理请求后,通过stdout返回JSON-RPC消息,也可通过stderr输出日志 3. **生命周期管理** - MCP Client控制子进程(MCP Server)的启动和关闭。通信结束后,MCP Client关闭stdin,终止MCP Server #### 2.2.2 基于SSE的Remote模式(MCP标准(2025-03-26版之前)) SSE(服务器发送事件)是一种基于HTTP协议的单向通信技术,允许Server主动实时向Client推送消息,Client只需建立一次连接即可持续接收消息。它的特点是: - 单向(仅Server → Client) - 基于HTTP协议,一般借助一次HTTP Get请求建立连接 - 适合实时消息推送场景(如进度更新、实时数据流等) 由于SSE是一种单向通信的模式,所以它需要配合HTTP Post来实现Client与Server的双向通信 严格的说,这是一种HTTP Post(Client->Server)+ HTTP SSE(Server -> Client)的伪双工通信模式 **这种传输模式下:** - 一个HTTP Post通道,用于Client发送请求。比如调用MCP Server中的Tools并传递参数。注意,此时Server会立即返回 - 一个HTTP SSE通道,用于Server推送数据,比如返回调用结果或更新进度 - 两个通道通过session_id来关联,而请求与响应则通过消息中的id来对应 **其基本通信过程如下:**  **详细描述如下:** 1. **连接建立:** Client首先请求建立 SSE 连接,Server“同意”,然后生成并推送唯一的Session ID 2. **请求发送:** Client通过 HTTP POST 发送 JSON-RPC2.0 请求(请求中会带有Session ID 和Request ID信息) 3. **请求接收确认:** Server接收请求后立即返回 202(Accepted)状态码,表示已接受请求 4. **异步处理:** Server应用框架会自动处理请求,根据请求中的参数,决定调用某个工具或资源 5. **结果推送:** 处理完成后,Server通过 SSE 通道推送 JSON-RPC2.0 响应,其中带有对应的Request ID 6. **结果匹配:** Client的SSE连接侦听接收到数据流后,会根据Request ID 将接收到的响应与之前的请求匹配 7. **重复处理:** 循环2-6这个过程。这里面包含一个MCP的初始化过程 8. **连接断开:** 在Client完成所有请求后,可以选择断开SSE连接,会话结束 简单总结:通过HTTP Post发送请求,但通过SSE的长连接异步获得Server的响应结果 #### 2.2.3 Streamable HTTP模式(MCP标准(2025-03-26版)) 在MCP新标准(2025-03-26版)中,MCP引入了新的Streamable HTTP远程传输机制来代替之前的HTTP+SSE的远程传输模式,STDIO的本地模式不变 该新标准还在OAuth2.1的授权框架、JSON-RPC批处理、增强工具注解等方面进行增加和调整,且在2025.05.08号发布的MCP SDK 1.8.0版本中正式支持了Streamable HTTP **HTTP+SSE这种方式存在问题有:** - 需要维护两个独立的连接端点 - 有较高的连接可靠性要求。一旦SSE连接断开,Client无法自动恢复,需要重新建立新连接,导致上下文丢失 - Server必须为每个Client维持一个高可用长连接,对可用性和伸缩性提出挑战 - 强制所有Server向Client的消息都经由SSE单向推送,缺乏灵活性 **其主要变化部分的基本通信过程如下:**  **这里的主要变化包括:** - Server只需一个统一的HTTP端点(/messages)用于通信 - Client可以完全无状态的方式与Server进行交互,即Restful HTTP Post方式 - 必要时Client也可以在单次请求中获得SSE方式响应,如:一个需要进度通知的长时间运行的任务,可以借助SSE不断推送进度 - Client也可以通过HTTP Get请求来打开一个长连接的SSE流,这种方式与当前的HTTP+SSE模式类似 - 增强的Session管理。Server会在初始化时返回Mcp-Session-Id,后续Client在每次请求中需要携带该MCP-Session-Id。这个Mcp-Session-Id作用是用来关联一次会话的多次交互;Server可以用Session-Id来终止会话,要求Client开启新会话;Client也可以用HTTP Delete请求来终止会话 **Streamable HTTP在旧方案的基础上,提升了传输层的灵活性与健壮性:** - 允许无状态的Server存在,不依赖长连接。有更好的部署灵活性与扩展能力 - 对Server中间件的兼容性更好,只需要支持HTTP即可,无需做SSE处理 - 允许根据自身需要开启SSE响应或长连接,保留了现有规范SSE模式的优势 ## 3. 使用高德地图MCP Server ### 3.1 高德地图 MCP Server 介绍 为实现 LBS 服务与 LLM 更好的交互,高德地图 MCP Server 现已覆盖12大核心服务接口,提供全场景覆盖的地图服务。包括地理编码、逆地理编码、IP 定位、天气查询、骑行路径规划、步行路径规划、驾车路径规划、公交路径规划、距离测量、关键词搜索、周边搜索、详情搜索等。 链接地址:https://lbs.amap.com/api/mcp-server/summary 具体提供的接口详情介绍: **(1)地理编码** name='maps_regeocode' description='将一个高德经纬度坐标转换为行政区划地址信息' inputSchema={'type': 'object', 'properties': {'location': {'type': 'string', 'description': '经纬度'}}, 'required': ['location']} **(2)逆地理编码** name='maps_geo' description='将详细的结构化地址转换为经纬度坐标。支持对地标性名胜景区、建筑物名称解析为经纬度坐标' inputSchema={'type': 'object', 'properties': {'address': {'type': 'string', 'description': '待解析的结构化地址信息'}, 'city': {'type': 'string', 'description': '指定查询的城市'}}, 'required': ['address']} **(3)IP 定位** name='maps_ip_location' description='IP 定位根据用户输入的 IP 地址,定位 IP 的所在位置' inputSchema={'type': 'object', 'properties': {'ip': {'type': 'string', 'description': 'IP地址'}}, 'required': ['ip']} **(4)天气查询** name='maps_weather' description='根据城市名称或者标准adcode查询指定城市的天气' inputSchema={'type': 'object', 'properties': {'city': {'type': 'string', 'description': '城市名称或者adcode'}}, 'required': ['city']} **(5)骑行路径规划** name='maps_bicycling' description='骑行路径规划用于规划骑行通勤方案,规划时会考虑天桥、单行线、封路等情况。最大支持 500km 的骑行路线规划' inputSchema={'type': 'object', 'properties': {'origin': {'type': 'string', 'description': '出发点经纬度,坐标格式为:经度,纬度'}, 'destination': {'type': 'string', 'description': '目的地经纬度,坐标格式为:经度,纬度'}}, 'required': ['origin', 'destination']} **(6)步行路径规划** name='maps_direction_walking' description='步行路径规划 API 可以根据输入起点终点经纬度坐标规划100km 以内的步行通勤方案,并且返回通勤方案的数据' inputSchema={'type': 'object', 'properties': {'origin': {'type': 'string', 'description': '出发点经度,纬度,坐标格式为:经度,纬度'}, 'destination': {'type': 'string', 'description': '目的地经度,纬度,坐标格式为:经度,纬度'}}, 'required': ['origin', 'destination']} **(7)驾车路径规划** name='maps_direction_driving' description='驾车路径规划 API 可以根据用户起终点经纬度坐标规划以小客车、轿车通勤出行的方案,并且返回通勤方案的数据。' inputSchema={'type': 'object', 'properties': {'origin': {'type': 'string', 'description': '出发点经度,纬度,坐标格式为:经度,纬度'}, 'destination': {'type': 'string', 'description': '目的地经度,纬度,坐标格式为:经度,纬度'}}, 'required': ['origin', 'destination']} **(8)公交路径规划** name='maps_direction_transit_integrated' description='公交路径规划 API 可以根据用户起终点经纬度坐标规划综合各类公共(火车、公交、地铁)交通方式的通勤方案,并且返回通勤方案的数据,跨城场景下必须传起点城市与终点城市' inputSchema={'type': 'object', 'properties': {'origin': {'type': 'string', 'description': '出发点经度,纬度,坐标格式为:经度,纬度'}, 'destination': {'type': 'string', 'description': '目的地经度,纬度,坐标格式为:经度,纬度'}, 'city': {'type': 'string', 'description': '公共交通规划起点城市'}, 'cityd': {'type': 'string', 'description': '公共交通规划终点城市'}}, 'required': ['origin', 'destination', 'city', 'cityd']} **(9)距离测量** name='maps_distance' description='距离测量 API 可以测量两个经纬度坐标之间的距离,支持驾车、步行以及球面距离测量' inputSchema={'type': 'object', 'properties': {'origins': {'type': 'string', 'description': '起点经度,纬度,可以传多个坐标,使用分号隔离,比如120,30;120,31,坐标格式为:经度,纬度'}, 'destination': {'type': 'string', 'description': '终点经度,纬度,坐标格式为:经度,纬度'}, 'type': {'type': 'string', 'description': '距离测量类型,1代表驾车距离测量,0代表直线距离测量,3步行距离测量'}}, 'required': ['origins', 'destination']} **(10)关键词搜索** name='maps_text_search' description='关键词搜,根据用户传入关键词,搜索出相关的POI' inputSchema={'type': 'object', 'properties': {'keywords': {'type': 'string', 'description': '搜索关键词'}, 'city': {'type': 'string', 'description': '查询城市'}, 'types': {'type': 'string', 'description': 'POI类型,比如加油站'}}, 'required': ['keywords']} **(11)周边搜索** name='maps_search_detail' description='查询关键词搜或者周边搜获取到的POI ID的详细信息' inputSchema={'type': 'object', 'properties': {'id': {'type': 'string', 'description': '关键词搜或者周边搜获取到的POI ID'}}, 'required': ['id']} **(12)详情搜索** name='maps_around_search' description='周边搜,根据用户传入关键词以及坐标location,搜索出radius半径范围的POI' inputSchema={'type': 'object', 'properties': {'keywords': {'type': 'string', 'description': '搜索关键词'}, 'location': {'type': 'string', 'description': '中心点经度纬度'}, 'radius': {'type': 'string', 'description': '搜索半径'}}, 'required': ['location']})] ### 3.2 申请高德地图API_KEY - 注册并认证开发者:https://lbs.amap.com/ - 进入控制台,创建应用,并添加Key,参考链接:https://lbs.amap.com/api/mcp-server/create-project-and-key ### 3.3 安装依赖 **注意:** 截止2025.04.25 MCP最新版本为1.6.0,建议先使用要求的对应版本进行本项目测试,避免因版本升级造成的代码不兼容。测试通过后,可进行升级测试。 ```python # !pip install mcp==1.6.0 # !pip install requests==2.32.3 ``` ### 3.4 MCP服务功能接口测试 1. 首先需要下载并安装node的环境,直接下载 https://nodejs.org/zh-cn 安装包进行安装即可 2. 测试服务器是否能正常启动:`npx -y @amap/amap-maps-mcp-server` 3. 进入到 `01_AmapMCPServerTest/amapMCPServerTest.py` 运行脚本进行服务接口的单独验证测试 ### 3.5 MCP Client测试 1. 进入到 `01_AmapMCPServerTest/clientChatTest.py` 运行脚本进行服务接口的单独验证测试 2. 在运行脚本之前,需要在 `.env` 文件中配置大模型相关的参数及在 `servers_config.json` 文件中配置需要使用的MCP Server 3. 获取经纬度工具:http://www.jsons.cn/lngcode/ 4. 测试问题参考所示: - 这个113.93029,22.53291经纬度对应的地方是哪里 - 深圳红树林的经纬度坐标是多少 - 112.10.22.229这个IP所在位置 - 深圳的天气如何 - 我要从深圳市南山区中兴大厦骑行到宝安区宝安体育馆,帮我规划下路径 - 我要从深圳市南山区中兴大厦步行到宝安区宝安体育馆,帮我规划下路径 - 我要从深圳市南山区中兴大厦驾车到宝安区宝安体育馆,帮我规划下路径 - 我要从深圳市南山区中兴大厦坐公共交通到宝安区宝安体育馆,帮我规划下路径 - 测量下从深圳市南山区中兴大厦到宝安区宝安体育馆驾车距离是多少 - 深圳市南山区中石化的加油站有哪些,需要有POI的ID - POI为B020016GPH的详细信息 - 深圳市南山区周围10公里的中石化的加油站 ## 4. 自定义MCP Server ```python ### 4.1 实现一个四则运算的MCP Server 实现一个四则运算的MCP Server,具体提供的接口详情介绍: **(1)加法运算** name='add' description='执行加法运算' inputSchema={'properties': {'a': {'title': 'A', 'type': 'number'}, 'b': {'title': 'B', 'type': 'number'}}, 'required': ['a', 'b'], 'title': 'addArguments', 'type': 'object'}) **(2)减法运算** name='subtract' description='执行减法运算' inputSchema={'properties': {'a': {'title': 'A', 'type': 'number'}, 'b': {'title': 'B', 'type': 'number'}}, 'required': ['a', 'b'], 'title': 'subtractArguments', 'type': 'object'}) **(3)乘法运算** name='multiply' description='执行乘法运算' inputSchema={'properties': {'a': {'title': 'A', 'type': 'number'}, 'b': {'title': 'B', 'type': 'number'}}, 'required': ['a', 'b'], 'title': 'multiplyArguments', 'type': 'object'}) **(3)除法运算** name='divide' description='执行除法运算' inputSchema={'properties': {'a': {'title': 'A', 'type': 'number'}, 'b': {'title': 'B', 'type': 'number'}}, 'required': ['a', 'b'], 'title': 'divideArguments', 'type': 'object'})] ``` ### 4.2 自定义四则运算MCP Server测试 - 3加4等于几 - 调用工具计算3+2 - 调用工具计算3-2 - 调用工具计算3*2 - 调用工具计算3/2 ## 5. 自定义 MySQL MCP Server ### 5.1 功能介绍 实现一个与MySQL连接的MCP Server,实现数据源访问和工具使用(SQL语句执行增删改查及联表查询),具体提供的接口详情介绍: 1. **获取资源 URI(Resources)** - uri=AnyUrl('mysql://students_info/data') - uri=AnyUrl('mysql://students_score/data') 2. **SQL语句执行(Tools)** - name='execute_sql' - description='Execute an SQL query on the MySQL server' - inputSchema={'type': 'object', 'properties': {'query': {'type': 'string', 'description': 'The SQL query to execute'}}, 'required': ['query']}, annotations=None ### 5.2 环境准备 ```python # !pip install mysql-connector-python==9.3.0 ``` #### 启动Docker服务 - 首先需要下载并安装docker,直接官网下载 https://www.docker.com/ 安装包进行安装即可 - 打开命令行终端,进入到supportFiles/docker-compose.yaml文件所在的目录,运行如下指令 `docker-compose up -d` - 启动成功后,通过数据库客户端软件连接到本地数据库,并将students_info.sql和students_score.sql文件导入到数据库中作为测试数据表 ### 5.3 MCP Client STDIO 模式测试 1. 进入到03_MySQLMCPServerTest/01_stdioTransportTest中运行脚本 `mysqlMCPServerTest.py` 进行服务接口的单独验证测试 2. 进入到03_MySQLMCPServerTest/01_stdioTransportTest中运行脚本 `clientChatTest.py` 使用大模型进行测试,在运行脚本之前,需要在.env文件中配置大模型相关的参数及在servers_config.json文件中配置需要使用的MCP Server 3. 测试问题,可参考如下: - 有哪些表可以使用 - 查询学生信息表中数据 - 查询学生成绩表中数据 - 查询学生成绩表中分数最高的 - 对学生信息表和学生成绩表进行联表查询,生成每个学生姓名、成绩 - 将学生姓名为张三的改为钱八,并获取最新的信息表 ### 5.4 MCP Client SSE HTTP 模式测试 1. 进入到03_MySQLMCPServerTest/02_sseTransportTest中运行脚本 `mysqlMCPServerTest.py` 进行服务接口的单独验证测试 2. 进入到03_MySQLMCPServerTest/02_sseTransportTest中运行脚本 `clientChatTest.py` 使用大模型进行测试,在运行脚本之前,需要在.env文件中配置大模型相关的参数及在servers_config.json文件中配置需要使用的MCP Server - 先启动 `sseServer.py` 脚本 - 再启动 `clientChatTest.py` 脚本 3. 测试问题,可参考如下: - 有哪些表可以使用 - 查询学生信息表中数据 - 查询学生成绩表中数据 - 查询学生成绩表中分数最高的 - 对学生信息表和学生成绩表进行联表查询,生成每个学生姓名、成绩 - 将学生姓名为张三的改为钱八,并获取最新的信息表 ### 5.5 MCP Client Streamable HTTP 模式测试 1. 进入到03_MySQLMCPServerTest/03_streamableTransportTest中运行脚本 `mysqlMCPServerTest.py` 进行服务接口的单独验证测试 2. 进入到03_MySQLMCPServerTest/03_streamableTransportTest中运行脚本 `clientChatTest.py` 使用大模型进行测试,在运行脚本之前,需要在.env文件中配置大模型相关的参数及在servers_config.json文件中配置需要使用的MCP Server - 先启动 `streamableHttpServer.py` 脚本 - 再启动 `clientChatTest.py` 脚本 3. 测试问题,可参考如下: - 有哪些表可以使用 - 查询学生信息表中数据 - 查询学生成绩表中数据 - 查询学生成绩表中分数最高的 - 对学生信息表和学生成绩表进行联表查询,生成每个学生姓名、成绩 - 将学生姓名为张三的改为钱八,并获取最新的信息表 ## 6. LangGraph MCP Server 使用LangGraph中预置的ReAct架构的Agent集成MCP Server,使用高德地图的MCP Server进行测试 **MCP Integration** 官方参考:https://langchain-ai.github.io/langgraph/agents/mcp/ **Visualize an agent graph** - create_react_agent 官方文档参考:https://langchain-ai.github.io/langgraph/agents/overview/ **ReAct** 虽然路由器允许 LLM 做出单一决策,但更复杂的代理架构通过两种主要方式扩展 LLM 的控制: - 多步骤决策:LLM 可以连续做出一系列决策,而不仅仅是一个决策。 - 工具访问:LLM 可以选择并使用各种工具来完成任务。 ReAct是一种流行的通用代理架构,它结合了这些扩展,集成了三个核心概念。 - 工具调用(Tool calling):允许 LLM 根据需要选择和使用各种工具。 - 记忆(Memory):使代理能够保留和使用前面步骤的信息。 - 规划(Planning):授权 LLM 创建并遵循多步骤计划来实现目标。 官方文档参考:https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#tool-calling-agent ### 6.1 安装依赖 ```python # !pip install langgraph==0.4.5 # !pip install langchain==0.3.25 # !pip install langchain-deepseek # 用于工具和资源集成的 MCP 服务器接口 # !pip install langchain-mcp-adapters==0.1.0 ``` ### 6.2 功能测试 进入到04_ReActAgentAmapMCPServerTest中运行 `amapMCPServer.py` 脚本进行测试 **附件** [【附件】第10章_MCP技术应用与开发.zip](/media/attachment/2025/10/%E7%AC%AC10%E7%AB%A0_MCP%E6%8A%80%E6%9C%AF%E5%BA%94%E7%94%A8%E4%B8%8E%E5%BC%80%E5%8F%91.zip)
李智
2025年10月4日 11:06
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码