之前做个几个大模型的应用,都是使用Python语言,后来有一个项目使用了Java,并使用了Spring AI框架。随着Spring AI不断地完善,最近它发布了1.0正式版,意味着它已经能很好的作为企业级生产环境的使用。对于Java开发者来说真是一个福音,其功能已经能满足基于大模型开发企业级应用。借着这次机会,给大家分享一下Spring AI框架。
注意:由于框架不同版本改造会有些使用的不同,因此本次系列中使用基本框架是 Spring AI-1.0.0,JDK版本使用的是19,Spring-AI-Alibaba-1.0.0.3-SNAPSHOT。
代码参考: https://github.com/forever1986/springai-study
目录
- 1 基于Nacos的MCP
- 2 MCP 服务注册到 Nacos
- 2.1 前提准备
- 2.2 代码
- 2.3 演示
- 3 Client 结合 Nacos 实现 MCP 集群发现
- 3.1 代码实现
- 3.2 演示
前几章基本上对Spring AI Alibaba的基本使用,包括模型、提示词、聊天记忆等讲了一遍,可以看到基本上使用方式与Spring AI差异不大,这一章讲一下Spring AI Alibaba-基于Nacos的MCP,这是一个基于企业级生产环境实践总结出来的应用框架。
1 基于Nacos的MCP
Spring AI Alibaba MCP 结合 Nacos 服务注册中心,为企业级智能体应用提供了强大的基础架构支持。这一组合解决方案主要围绕三条核心技术线展开,实现了从服务注册、工具代理到服务发现的完整闭环,为企业级 AI 应用部署提供了坚实基础。
Nacos3中提供了新的MCP列表功能,其中有三类MCP服务可以注册到Nacos:
- 第一类:已有的API服务,通过声明自动转化为 MCP 服务,配合 Higress 的协议转换能力,实现 0 代码改造成 MCP 服务协议
- 第二类:已经构建好的或其他供应商提供的 MCP 服务,可以导入到 Nacos 中,进行其描述、工具列表、工具 Schema 等内容的动态修改和维护
- 第三类:新构建的 MCP 服务注册, 配合 Spring AI Alibaba应用框架或者Nacos-MCP 的 sdk,能够做到像微服务一样自动注册到 Nacos 中进行统一的管理和维护
前两类都是Nacos3本身支持的功能,这里主要是讲Spring AI Alibaba。因此本次演示的是第三类,使用Spring AI Alibaba框架注册服务到Nacos,并通过Spring AI Alibaba框架获得及发现MCP服务。
2 MCP 服务注册到 Nacos
参考lesson25子模块中ali-mcp-server子模块
示例说明:本实例创建一个MCP的server,里面有一个查询天气的工具,然后将MCP服务(基于sse模式)注册到Nacos上面,本次使用Nacos3.0.2版本
2.1 前提准备
1)安装并启动nacos3.0.2
2)申请高德开放平台的API KEY
2.2 代码
1)新建lesson25子模块
2)在lesson25子模块下,新建ali-mcp-server子模块,其pom引入如下:
<dependencies><!-- MCP Nacos 注册 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-nacos-mcp-server</artifactId></dependency><!-- MCP Server (webflux) --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webflux</artifactId></dependency>
</dependencies>
3)新建application.properties配置文件
server.port=9005
spring.application.name=mcp-nacos-registry-examplespring.ai.dashscope.api-key=你的阿里百炼API KEY
spring.ai.dashscope.chat.options.model=qwen-plus## NacosMcpProperties nacos的配置
spring.ai.alibaba.mcp.nacos.namespace=public
spring.ai.alibaba.mcp.nacos.server-addr=localhost:8848
spring.ai.alibaba.mcp.nacos.username=nacos
spring.ai.alibaba.mcp.nacos.password=nacos## McpServerProperties MCP的配置
spring.ai.mcp.server.name=webflux-mcp-server
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.type=ASYNC## NacosMcpRegistryProperties MCP注册到nacos的配置
spring.ai.alibaba.mcp.nacos.registry.enabled=true
spring.ai.alibaba.mcp.nacos.registry.service-group=mcp-server
spring.ai.alibaba.mcp.nacos.registry.service-name=webflux-mcp-server
4)配置RestTemplateConfig类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class RestTemplateConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}
5)新增天气查询服务WeatherService:
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;@Service
public class WeatherService {@Autowiredprivate RestTemplate restTemplate;private static final String adcode = "adcode";@Tool(description = "获取中国城市的天气情况")public String getWeatherForecastByCity(@ToolParam(description = "城市名称") String city) {// 获取城市的adcodeString result = restTemplate.getForObject("https://restapi.amap.com/v3/geocode/geo?address="+city+"&key=ef3cbaef8f0965c6205f56e0ff00ceb4", String.class);// 这里为了方便简单处理一下字符串获取adcode,正式的话需要解析json格式int startIndex = result.indexOf(adcode);String code = result.substring(startIndex+adcode.length()+3,result.indexOf(",",startIndex)-1);// 通过城市的adcode,进行获取天气预报result = restTemplate.getForObject("https://restapi.amap.com/v3/weather/weatherInfo?extensions=all&key=ef3cbaef8f0965c6205f56e0ff00ceb4&city="+code, String.class);return result;}}
6)新建启动类Lesson25ServerApplication,注册工具:
import com.demo.lesson25.server.service.WeatherService;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class Lesson25ServerApplication {public static void main(String[] args) {SpringApplication.run(Lesson25ServerApplication.class, args);}@Beanpublic ToolCallbackProvider weatherTools(WeatherService weatherService) {return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();}}
2.3 演示
1)启动项目后,在nacos控制台的MCP服务列表可以看到注册的MCP服务
2)点击详情,可以看看详情
3)查看服务列表,可以看到服务已经注册到nacos
4)点击详情可以看到服务地址
3 Client 结合 Nacos 实现 MCP 集群发现
参考lesson25子模块中ali-mcp-client子模块
示例说明,本实例创建一个MCP的client,通过Nacos方式,将上面注册的工具通过sse模式拉取到本地,并访问测试
3.1 代码实现
1)在lesson25子模块下,新建ali-mcp-client子模块,其pom引入如下:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId></dependency><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-nacos-mcp-client</artifactId></dependency><!-- 引入的是mcp-client --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-client-webflux</artifactId></dependency>
</dependencies>
2)创建application.properties配置文件
server.port=9006
spring.application.name=mcp-nacos-client-examplespring.ai.dashscope.api-key=你的阿里百炼API KEY
spring.ai.dashscope.chat.options.model=qwen-plus## NacosMcpProperties nacos的配置
spring.ai.alibaba.mcp.nacos.namespace=public
spring.ai.alibaba.mcp.nacos.server-addr=localhost:8848
spring.ai.alibaba.mcp.nacos.username=nacos
spring.ai.alibaba.mcp.nacos.password=nacos## NacosMcpSseClientProperties MCP客户端配置通过nacos获取的MCP server
spring.ai.alibaba.mcp.nacos.client.enabled=true
spring.ai.alibaba.mcp.nacos.client.sse.connections.server1.service-name=webflux-mcp-server
spring.ai.alibaba.mcp.nacos.client.sse.connections.server1.version=1.0.0## McpClientCommonProperties MCP客户端配置的配置
spring.ai.mcp.client.enabled=true
spring.ai.mcp.client.name=mcp-client-webflux
spring.ai.mcp.client.version=1.0.0
spring.ai.mcp.client.type=ASYNC
3)配置ClientController 演示类:
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ClientController {private final ChatClient chatClient;public ClientController(ChatClient.Builder chatClientBuilder, @Qualifier("loadbalancedMcpAsyncToolCallbacks") ToolCallbackProvider tools) {this.chatClient = chatClientBuilder.defaultToolCallbacks(tools.getToolCallbacks()).build();}@GetMapping("/ai/generate")public String generate(@RequestParam(value = "message", defaultValue = "请问北京市目前天气预报?") String message) {return this.chatClient.prompt().user(message).call().content();}
}
说明:工具的获取,Spring AI Alibaba分为同步和异步
1)同步方式:
- 通过@Qualifier(“loadbalancedSyncMcpToolCallbacks”) ToolCallbackProvider tools参数注册;
- 通过@Autowired private List loadbalancedMcpSyncClients;变量注册
2)异步方式:
- 通过@Qualifier(“loadbalancedMcpAsyncToolCallbacks”) ToolCallbackProvider tools参数注册;
- 通过@Autowired private List loadbalancedMcpAsyncClients;变量注册
4)启动类Lesson25ClientApplication :
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Lesson25ClientApplication {public static void main(String[] args) {SpringApplication.run(Lesson25ClientApplication.class, args);}}
3.2 演示
http://localhost:9006/ai/generate
结语:本章通过一个基于Nacos的MCP服务端和MCP客户端,演示了Spring AI Alibaba-基于Nacos的MCP实现方法,当然Spring AI Alibaba-基于Nacos的MCP是一种企业级的应用模式,详情可以参考官方文档,它并不止提供本章内容,比如远程其它MCP服务也可以通过Nacos注册等等。这里就不多累述。
Spring AI系列上一章:《Spring AI 系列之三十 - Spring AI Alibaba-其它模型》
Spring AI系列下一章:《Spring AI 系列之三十二 - Spring AI Alibaba-Graph框架之入门》