Spring AI 2.0.1 正式发布,修复多项安全漏洞并引入新功能
我代表 Spring AI 团队以及所有贡献者,高兴地宣布 Spring AI 2.0.1 已发布,现已在 Maven Central 上提供!
2.0.1 是继 2.0.0 GA 版本 之后的第一个维护版本。这是一个大版本:包含超过 80 个 issue 和 pull request,其中大多数来自最近几周将应用程序迁移到 2.0 的团队的反馈。除了修复之外,它还增加了一些自 GA 以来被频繁请求的功能。
本版本修复的 CVE
- CVE-2026-47851 - Spring AI PDF 文档阅读器中对攻击者控制的 PDF 大纲树进行无界递归
- CVE-2026-47852 - 可预测的缓存目录位置允许在 Spring AI 中进行本地 ONNX 模型替换
- CVE-2026-59279 - 通过重复的 initialize 请求进行无界持久会话分配
- CVE-2026-59294 - ResourceCacheService 中通过路径遍历实现任意文件写入
- CVE-2026-59308 - 通过 SHA-256 截断绕过语义缓存的跨租户隔离
- CVE-2026-59319 - RedisChatMemoryRepository 中的 RediSearch 标签注入导致跨对话数据泄露
- CVE-2026-59318 - DefaultToolCallingManager 全局解析器回退允许通过提示注入进行未声明工具的分发
升级前需要注意的事项
大多数应用程序只需升级版本即可从 2.0.0 迁移到 2.0.1,但有少数更改需要留意。升级说明 详细介绍了这些更改,并且升级说明本身也针对此版本进行了扩充:
-
弃用的 Mistral AI 聊天模型已被移除(#6772)。如果您仍通过常量引用它们,请改用当前受支持的模型名称。
-
Redis 聊天记忆自动配置模块已重命名(#6416),以与其余
spring-ai-autoconfigure-*命名保持一致。请更新构建文件中的 artifact id。 -
OpenAI 工具调用的严格模式现在默认为
false(#6755)。生成的工具模式通过从required中省略来标记可选参数,而严格模式会拒绝这种形式——因此任何包含可选参数的工具都会以 400 错误失败。严格模式现在改为选择启用,与 OpenAI API 默认值保持一致;如果您的模式符合其规则,请显式启用它。 -
Media构建器使用类型化的data重载(#6481),这使可接受的负载类型变为显式,而不是接受Object。 -
DeepSeekApi已修订(#6428),使其与其他 API 客户端的约定保持一致。 -
Couchbase 向量存储现在使用 Spring Boot 管理的 Couchbase 客户端(#6583),而不是自行创建,因此它会参与您的应用程序已经声明的集群配置。
本版本的新增功能
工具调用限制
永不终止的智能体循环是一种代价高昂的失败模式。ToolCallingAdvisor 现在接受对每个请求的工具调用次数的可配置限制,并在达到限制时抛出 ToolCallLimitExceededException。该异常路径会返回单个 Generation,因此错误处理保持与正常响应相同的形态。与此相关,工具解析回退现在也是可配置的:您决定不可解析的工具名称是快速失败还是回退。
OpenAI 音频
OpenAiAudioSpeechModel 支持音频流式传输,并公开了 instructions 选项来控制语音和表达方式。在转录方面,选项和响应得到了丰富,覆盖了更多 OpenAI API 表面。
Google GenAI
Google GenAI 现在支持 ToolChoice,让您可以强制、禁用或让模型自行选择工具;并且通过标准的 ImageModel 抽象支持图像生成。
文档读取
PagePdfDocumentReader 接受页面范围,这样您就可以只读取大文档的一部分,而不是全部。TokenTextSplitter 现在会验证其构建器参数,而不是稍后才以令人困惑的错误失败。
AWS 区域解析
两个长期存在的报告终于关闭:Spring AI 现在遵循 AWS SDK 的默认区域解析规则,并且不再在解析区域时记录令人困惑的 WARN。如果您依赖环境或基于配置文件的区域配置来使用 Bedrock,现在它的行为将与您 AWS 技术栈中的其他部分一致。
可靠性
流式传输和工具调用
流式响应是本版本关注的重点。OpenAiChatModel 现在按索引合并流式工具调用增量,并处理空的 tool_calls 数据块;同时,关于 OpenAI 流式模式下 token 用量为零的报告也已解决。取消流式传输不再泄漏底层 HTTP 响应,无论是聊天还是音频转录。ToolCallingAdvisor 的流式循环不再丢弃 doBeforeStream 的修改,token 用量会跨工具调用迭代累计而不是只报告最后一次,并且工具调用观测在阻塞模式下会获得正确的父 span。
另外修复了:聊天选项构建器 clone() 中的共享可变状态及其 Anthropic 对应项、ToolContext 参数检测、严格模式负载位置、OpenAiChatModel 中的 PDF 媒体映射、OpenAiChatModel#buildGeneration 中对 Optional 的解包、通过 OpenAI API 调用 DeepSeek 时的 reasoningContent 元数据、模型构造之外被忽略的 AnthropicChatOptions.timeout(Duration)、OllamaChatModel 提示选项未继承已配置模型、Google GenAI 思考级别验证、Mistral AI 审核结果中的 null 字段、代理主机的 Microsoft Foundry URL 路径处理,以及 TLS 检查代理背后的 Azure OpenAI 认证。
2.0.0 中引入的工具搜索顾问现在已包含在 BOM 中(之前遗漏了,导致依赖它很不方便),并修复了自动配置顺序和并行工具调用的引用提取。
聊天记忆
Redis ChatMemoryRepository 在三个方面得到了强化:时间戳以原子方式保留,因此并发写入方不会冲突;clear() 确实可以清除;并且查询中的元数据值会被转义,这样包含特殊字符的值不再破坏查询。文档现在也解释了会话 ID 的范围。
向量存储
Milvus 获得了三项修复:过滤器表达式转换器中的分组优先级、整数元数据值被反序列化为 Long 而不是 Double,以及针对自定义元数据字段的过滤器。在其他方面,OpenSearchVectorStore 正确反序列化文档,PgVectorStore 在初始化后验证其表结构,而不是在第一次查询时失败,CouchbaseSearchVectorStore.Builder 不再断言错误的条件。
MCP
MCP 注解在 GraalVM 原生镜像下重新可用。@McpTool 异常处理与 @Tool 契约保持一致,没有参数的 stdio 连接可以工作,HTTP 客户端请求定制器 bean 会被应用,并且 Streamable HTTP WebClient 传输接受没有 event 字段的 SSE 帧,正如规范所允许的那样。服务器现在可以通过 maxSessions 和 sessionIdleTimeout 限制其会话状态。
健壮性
多项修复使 Spring AI 在处理不可信或意外输入时表现更佳:解析后的资源路径会得到验证,缓存使用临时目录,用完整长度哈希替代截断哈希,畸形 PDF 会得到处理而不是传播原始解析器失败,MarkdownCodeBlockCleaner 验证文本长度,并且不再丢弃单行围栏代码块。线上和协议值的字符串大小写转换现在使用 Locale.ROOT,这修复了经典的土耳其语区域设置 i 问题,并且 TransformersEmbeddingModel 关闭其原生资源。
文档、依赖项和构建
文档方面,结构化输出和工具调用参考文档被重构,CosmosDBChatMemoryRepository 章节已恢复,并且 Pinecone 免费层命名空间说明已更新到最新。
依赖方面,Milvus 升级到 2.6.21,Pinecone 升级到 6.2.0,Qdrant 升级到 1.18.0。构建现在将 Maven 插件版本和 gRPC 版本管理委托给 Spring Boot BOM,并移除了显式的 protobuf-java 版本属性——Spring AI 与 Spring Boot 为您管理的版本不一致的地方更少了。此外,spring-ai-azure-store 中移除了 fastjson2 依赖。## 贡献者
感谢所有为本次发布付出努力的各位:
@DragonFSKY, @EvanYao826, @JamesBLewis, @MKP999, @OneZero-Y, @OreOreDa, @Seol-JY, @TimurRakhmatullin86, @YashRL, @ZhangDT-sky, @angus-guo, @chaechaepower, @chemicL, @dimitarproynov, @ericbottard, @gaoxiaolei-s59, @gh7035, @guanxuc, @hutiefang76, @ilayaperumalg, @iuliiasobolevska, @jewoodev, @kamalcis, @kezhenxu94, @leeworms, @liushenling2001, @nicolaskrier, @prachipanditrao, @pyg410, @quaff, @rea9r, @sdeleuze, @sdudzin, @seeun0210, @sobychacko, @strogiyotec, @subhashpolisetti, @thjanssen, @tzolov, @ultramancode, 和 @yyyCode
快速开始
升级您的应用程序,或在 start.spring.io 上开始一个新项目。一如既往,我们期待您的反馈——如果遇到问题,请提交 issue,或者发起讨论,告诉我们您接下来希望看到什么。
谢谢!