Spring AI 2.1’de ‘MessagePart’ Muhakeme Mimarisi, ‘VectorStore.upsert()’ ile Özel Gömme Vektörleri ve JDK 28’de 18 Kat Hızlı Yığın Dışı Bellek
Java ve Spring ekosisteminde üç kritik mühendislik güncellemesi yayınlandı: Çok turlu sohbetlerde düşünme bloklarını ve kriptografik imzaları koruyan Spring AI 2.1 MessagePart (ReasoningPart & OpaquePayload) mimarisi, harici vektörleri doğrudan yazan VectorStore.upsert(EmbeddedDocument) API'si ve JDK 28 FFM API'de yığın dışı bellek tahsisini 6 ila 18 kat hızlandıran yerleşik Arena havuzları.

Kurumsal Java ekosisteminde hem yapay zeka ajan çerçevelerini hem de düşük seviyeli sistem programlama performansını doğrudan etkileyen üç önemli mühendislik güncellemesi paylaşıldı. Resmi Spring Blog’da 28 Ekim 2026 tarihinde yayımlanan iki teknik makale, Spring AI 2.1 (2.1.0-RC1) sürümüyle gelen sıralı MessagePart muhakeme (reasoning) veri modelini ve önceden hesaplanmış vektörleri doğrudan veritabanına yazan VectorStore.upsert(EmbeddedDocument) API’sini detaylandırırken; OpenJDK cephesinde JDK 28 Foreign Function & Memory (FFM) API içerisindeki Arena.ofConfined() tahsislerini 6 ila 18 kat hızlandıran iş parçacığı yerel bellek havuzları ve güncellenen Java Güvenli Kodlama Rehberi duyuruldu.
Bu kapsamlı analizde, her üç mimari yeniliğin çözdüğü üretim darboğazları ve kod düzeyindeki uygulamaları incelenmektedir.
1. Spring AI 2.1 MessagePart Mimarisi: Çok Turlu Sohbetlerde Muhakeme Bloklarının (ReasoningPart) Kayıpsız Korunması
Modern sınır dil modelleri (Anthropic Claude, Google Gemini, OpenAI Responses API, DeepSeek) bir soruyu yanıtlarken veya bir aracı (ToolCall) tetiklerken yalnızca düz metin üretmez; aynı zamanda içsel düşünme/muhakeme blokları (thinking blocks) ve bu blokların bütünlüğünü doğrulayan kriptografik imzalar (thought signatures / encrypted reasoning items) üretir.
Eski Veri Modelindeki Kırılma
Spring AI’ın önceki sürümlerinde AssistantMessage gibi mesaj sınıfları, içeriği tek bir düz metin alanı (String text) ve buna eklenen yan listeler (List<ToolCall>, List<Media>) olarak tutuyordu. Çok turlu (multi-turn) bir ajan iş akışında sohbet geçmişi modele geri gönderildiğinde:
- Düşünme bloklarının (
reasoning) metin ve araç çağrıları arasındaki kesin sırası kayboluyordu. - Sağlayıcının beklediği kriptografik düşünce imzaları düşürülüyordu.
- Bunun sonucunda sağlayıcı API’leri
HTTP 400 Bad Requesthatası döndürüyor veya model önceki turdaki akıl yürütme bağlamını sıfırlayarak ağır performans kaybı yaşıyordu.
Çözüm: Sıralı MessagePart Listesi ve OpaquePayload
Dimitar Proynov tarafından tanıtılan Spring AI 2.1 (2.1.0-RC1) çekirdek veri modeli güncellemesiyle birlikte, her mesaj (AssistantMessage, UserMessage, ToolResponseMessage) artık içeriğini tiplendirilmiş ve sıralı bir MessagePart listesi olarak saklıyor:
TextPart: Standart metin çıktıları.ReasoningPart: Modelin içsel düşünme ve muhakeme adımları.ToolCallPart&ToolResultPart: Modelin talep ettiği araç çağrıları ve dönen yürütme sonuçları.MediaPart: Görsel, ses ve belge içerikleri.UnknownPart: Sağlayıcının henüz açıkça modellenmemiş yeni JSON bloklarını veri kaybı olmadan yakalayan koruma katmanı.OpaquePayload: Anthropic düşünce imzaları, GeminithoughtSignaturejetonları veya OpenAI şifreli muhakeme öğeleri gibi sağlayıcıya özgü kriptografik verileri değiştirmeden saklayıp bir sonraki API isteğinde birebir (verbatim) geri oynatan taşıyıcı.
flowchart LR
subgraph Turn1["1. Tur: Model Yanıtı (Spring AI 2.1.0-RC1)"]
R1["ReasoningPart\n+ OpaquePayload (İmza)"] --> TC["ToolCallPart\n(Veritabanı Sorgusu)"]
end
subgraph SessionMem["Yerleşik Session Memory"]
SM[("Sıralı MessagePart Akışı\nKayıpsız Kalıcılık")]
end
subgraph Turn2["2. Tur: Kayıpsız Geri Oynatma (Round-Trip Replay)"]
Replay["ReasoningPart (İmza Korundu)\n+ ToolCallPart + ToolResultPart"] --> Final["TextPart\n(Nihai Doğrulanmış Yanıt)"]
end
Turn1 --> SM --> Turn2
Bu mimari; OpenAI (Chat Completions & Responses API), Anthropic, Google GenAI (Gemini), Amazon Bedrock Converse, Ollama, DeepSeek ve Mistral AI entegrasyonlarında yerel olarak desteklenmekte olup, geriye dönük uyumluluk için getText() ve getToolCalls() metotları alttaki MessagePart listesi üzerinde görünüm (view) olarak çalışmaya devam etmektedir.
2. Spring AI 2.1 VectorStore.upsert() ve EmbeddedDocument: Kendi Gömme Vektörlerini Doğrudan Yazma
Spring AI 2.1’den önce VectorStore.add(List<Document>) çağrıldığında, çerçeve her zaman içeride yapılandırılmış bir EmbeddingModel nesnesini tetikleyerek metni o anda vektöre dönüştürüyordu. Ancak kurumsal veri boru hatlarında vektörlerin çevrimdışı (offline) toplu işlerle, ince ayarlı özel modellerle veya görsel/ses gibi çok modlu (multimodal) gömme motorlarıyla önceden hesaplandığı senaryolarda bu zorunluluk hem çift maliyet hem de mimari engel yaratıyordu.
Yeni EmbeddedDocument kaydı (record) ve VectorStore.upsert(List<EmbeddedDocument>) API’si bu kısıtı ortadan kaldırıyor:
- Sıfır Yerel Embedding Çağrısı:
Documentnesnesi ile önceden hesaplanmışfloat[]vektörü birEmbeddedDocumentiçinde eşleştirilerek doğrudan vektör veritabanına yazılır. - Kurucu Zamanı (Construction-Time) Katı Doğrulama:
EmbeddedDocumentoluşturulurken boş diziler,NaNveyaInfinitydeğerleri anında reddedilir; veritabanına yazılmadan önce vektör boyutu hedef indeksin boyutuyla karşılaştırılır. - İdempotent Güncelleme ve
DocumentMetadata.CONTENT_REF: Kararlı belge kimlikleri (id) üzerinden çalışanupsertdeseni, yarıda kalan toplu taşıma (batch migration) işlerinin mükerrer kayıt oluşturmadan güvenle yeniden çalıştırılmasını sağlar. Çok büyük ham içerikler ise veritabanı satırını şişirmek yerineDocumentMetadata.CONTENT_REFanahtarıyla S3/nesne depolama adresine yönlendirilebilir. - Desteklenen Veritabanları: PgVector, Redis, Qdrant ve Elasticsearch entegrasyonları
2.1sürümünde kutudan çıktığı haliyleupsert()desteğine sahiptir.
| Özellik / Kriter | Spring AI 2.0 (Eski Mimari) | Spring AI 2.1 (2.1.0-RC1 Yeni Mimari) |
|---|---|---|
| Mesaj İçeriği Temsili | Düz String text + ayrık ToolCall / Media yan listeleri |
Sıralı List<MessagePart> (ReasoningPart, TextPart, ToolCallPart) |
| Kriptografik Düşünce İmzaları | Çok turlu geri dönüşlerde (round-trip) kaybolma / HTTP 400 riski | OpaquePayload ve SessionMemory ile birebir (verbatim) geri oynatma |
| Vektör Yükleme Yöntemi | add(List<Document>) ile zorunlu anlık EmbeddingModel çağrısı |
upsert(List<EmbeddedDocument>) ile önceden hesaplanmış float[] yazımı |
| Vektör Bütünlük Denetimi | Veritabanı sürücüsü hata verene kadar gecikmeli kontrol | Kurucu zamanında NaN / Infinity ve indeks boyut doğrulaması |
| Büyük İçerik Referansı | Metnin tamamının vektör satırına gömülmesi | DocumentMetadata.CONTENT_REF ile harici nesne depolama (S3 vb.) bağlama |
3. JDK 28 FFM API’de 6–18 Kat Hızlı Yığın Dışı (Off-Heap) Bellek Havuzları ve Güvenli Kodlama
OpenJDK tarafında JDK 28 için paylaşılan performans analizleri, Project Panama kapsamında geliştirilen Foreign Function & Memory (FFM) API içerisindeki önemli bir darboğazın çözüldüğünü gösteriyor.
C/C++ kütüphaneleriyle konuşan Java kodlarında geçici işaretçiler (pointers), küçük struct yapıları veya errno değerleri için sıklıkla Arena.ofConfined() kullanılır. OpenJDK mühendislerinin topladığı telemetri verileri, yerel bellek ayıran sınırlandırılmış arenaların (confined arenas) %99,99’undan fazlasının 64 bayttan daha küçük bellek talep ettiğini ortaya koydu. Önceki JDK sürümlerinde yalnızca 4 veya 8 baytlık bir tam sayı için bile işletim sisteminin yerel ayırıcısına (malloc) gidilmesi ve ağır temizlik (cleanup) üst verisi oluşturulması, bellek erişiminin kendisinden çok daha yüksek bir gecikme yaratıyordu.
JDK 28’in Çözümü: İş Parçacığı Yerel (Per-Thread) Tembel Bellek Havuzları
- Her platform iş parçacığı (platform thread) artık küçük tahsisler için tembel olarak başlatılan yerel bellek havuzlarını (varsayılan olarak dört adet 64 baytlık havuz) önbelleğinde tutuyor.
Arena.ofConfined()içindeki küçük tahsisler işletim sistemine gitmeden doğrudan bu iş parçacığı yerel havuzdan karşılanıyor ve arena kapandığında havuza iade ediliyor.- Sonuç: Hiçbir kaynak kod değişikliği gerektirmeden ve
Arena.ofConfined()’ın iş parçacığı güvenliği garantilerini bozmadan tahsis gecikmesi %90’a kadar düşüyor ve mikro kıyaslamalarda 6 ila 18 kat daha hızlı yığın dışı bellek tahsisi sağlanıyor.
Buna paralel olarak yayımlanan güncellenmiş Oracle Java Güvenli Kodlama Rehberi (Java Secure Coding Guidelines) ise Security Manager sonrası dönemde güvenli olmayan serileştirmelere karşı ObjectInputFilter (JEP 290 / JEP 415) kullanımını, FFM bellek sınır kontrollerini ve katı girdi doğrulama desenlerini kurumsal standart olarak vurguluyor.
4. Kod Uygulaması: Spring AI 2.1 MessagePart + EmbeddedDocument ve JDK 28 Arena.ofConfined()
Aşağıdaki kapsamlı Java referans sınıfı; Spring AI 2.1’de EmbeddedDocument ile önceden hesaplanmış vektörlerin upsert edilmesini, AssistantMessage içindeki sıralı ReasoningPart / OpaquePayload bloklarının okunmasını ve JDK 28 FFM API ile yüksek hızlı Arena.ofConfined() kullanımını bir arada göstermektedir:
package com.enterprise.ai.platform;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.util.List;
import java.util.Map;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.MessagePart;
import org.springframework.ai.chat.messages.ReasoningPart;
import org.springframework.ai.chat.messages.TextPart;
import org.springframework.ai.chat.messages.ToolCallPart;
import org.springframework.ai.document.Document;
import org.springframework.ai.document.DocumentMetadata;
import org.springframework.ai.vectorstore.EmbeddedDocument;
import org.springframework.ai.vectorstore.VectorStore;
public class SpringAi21AndJdk28Showcase {
/**
* 1. Spring AI 2.1: Önceden hesaplanmış (pre-computed) vektörlerin
* yerel EmbeddingModel çağrılmadan doğrudan VectorStore'a upsert edilmesi.
*/
public void ingestPrecomputedVectors(VectorStore vectorStore, float[] externalEmbedding) {
Document doc = Document.builder()
.id("arch-spec-2026-42")
.text("Sıfır güven mikroservis ağ geçidi mimari özeti...")
.metadata(Map.of(
"pipeline", "offline-gpu-batch-v3",
DocumentMetadata.CONTENT_REF, "s3://corp-knowledge-lake/specs/arch-spec-2026-42.pdf"
))
.build();
// Kurucu zamanında NaN, Infinity ve boş dizi kontrolü otomatik yapılır
EmbeddedDocument embeddedDoc = new EmbeddedDocument(doc, externalEmbedding);
vectorStore.upsert(List.of(embeddedDoc));
}
/**
* 2. Spring AI 2.1: Çok turlu sohbetlerde sıralı MessagePart ve ReasoningPart incelemesi.
*/
public void inspectReasoningRoundTrip(AssistantMessage responseMessage) {
for (MessagePart part : responseMessage.getParts()) {
switch (part) {
case ReasoningPart reasoning -> System.out.printf(
"[MUHAKEME BLOĞU] Uzunluk: %d kr | Kriptografik İmza Mevcut: %b%n",
reasoning.getText().length(),
reasoning.getOpaquePayload() != null
);
case ToolCallPart toolCall -> System.out.printf(
"[ARAÇ ÇAĞRISI] Araç: %s%n", toolCall.getToolName()
);
case TextPart text -> System.out.printf(
"[YANIT METNİ] %s%n", text.getText()
);
default -> System.out.println("[DİĞER BLOK] " + part.getClass().getSimpleName());
}
}
}
/**
* 3. JDK 28 FFM API: İş parçacığı yerel 64-bayt havuzlarından
* 6-18 kat daha hızlı yığın dışı (off-heap) bellek tahsisi.
*/
public float computeFastDotProductOffHeap(float x1, float y1, float x2, float y2) {
// JDK 28'de <=64 bayt tahsisler işletim sistemi malloc() çağrısı yerine
// platform iş parçacığının yerel havuzundan (confined pool) anında karşılanır.
try (Arena arena = Arena.ofConfined()) {
MemorySegment vecA = arena.allocateFrom(ValueLayout.JAVA_FLOAT, x1, y1);
MemorySegment vecB = arena.allocateFrom(ValueLayout.JAVA_FLOAT, x2, y2);
return (vecA.getAtIndex(ValueLayout.JAVA_FLOAT, 0) * vecB.getAtIndex(ValueLayout.JAVA_FLOAT, 0))
+ (vecA.getAtIndex(ValueLayout.JAVA_FLOAT, 1) * vecB.getAtIndex(ValueLayout.JAVA_FLOAT, 1));
}
}
}
5. Mühendislik Özeti
Spring AI 2.1 (2.1.0-RC1), MessagePart ve OpaquePayload mimarisiyle çok adımlı muhakeme ajanlarında en sık karşılaşılan bağlam/imza kaybı sorununu kökten çözerken, VectorStore.upsert(EmbeddedDocument) ile büyük ölçekli kurumsal RAG boru hatlarına tam esneklik kazandırıyor. Alt katmanda ise JDK 28’in 6–18 kat hızlanan FFM Arena.ofConfined() havuzları, yerel C/C++ ve SIMD/GPU kütüphaneleriyle konuşan yüksek frekanslı Java servislerinde yığın dışı bellek maliyetini neredeyse sıfıra indiriyor.
Yazılım mimarisi, mikroservis ekosistemleri ve üretken yapay zeka uygulamaları üzerine çalışıyorum. TastutanLabs çatısı altında geliştirici araçları ve SaaS ürünleri inşa ediyorum.
Bu analizin 6 kartlık görsel özetini Instagram'da inceleyin ve kaydedin
Her gün yazılım mimarisi, Java/JVM ve yapay zeka gelişmelerini kendi başına okunabilen 6 slaytlık Mini-Blog serileri halinde paylaşıyoruz.
Yorumlar (0)
Düşüncelerinizi Paylaşın
Henüz yorum yapılmamış. İlk yorumu siz yapın!
Bu Kategorideki Diğer İncelemeler
OpenJDK ‘Project Detroit’ (FFM ile V8 ve CPython), Spring Boot Yerel ‘Cloud Foundry / kind’ Orkestrasyonu ve Quarkus 4.0 Mimarisi
OpenJDK'nın Foreign Function & Memory (FFM) API üzerinden Google V8 ve CPython çalışma zamanlarını doğrudan JVM sürecine gömen Project Detroit girişimi, Spring Boot uygulamalarında Docker/kind tabanlı yerel Cloud Foundry dağıtımı ve Quarkus 4.0 (Vert.x 5, HTTP/3, Hibernate 8) mimarisi inceleniyor.
JDK 28’de ‘JEP 401 Value Classes’ ve Değişmez Veri Mimarisi, Spring AI 2.1 ‘MessagePart’ Akıl Yürütme Korunumu ve Özel Vektör ‘Upsert’ API’si
OpenJDK 28 erken erişim sürümlerinde 30 çekirdek sınıfı kimliksiz değer nesnesine dönüştüren JEP 401 (Value Classes), çok turlu akıl yürütme imzalarını kayıpsız taşıyan Spring AI 2.1 MessagePart mimarisi ve önceden hesaplanmış float[] vektörleri destekleyen VectorStore.upsert() yetenekleri inceleniyor.