之前做個幾個大模型的應用,都是使用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框架之入門》