掘金 人工智能 前天 22:44
Spring Ai 从Demo到搭建套壳项目(二)实现deepseek+MCP client让高德生成昆明游玩4天攻略
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文探讨了如何利用Model Context Protocol (MCP) 协议,结合Spring AI框架,使LLM(如DeepSeek)能够获取最新数据,并实现与外部服务的交互。通过配置MCP客户端,LLM可以调用各种工具,例如高德地图,从而回答需要实时信息的问题,如行程规划。文章详细介绍了MCP的原理、Spring AI的配置方法,以及如何通过代码实现与MCP服务器的连接,并最终展示了使用DeepSeek和MCP构建应用的功能,为开发者提供了实践指南。

💡 MCP协议是LLM与外部服务通信的关键,类似于HTTP协议,允许LLM作为客户端与提供各种功能的MCP服务器交互。

🛠️ Spring AI框架简化了MCP客户端的配置和使用,支持SSE和stdio两种连接方式,方便开发者接入不同的MCP服务器。

🗺️ 通过配置高德地图MCP服务器,LLM可以调用地图工具,实现行程规划、路线查询等功能,为用户提供智能化的服务。

⚙️ LLM结合MCP的工作流程包括思考、行动、观察三个步骤,通过调用工具、获取结果,逐步完善回答,实现复杂任务。

🚀 开发者可以使用Spring AI和MCP构建类似Cursor的应用,从而实现更智能、更个性化的服务,并探索更多可能性。

前言

上一章节说到LLM(deepseek)可以对话,但是获取不到最新的数据。那如果想获取最新的数据怎么办?那就要利用MCP协议的server,让LLM作为Client,知道某个MCP server提供哪些能力,然后结合这些能力来组织答案。

我觉得MCP是LLM里最实用的功能,你有没有想过,让LLM告诉你假期行程、理财实时数据并分析、券商实时数据?

这次将会使用spring ai结合MCP的方式来使用Chat对话。

一、什么是MCP?

MCP就是Model Context Protocol,相当于像HTTP的一个网络协议。用于服务和服务之间传输数据和通信。就像大家的网页都通过http访问后端,那就是大家使用MCP协议,才可以跟LLM通信。

二、为什么要用MCP

场景:你问deepseek,弄一个广州三天两夜游行程,他需要知道未来几天的广州天气预报,广州几个几点的坐标,每个坐标之间距离,如何使用公交完成行程。但是这些实时或需要精确度问题,deepseek是不知道,他只知道广州的著名景点有哪些,因为这些在一年前的数据都能搜索出来。如何实现精确回答实时内容的问题呢,请看下文。

三、LLM怎么结合MCP

上述问题中,涉及多次访问外部拿数据,并依据结果给出最终回答的话,一般都是基于ReAct原理来做的。这里提到的ReAct就是所谓的智能体,英文文档里叫Agent

LLM处理的步骤如下:

    思考Thought:即,如果要回答这个问题,首先要做什么行动Act:根据问题调用工具,并记录工具的结果 就是Tool calling的过程。 (tool calling后面讲)。观察Obs:是否能做出最终回答,如果不能,则回到第一步,如果能做出最终答复,回答问题

[workflow]

LLM结合MCP实现对话的工作流程

这个步骤在官网叫Function calling

    初始化客户端启动时,就要去连接到各个你配置好的MCP服务器

你现在就是图中,最左边的client,通过一个像http层面的协议跟外部通信。以cursor举例,就像这里配置各个mcp服务器

    获取可用工具列表

就像cursor,他会问各个mcp服务器“你们提供什么能力”,下面tool里的就是他们的能力。

    接收用户输入,也就是对应上面图[workflow]的第一步

    调用AI模型处理输入,ai model就会结合已有的工具,思考用哪些方法。如果用到方法了,就返回给客户端,告诉让客户端要调用mcp

    执行必要的工具调用,这里就对应[workflow]的第三步,调用客户端就像curosr会调用MCP。但cursor做得不是很好的地方,就是每次调用MCP都需要人为点一下按钮,不够自动化。

    返回处理结果循环继续或结束会话

数据传递的过程上就是

Request :- messages:- UserMessage:- text: What is the square root of 475695037565?- AiMessage:- toolExecutionRequests:- squareRoot(475695037565)- ToolExecutionResultMessage:- text: 689706.486532Response :- AiMessage:- text: The square root of 475695037565 is 689706.486532.

四、现在就来用spring ai mcp client实现上面的需求

spring ai支持两种方式连接mcp server,一种是sse 事件流接口,一种是stdio标准io。

引入依赖

接着上一章,我是使用spring-ai-starter的框架,所以使用的是spring-ai-starter-model-deepseek,如果要看spring-ai-alibaba,我下一章节再讲。

<dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>        <version>3.3.4</version>    </dependency>    <dependency>        <groupId>org.springframework.ai</groupId>        <artifactId>spring-ai-starter-model-deepseek</artifactId>        <version>1.0.0</version>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-webflux</artifactId>        <version>3.3.4</version>    </dependency>    <dependency>        <groupId>org.springframework.ai</groupId>        <artifactId>spring-ai-starter-mcp-client</artifactId>        <version>1.0.0</version>    </dependency></dependencies>

关键是这个spring-ai-starter-mcp-client要引入,代表能跟mcp server通信。

配置LLM模型内容

server:  port: 8081spring:  application:  name: spring-ai-deepseek-chat-model-example  ai:    deepseek:      api-key: 你的key      base-url: "https://api.deepseek.com"      chat:        options:          model: deepseek-chat      embedding:        enabled: false

spring ai sse连接方式

我们以高德案例为例。

##spring: 接着上面的LLM配置填写    mcp:      client:        type: ASYNC        sse:          connections:            amap:              url: https://mcp.amap.com/sse              api-key: 你的key

这里就配置了高德MCP server,这里注意一个点,很多文章都已localhost:8080填在url上,就没有人演示如何使用公网的mcp server,连官网都没写好api-key要做为一个yml的key与url平级。搞得我之前一直把key填在url里,url: mcp.amap.com/sse?key=xxx… 搞得我一直报403拒绝访问。

spring ai stdio连接方式

mcp:  client:    type: ASYNC    sse:      connections:        amap:          url: https://mcp.amap.com/sse          api-key: 你的key    stdio:      servers-configuration: classpath:/mcp-servers-config.json

你也可以同时配置stdio方式,因为市面上的MCP不一定只是sse方式连接。

有些会需要执行uv、python、npx命令的,所以需要stdio方式,还需要一个json文件配置,就像Cursor配置mcp一样。

{  "mcpServers": {    "filesystem": {      "command": "npx.cmd",      "args": [        "-y",        "@modelcontextprotocol/server-filesystem",        "C:/Users/kelvin/Desktop",        "C:/Users/kelvin/Desktop"      ]    }}

五、开始使用

该配置的已经配置好了,可以进行使用了

@SpringBootApplicationpublic class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class,args);    }    @Bean    public CommandLineRunner predefinedQuestions(            ChatClient.Builder chatClientBuilder,            ToolCallbackProvider tools,            ConfigurableApplicationContext context) {        return args -> {            // 构建ChatClient并注入MCP工具            ChatClient chatClient = chatClientBuilder                    .defaultToolCallbacks(tools)                    .build();            // 定义用户输入            String userInput = "有哪些工具可用";            // 打印问题            System.out.println("\n>>> QUESTION: " + userInput);            // 调用LLM并打印响应            System.out.println("\n>>> ASSISTANT: " +                    chatClient.prompt(userInput).call().content());            // 关闭应用上下文            context.close();        };    }}

问问有什么能力

可以先用这个userInput来访问有哪些工具,就像cursor一样,可以知道每个mcp server有哪些能力。他就回复我各个工具的能力。

### 地图相关工具1. **骑行路径规划**:规划骑行通勤方案。2. **驾车路径规划**:规划驾车通勤方案。3. **公交路径规划**:规划公共交通(火车、公交、地铁)通勤方案。4. **步行路径规划**:规划步行通勤方案。5. **距离测量**:测量两个经纬度坐标之间的距离(支持驾车、步行和直线距离)。6. **地理编码**:将结构化地址转换为经纬度坐标。7. **逆地理编码**:将经纬度坐标转换为行政区划地址信息。8. **IP 定位**:根据 IP 地址定位位置。9. **天气查询**:根据城市名称或 adcode 查询天气。10. **POI 搜索**    - **关键词搜索**:根据关键词搜索 POI。    - **周边搜索**:根据坐标和半径搜索 POI。    - **POI 详情查询**:查询 POI 的详细信息。11. **地图展示**    - **行程规划地图**:展示行程规划结果。    - **导航页面**:唤起导航页面。    - **打车页面**:唤起打车页面。### GitHub 相关工具1. **仓库管理**    - 创建仓库。    - 搜索仓库。    - 获取仓库文件内容。    - 创建或更新文件。    - 推送多个文件。    - 创建分支。    - 列出提交记录。2. **问题管理**    - 创建、更新、列出问题。    - 添加问题评论。3. **拉取请求管理**    - 创建、合并拉取请求。    - 获取拉取请求详情。    - 列出拉取请求文件。    - 获取拉取请求状态。4. **其他**    - 搜索代码、用户、问题。    - 创建 Fork。### 文件系统操作工具1. **文件读写**    - 读取单个或多个文件。    - 写入或编辑文件。2. **目录操作**    - 创建目录。    - 列出目录内容。    - 获取目录树。    - 移动或重命名文件。3. **搜索与信息**    - 搜索文件。    - 获取文件或目录的详细信息。    - 列出允许访问的目录。如果需要了解某个工具的具体功能或使用方法,可以告诉我,我会为您提供详细说明!

下一步就是让他做事

把userInput 改为

String userInput = "##我五一计划去昆明游玩4天的旅行攻略。" +        "#帮制作旅行攻略,考虑出行时间和路线,以及天气状况路线规划。" +        "#制作网页地图自定义绘制旅游路线和位置。" +        "##网页使用简约美观页面风格,景区图片以卡片展示。" +        "#行程规划结果在高德地图app展示,并集成到h5页面中。" +        "##同一天行程景区之间我想打车前往。" +        "生成html格式的内容。让我人工保存到文件里。";

案例就如高德提到的样例一样: lbs.amap.com/api/mcp-ser…

回答得到

把html内容保存到电脑某个文件,改后缀叫html。打开,则看到高德示例的结果。有些不足的就是,deepseek拿到的图片可能是一年前的旧的连接,所以图片就打不开的了。

至此,你也可以利用deepseek和mcp client做些应用的功能了。

你也可以跟别人说,你跟高德合作过项目了。

六、开发MCP server

以后再来介绍mcp server。因为我觉得如果做一个项目,做应用层的话,可以利用已有的东西,快速做些实际效果,调用已存在的东西会比较快。

其次,没有什么场景需要我自己提供mcp server/http server,除非我是一个公众业务软件。

总结

做好了MCP功能,我们能实现Cusor这部分的功能了,所以说Cusor也是套壳项目,cursor不提供算法,提供基于LLM上层应用。

自己做了这个,哪里还需要20$一个月啊。距离完成自己的套壳项目,又进一步了。

下一章,讲spring-ai-alibaba

以后还会讲解ant-design-x做前端。

如果想知道还有哪些好用的MCP请加关注,联系我。

公————地藏思维

Fish AI Reader

Fish AI Reader

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

FishAI

FishAI

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

联系邮箱 441953276@qq.com

相关标签

MCP协议 Spring AI LLM DeepSeek 智能应用
相关文章