【Spring AI】Spring AI 1.0.0-M7、M8更新至1.0.0版本兼容的所需修改要点
引言
Spring AI更新的速度非常快,在一个月之前我还在用着最新的M7版本,中间经过M8、1.0.0RC1,现在马上就到了1.0.0正式版。正式版当然也新增了许多东西。
核心功能包括支持20个AI模型的ChatClient
接口、适配20个向量数据库的检索模块、支持滑动窗口和向量搜索的对话记忆功能、基于@Tool
注解的工具调用机制,以及模型评估、可观测性和Model Context Protocol(MCP)支持。此外,新增RAG流水线、ETL框架、工作流驱动和自主代理功能。
更新的契机还是在引入百度的MCP Server的时候,百度的sse包含一个路径参数,而Spring AI默认在url后面拼接一个/sse,导致服务怎么都启动不起来,看源码才发现它是直接将终端节点endpoint硬编码了,也没有提供API去修改endpoint,我就意识到要更新版本了,而1.0.0版本是支持这个特性的最新版,更新之后当然有许多东西不兼容了,代码直接报错了。
别的不多说了,因为大多数人都在用M7和M8版本的Spring AI,本篇文章我就介绍一下M7、M8版本向1.0.0版本做兼容时主要需要修改的点
模型记忆存储
在旧版本中,模型记忆的存储的方式很有限,基本都是用的InMemoryChatMemory,这样写的:
ChatMemory chatMemory = new InMemoryChatMemory();ChatMemory chatMemoey = ChatClient.builder(chatClient).defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory)).build
而在1.0.0版本中,相应的写法应该这么写:
ChatMemory chatMemory = MessageWindowChatMemory.builder().maxMessages(50).build();ChatClient chatClient = ChatClient.builder(chatModel).defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()).build();
我看了一下官方文档,改动的意思主要就是:原来的ChatMemory支持InMemoryChatMemory,由内存自动管理;现在的是ChatMemory的实现变味了MessageWindowChatMemory,需要由构造器构造,它的下面新增了一批内存管理类,比如总工程类ChatMemoryRepository,其中可以传参InMemoryChatMemoryRepository、JdbcChatMemoryRepository、Neo4jChatMemoryRepository、CassandraChatMemoryRepository。其中InMemoryChatMemoryRepository就相当于原来的InMemoryChatmemory,同样也是默认的实现。
例如现在你可以这么写:
ChatMemory chatMemory = MessageWindowChatMemory.builder().chatMemoryRepository(new InMemoryChatMemoryRepository()).maxMessages(50).build();
还有一个改动点是:原来的内存管理没有上限,想存多少存多少,现在则是可以在构造内存管理的时候定义最大消息数.maxMessage(),类似于滑动窗口,超出限制就把最早的消息从记忆中删除。
不写的话默认就是存储20条。
会话存储
在旧版本中,我们是通过引入advisors配置会话id以在内存中分别管理不同会话的消息,其是以键值对的形式存储,其中key是通过一个静态变量配置
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;chatClient.prompt().system().advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, request.getChatId())).content();
而现在的key变化了,直接通过Chatmemory中的属性作为键
chatClient.prompt().system().advisors(a -> a.param(ChatMemory.CONVERSATION_ID, request.getChatId())).content();
工具调用
以往在配置工具时,通过.tools()配置工具回调
chatClient.prompt().system().tools(new AsyncMcpToolCallbackProvider(mcpASyncClients)).content();
现在则变成了.toolCallbacks()
chatClient.prompt().system().toolCallbacks(new AsyncMcpToolCallbackProvider(mcpASyncClients)).content();
MCP配置
在1.0.0版本之前,在配置MCP客户端时,要连接一个MCP服务端,双方都会默认的在url的最后加一个/sse,并且不能轻易更改,还是硬拼接。
比如客户端这么写:http://localhost:8080/api
服务端的url就应该这么写:http://localhost:8080/api
而在请求时则其实是这都是这样:http://localhost:8080/api/sse
这种情况还好,但是现在MCP Server越来越多,服务提供商可能就需要用户在连接时提供凭证,比如密钥什么的,url可能就需要请求参数,这时候直接把/sse拼接到最后就直接导致地址解析失败
以前的写法:
spring.ai.mcp.client.sse.connections.server1.url=http://localhost:8080# 相当于 http://localhost:8080/sse
现在可以额外配置:
spring.ai.mcp.client.sse.connections.server1.url=http://localhost:8080
spring.ai.mcp.client.sse.connections.server1.sse-endpoint=/sse# 相当于 http://localhost:8080/sse#spring.ai.mcp.client.sse.connections.server2.url=https://mcp.map.baidu.com
#spring.ai.mcp.client.sse.connections.server2.sse-endpoint=/sse?ak=123456789# 相当于 https://mcp.map.baidu.com/sse?ak=123456789
当然不写的话默认还是自动添加/sse
目前最常用的兼容性改动差不多是这些,后续再遇到我会在进行整理。
更详细的技术点请查看官方文档:引言 :: Spring AI Reference(中文版)