Ohhnews

分类导航

$ cd ..
Spring Blog原文

Spring AI 2.1.0-M1 里程碑版本正式发布

#spring ai#人工智能#openai#向量数据库#版本发布

[LOADING...]

我代表 Spring AI 团队以及所有做出贡献的人,很高兴地宣布 Spring AI 2.1.0-M1 已经发布,现在可以从 Maven Central 获取!

发行说明 | 升级说明 | 参考文档

2.1.0-M1 是 2.1 线路的第一个里程碑版本。它基于 2.0.1 中发布的所有内容构建,将基线迁移到 Spring Boot 4.2(本里程碑版本基于 4.2.0-M2 构建),并引入了三项新能力:对结构化、有序的消息内容模型的初步支持,对 OpenAI Responses API 的支持,以及将预计算嵌入写入向量存储的方法。

与任何里程碑版本一样,新 API 已可供试用,但在 GA 之前仍可能发生变化。你们现在的反馈将塑造它们。

本次发布的新特性

消息部件

到目前为止,Spring AI 消息是一段文本加上额外的工具调用和媒体列表。这种形态无法表示当前模型实际返回的内容:推理与工具调用交错、图像之间的文本,或者必须在下一轮逐字发送回去的提供者特定块。

AssistantMessage、UserMessage 和 ToolResponseMessage 现在将其内容保存为 MessagePart 条目的有序列表:TextPart、ReasoningPart、ToolCallPart、ToolResultPart、MediaPart 和 UnknownPart。各部件保留提供者生成它们的顺序,因此对话可以忠实地往返传递。ReasoningPart 或 ToolCallPart 可以携带一个 OpaquePayload,其中保存诸如 Anthropic 思考签名或 Gemini 思想签名之类必须原样重放的数据。UnknownPart 保留适配器尚未建模的任何块的原始 JSON,因此不会有任何内容被静默丢弃。

熟悉的访问器(getText()、getMedia()、getToolCalls() 以及新增的 getReasoning())现在是部件之上的视图,现有的构造函数和构建器继续按旧有顺序生成它们。要自行控制顺序,可以直接添加部件:

$ java
UserMessage question = UserMessage.builder()
    .part(TextPart.of("What changed between these two charts?"))
    .part(MediaPart.of(firstChart))
    .part(MediaPart.of(secondChart))
    .build();

AssistantMessage answer = chatModel.call(new Prompt(question)).getResult().getOutput();
for (ReasoningPart reasoning : answer.getReasoning()) {
    System.out.println("Reasoning: " + reasoning.text());
}
System.out.println(answer.getText());

流式模型现在可以增量地传递部件:块携带带索引的部分部件和一个响应 id,MessageAggregator 从中重建完整的部件。只读取 getText() 的订阅者看到与之前相同的文本增量,工具调用仍然被缓冲并作为完整调用一次性传递。请参阅参考文档中的消息部件部分。

这是初步的消息部件支持:只有新的 OpenAiResponsesChatModel 能原生地生成和消费部件。其他 ChatModel 实现将在 2.1.0-RC1 中重构以使用它们。

OpenAI Responses API

新的 OpenAiResponsesChatModel 与 OpenAI 的 /v1/responses 端点通信,与现有的基于 Chat Completions 的 OpenAiChatModel 并存。使用它的主要原因是正确性:从 GPT-5.4 开始,Chat Completions 不支持将工具调用与除 none 以外的推理努力组合使用,而 Responses 支持。如果你正在基于当前的 OpenAI 旗舰模型构建代理,这就是要使用的端点。

切换只需一个属性,spring.ai.openai 的其余连接设置保持不变:

$ properties
# chat-completions (default) | responses
spring.ai.openai.chat.api=responses

该模型基于消息部件构建。Responses 回复中的每一项按顺序变成一个部件,加密的推理内容携带在 ReasoningPart 中,并在工具调用之间原样传回,因此模型在工具循环中保持其思路。OpenAiResponsesChatModel 有意设计为无状态:每次调用都发送整个 Prompt,因此 ChatMemory、顾问和 RAG 的工作方式与 OpenAiChatModel 完全相同。

OpenAiResponsesChatOptions 公开推理努力和推理摘要、详细程度、结构化输出以及图像和 PDF 输入。HostedTool 启用 OpenAI 在其侧运行的工具:网络搜索、文件搜索、代码解释器、远程 MCP 和图像生成。可观测性和自动配置已包含在内。OpenAI Responses 参考页面涵盖了配置属性以及何时选择哪个端点。

聊天记忆仓库尚不持久化消息部件,因此只有 InMemoryChatMemoryRepository 在对话轮次之间保留推理。对话与其他仓库仍然可以工作,但模型在每一轮都从头推理。持久化仓库支持计划在 2.1.0-RC1 中提供。

写入预计算嵌入

VectorStore.add() 总是使用存储自己的嵌入模型来计算嵌入。有时你已经有了向量:提供者的批处理 API 在夜间以折扣价计算了它们,另一个团队拥有嵌入管道,多模态模型嵌入了图像,或者你正在从一个将文本和向量一起导出的系统迁移。

新的 VectorStore.upsert() 接受一个 EmbeddedDocument,将 Document 与其 float[] 向量配对,并按给定方式存储向量:

$ java
float[] embedding = ...; // computed elsewhere
Document document = new Document("8f14e45f-ceea-467a-9a3e-5b1c2d6f7a90", "some text",
        Map.of("source", "manual"));

vectorStore.upsert(List.of(new EmbeddedDocument(document, embedding)));

顾名思义,再次写入相同的 id 会替换该行,因此具有稳定 id 的摄取作业可以在失败后安全地重新运行。在写入任何内容之前,每个批次都会根据索引宽度进行检查。pgvector、Redis、Elasticsearch 和 Qdrant 在此里程碑版本中支持 upsert;其他存储会抛出异常,直到它们选择加入。新的 DocumentMetadata.CONTENT_REF 键允许你指向存储在存储之外的内容,用于那些向量来自图像或文件太大而无法内联的行。请参阅写入用户提供的嵌入。

较小的新增内容

修复

  • spring.ai.openai.timeout 和 spring.ai.openai.chat.timeout 再次生效。自 2.0.1 以来,每个请求都带有一个 60 秒的每次调用超时,覆盖了配置的值,这会导致超过一分钟的流式轮次以 OpenAIIoException: Stream failed 中止。
  • OpenAI 严格模式工具模式在每个对象级别回填了 additionalProperties: false。这修复了并非来自 Spring AI 自己的生成器的模式的严格模式,例如 MCP 工具模式或手写输入模式。
  • 携带媒体但没有文本的 Bedrock 用户消息不再发送空文本块,Converse API 曾因此以 400 错误拒绝。
  • TextReader 关闭它读取的资源流,而不是为每个文档泄漏一个文件描述符。
  • InMemoryChatMemoryRepository 在保存时复制消息列表,因此之后对调用者列表的更改不再改变已存储的对话。
  • MariaDBVectorStore 模式验证在未配置模式名称时也能工作,而不是将现有表报告为在模式 null 中缺失。
  • 空的 OpenAI 图像响应被报告为生成失败,而不是无关的异常。

文档、依赖项和构建

MCP 客户端文档新增了关于客户端作用域和会话边界的一节(自动配置的 bean 共享什么,以及如何在需要时获得每用户隔离),并且关于 MCP 与本地工具名称冲突的指南得到了完善。OpenAI 的推理努力属性现已记录在文档中。

Spring AI 现在跟踪 Spring Boot 4.2,Anthropic Java SDK 升级到 2.64.0。构建现在配置为可重复构建,并且修复了假定 Unix 行尾的测试,因此项目可以在 Windows 上构建。

贡献者

感谢所有参与此版本工作的人:

@CryoThrust, @JamesBLewis, @Lubaoshuai, @chabinhwang, @chensishang, @dimitarproynov, @dlwldn30, @fatan, @herder, @ilayaperumalg, @jhpark1227, @kezhenxu94, @martin-grofcik, @pengmoubuaixuexi, @sdeleuze, @sobychacko, 和 @tzolov

来自 Spring AI 社区

  • Spring AI TypeSafe Jev 0.2.0 延续了本周引入的 TypeSafe Jev 快速结构化决策。作为评判者的模型获得了代码标准、类型化输入、条件标准和自优化修复,以及实验性的 JevChatModel。请参阅参考文档。
  • MCP Security 0.1.14 通过 Origin 头验证、缺失 API 密钥时返回 401 响应以及 CIMD 流程中的颁发者 URL 验证来加固 MCP 服务器。
  • Spring AI Agent Utils 发布了两个版本。0.11.0 增加了 Auto-Dream 记忆整合与跨会话回忆。0.12.0 增加了可插拔的 ExecBackend,带有用于沙箱命令执行的 Docker 后端、Workspace 抽象、搜索工具的目录限制,以及用于控制代理循环的 InterruptAdvisor 和 ToolCallListener。
  • Spring AI Session 0.7.0 和 0.8.0 使 appendEvent 幂等,通过 CrossSessionRecallTools 增加了跨会话的关键词和模式搜索,并阻止当记忆顾问在工具调用循环内运行时出现重复的提示历史。
  • Spring AI AgentCore 2.2.0 增加了 Spring AI Session API 对 AgentCore 记忆的支持和 AgentCore 身份。

下一步

2.1.0-RC1 的工作已经开始。消息部件是其中大部分工作的基础:

  • Spring AI Agents。 我们计划在 2026 年 11 月将新的代理支持作为 Spring Projects Experimental 下的一个独立项目发布,并计划在明年年中将其合并到 Spring AI 3.0 中。
  • 跨所有提供者的消息部件。 我们将重构现有的 ChatModel 实现,以原生方式生成和消费 MessagePart 内容,同时为使用当前访问器的代码保持向后兼容性。
  • 核心中的会话管理。 我们正在将 Spring AI Session 的关键部分引入 Spring AI 本身。除了高级对话历史管理、压缩和回忆之外,其 SessionRepository 实现将持久化完整的 MessagePart 结构。届时,推理不仅会在内存仓库中,还会在持久化存储中跨对话轮次保留下来。
  • MCP 2026-07-28。 对 MCP 2026-07-28 规范的支持工作正在进行中,包括在 MCP Java SDK中以及基于它构建的 Spring AI MCP 抽象和注解中。

开始使用

在现有应用程序中尝试该里程碑版本,或在 start.spring.io 上开始一个新项目。消息部件模型和 Responses API 正是我们希望在 GA 之前获得反馈的那类更改 --- 如果有任何问题,请提交 issue,或者发起讨论告诉我们你希望接下来看到什么。

谢谢!

资源

项目页面 | GitHub | 问题 | 参考文档