Spring AI 2.1.0-M1: Message Parts, OpenAI Responses API and Pre-Computed Embeddings
Spring AI 2.1.0-M1, the first milestone of the 2.1 line, is built against Spring Boot 4.2.0-M2. Its biggest change is structural: a Message now holds an ordered list of MessagePart entries (TextPart, ReasoningPart, ToolCallPart, ToolResultPart, MediaPart, UnknownPart) that keep the provider's original ordering. Reasoning traces can now interleave with tool calls, and media can sit between text segments, which the old flat text-plus-media model could not represent. getText() and getMedia() remain as views over the parts, so existing code keeps compiling.
The second addition is OpenAiResponsesChatModel, which targets OpenAI's /v1/responses endpoint. The release notes explain why it matters for agents: Chat Completions cannot combine tool calling with any reasoning effort other than none, while the Responses API can. Switching is a single property: spring.ai.openai.chat.api=responses. For now it is the only model that produces message parts natively. The other providers will be refactored before RC1, and persistent chat-memory repositories don't yet store parts, so reasoning only carries across turns with in-memory memory.
The third feature is VectorStore.upsert(), which takes EmbeddedDocument objects (a document paired with a pre-computed float[]). You can ingest embeddings produced by an external batch pipeline, and stable IDs make re-runs idempotent. It is supported on pgvector, Redis, Elasticsearch and Qdrant at launch. The release also fixes ignored OpenAI timeout properties and strict-mode tool schemas with additionalProperties: false, and bumps the Anthropic Java SDK to 2.64.0.
Read more — Spring Blog
Modular RAG in Spring AI, With Jev as the Post-Retrieval Filter and Reranker
A new Spring blog walkthrough builds a full modular RAG pipeline on RetrievalAugmentationAdvisor and targets three weaknesses of naive RAG: noisy user queries, similarity search that returns topical but unhelpful chunks, and retrieved text that can't be trusted. Before retrieval, RewriteQueryTransformer turns conversational input into a search query and MultiQueryExpander fans it out into variants. VectorStoreDocumentRetriever and ConcatenationDocumentJoiner then fetch and deduplicate results, and ContextualQueryAugmenter builds the final prompt.
The new part is the post-retrieval stage, which uses TypeSafe's Jev decision model through two DocumentPostProcessor implementations. JevDocumentFilter makes four small judgments per passage: is there a prompt-injection attempt, does it contradict other passages, is it relevant, and does it contain evidence that answers the question. Thresholds are configurable, and contradicting passages are deliberately kept. JevDocumentReranker then scores each surviving passage on one narrower question, "could this passage answer the query?", rather than plain topical similarity.
In the demo (a question about Hurricane Milton's landfall, answered over Wikipedia PDFs), six retrieved chunks, most of them reference-list noise, were reduced to two passages scoring 0.97 and 0.88, and the model answered correctly. The setup needs spring-ai-rag, spring-ai-starter-typesafe and typesafe-spring-ai. The pattern also carries over to other models: per-passage injection screening is something you can drop into any Spring AI RAG chain.
Read more — Spring Blog
Spring Batch 6.1.0-M2: MongoDB Prefixes, Async Processing Moves to Core, Compile-Time-Checked Builders
Spring Batch 6.1.0-M2 moves to Spring Framework 7.1.0-M2, Spring Data 2026.1.0-M2 and Micrometer 1.18.0-M2, and brings several features that remove day-to-day annoyances:
- MongoDB job repository collection prefix: the equivalent of the JDBC table prefix (default
BATCH_), so several applications can share one MongoDB database. - Async components in core:
AsyncItemProcessor,AsyncItemWriterandChunkTaskExecutorItemWritermoved fromspring-batch-integrationtospring-batch-core, so you no longer need the integration module just for async processing. RepositoryItemWriterflushing: save-and-flush after each chunk, via method naming or a subclass override.- Resource patterns in builders: pass
"classpath:data/input/file-*.txt"directly instead of building aResource[]yourself. - Staged DSL builders:
FlatFileItemReaderBuilderand others now reject mutually exclusive option combinations at compile time instead of failing at startup.
The job repository now uses Spring Framework's DefaultFormattingConversionService through a new ConversionServiceFactory in place of hand-written converters, with backward compatibility kept. The milestone also lists APIs deprecated for removal in Spring Batch 7.0, including Apache Derby support, the legacy date/time converters and some JobExecution methods. Check your builds for deprecation warnings now.
Read more — Spring Blog