Spring AI 2.0 做得最重要的一件事,是停止自己造轮子。
过去 Spring 为了对接 OpenAI 和 Anthropic,自己维护了一套基于 HTTP 协议的内部 SDK。问题是模型厂商接口迭代飞快,Spring 这套自维护实现总是慢半拍,还时不时冒出协议兼容的坑。2.0 把这套全扔了,主流模型的底层直接换成各家官方的 Java SDK:
OpenAI 切到官方
openai-java,Chat、Embedding、Image、Audio 全线重构。顺手修掉了错误附带extra_body参数的老问题,还补上了reasoning_content(推理过程)在多轮对话里的回放;
Anthropic 切到官方
com.anthropic:anthropic-java,丢掉了原来 RestClient/WebClient 手工拼装那套。最实际的好处是,Anthropic 独有的限流响应头现在能直接从ChatResponseMetadata拿到
一句话:2.0 不再跟厂商接口赛跑,把这件事交回给官方,自己专心做上层抽象。这是整个版本的基调——能用官方的就用官方的,能砍的就砍。
先升 Spring Boot 4.0
Spring AI 2.0 的底座绑死 Spring Boot 4.0 和 Spring Framework 7.0,Jakarta EE 11 全面落地,跟 Boot 3.x 的向后兼容彻底断了。还跑在 3.x 上的项目,升 Spring AI 2.0 之前得先做一次底座迁移,然后才轮到 AI。
Java 版本。最低还是 Java 17,但 AI 场景推荐 Java 25。AI 应用干的就是密集 I/O 阻塞——调大模型 API、处理流式响应,Java 25 的虚拟线程在这种场景下吞吐量提升明显,并发长连接流式响应尤其受益。
序列化引擎。跟着 Boot 4.0 切到 Jackson 3,硬分叉。
别小看这层。Spring AI 的结构化输出、JSON Schema 推导、向量库元数据解析全靠底层 ObjectMapper,Jackson 3 校验更严,原来 1.x 能容忍的模糊绑定现在直接报错。
空安全。引入 JSpecify,核心 API 覆盖 @NonNull 和 @Nullable。配合 IDEA 静态分析,很多运行时才暴露的空指针,编译期就能抓出来。Kotlin 2.2 用户还能多占点便宜,编译器原生认这些注解。
工具调用从黑盒变透明
用过 1.x Tool Calling 的人都知道:LLM 和工具之间调了几次、传了什么,从外面看不见。执行逻辑硬编码在各个 ChatModel 里,日志切面插不进去,监控收不到数据。
2.0 把这套逻辑全部上浮到新的 ToolCallingAdvisor,底层模型不再碰工具调用。
同期加了两个 Advisor:
StructuredOutputValidationAdvisor 治返回格式不稳。JSON 带 Markdown 代码块、字段缺失、结构错位,它不让解析器崩,而是把失败原因和期望格式发回 LLM 重试,默认 3 次。
ToolSearchToolCallingAdvisor 管动态工具发现。几百个工具签名全塞进 System Prompt 太费 Token,它能在 LLM 表露意图时实时检索最相关的定义动态注入,不用启动时全加载。
对话记忆重做
这次有个强制安全变更,背后是 CVE-2026-40966(CVSS 5.9,中危)。
问题在 1.x 的 ChatMemoryAdvisor:初始化没传会话标识符,就自动降级用常量 ChatMemory.DEFAULT_CONVERSATION_ID,值是 "default"。多租户下,所有并发用户的对话历史塞进同一个桶,攻击者顺着就能读到别人的数据。
2.0 把这个默认行为彻底干掉:
DEFAULT_CONVERSATION_ID常量删除,引用它的旧代码编译报错静态
.conversationId(String)方法移除运行时缺
ChatMemory.CONVERSATION_ID,直接抛IllegalArgumentException
PromptChatMemoryAdvisor 同时废弃,官方只推 MessageChatMemoryAdvisor。区别:前者把历史拼到 System Prompt 末尾,后者直接以 Message 对象数组插进 API 请求,更贴现代大模型的上下文格式。
再见智谱、MiniMax
承接开头那句"能砍的就砍",2.0 从核心库里移走了这些模型:
MCP 从实验区毕业
MCP 在 1.x 时代只能待在社区实验分支,包路径 org.springaicommunity.mcp。2.0 合进核心库:
包路径升到
org.springframework.ai.mcp.annotation传输层从外部 SDK 挪进 Spring AI 命名空间
同步/ 异步客户端配置合并进泛型
McpClientCustomizer
向量存储变动
在用 RAG 的项目留意几处:
VectorStore.delete() 返回值从 Optional<Boolean> 改成 void,删成功就成功,失败直接抛运行时异常。
所有 VectorStore 实现类的公共构造函数移除,强制 Builder 模式。包结构也重组了,类归进各自专属路径(如 org.springframework.ai.pgvector.vectorstore),旧路径依赖得更新。
还有 initialize-schema,2.0 默认改成 false。以前启动自动建表,现在默认不建,要显式开。升级后数据库没自动初始化,先查这儿。
升级怎么做
官方给了迁移工具 MigrateToSpringAI200M3,基于 OpenRewrite。Maven 跑一条命令,自动处理废弃 API 替换、Builder 转换、枚举更新、MCP 包路径重定向。
本文转载自:https://mp.weixin.qq.com/s/mXTNZJkQ7SjIid61Lb8lfQ