💡 Tam çalışan örnek GitHub’da mevcuttur:
document-to-markdown-rag-chunks-java
İddia Masası Sorunu: Neden RAG Alımı Gerçek Dosyalarda Bozulur
Yerinde bir RAG alım hattı, bir ekibin zaten sahip olduğu dosyaları üçüncü bir tarafa göndermeden aranabilir, alıntılanabilir metne dönüştüren bir belge ayrıştırma katmanıdır. Sigorta operasyonları bunun neden önemli olduğunu gösterir. Bir iddia sorumlusu iç asistanına “bu poliçedeki su hasarı hakkında düzenleyici ne söylemişti?” diye sorar ve cevap geçen Mart ayındaki bir e-postada, ona eklenmiş bir PDF raporunda, “Findings” (Bulgular) başlığı altında bulunur. Asistan, alım ekşi okur, başlığı korur ve raporun hangi e-postayla geldiğini hatırlarsa bunu bulabilir.
Çoğu alım işi bu üç unsurdan birini yanlış yapar. Düz metin çıkarıcı e-posta gövdesini döndürür ve eki görmez. Sabit 512‑token bölücü raporu “Findings” başlığının ortasından keser. Ve barındırılan ayrıştırıcı ikisini de çözer, ancak iddia dosyası, kişisel ve tıbbi detaylarıyla, bir başkasının sunucularına yüklendikten ve sayfa başına faturalandırıldıktan sonra.
Ekibin ihtiyacı dar ve somut: Java hizmeti içinde Word, PDF, EML ve ZIP dosyalarını okuyabilmek, yapılarını Markdown olarak koruyabilmek, yazarın başlıklarında bölmek ve her parçaya kaynak ve üst öğeyi eklemek.
Piyasa anlık görüntüsü: İncelediğimiz 2026 “RAG için belge ayrıştırma” kılavuzları, açık kaynak Python ayrıştırıcılarını sayfa başına faturalandırılan bulut API’leriyle karşılaştırıyor. Kendi donanımınızda çalışan bir Java kütüphanesi bu konuşmadan büyük ölçüde eksik.
Neden RAG Boru Hatları Düz Metin Yerine Markdown’a İhtiyaç Duyar?
Markdown, bir alıcının bir fikrin nerede bittiğini ve bir sonrakinin nerede başladığını gösteren belge parçalarını korur. Başlıklar # satırları haline gelir, tablolar satır ve sütun olarak kalır, listeler öğelerini saklar. Bir parçalama aracı bu başlıklarda bölünebilir ve parçayı okuyan bir LLM, bir kişinin göreceği aynı taslağı görür. Düz metin bu taslağı atar, bölme için tek sinyal olarak yalnızca boyutu bırakır.
Neden Genel Çözümler Burada İşe Yaramaz
Takımlar, uygun bir alım katmanı inşa etmeden önce genellikle üç şeyden birini dener:
- Düz metin çıkarımı artı token bölücü: kurması hızlıdır, ancak parçalar bölümleri karıştırır ve alıntılayacağınız başlığı kaybeder.
- Bulut ayrıştırma API’si: iyi yapı sağlar, ancak dosyalar ağ üzerinden çıkar ve her yeniden indeksleme sayfasıyla fatura artar.
- Format başına ev yapımı ayrıştırıcı: DOCX için bir kütüphane, PDF için bir diğeri, e-posta için bir MIME ayrıştırıcı ve arşivler için
java.util.zip, her biri kendi kenar durumlarıyla.
GroupDocs.Parser for Java, tek bir Parser sınıfı altında tüm dört formatı kapsar ve aynı süreç içinde çalışır.
Çözüm: İddia Alımı İş Akışında GroupDocs.Parser
GroupDocs.Parser for Java bir belgeyi okur ve getFormattedText aracılığıyla metnini Markdown olarak döndürebilir. E-postalar ve arşivler, öğeleri yeni Parser örnekleri olarak açan kapsayıcılar olarak sunulur; böylece bir e-postaya eklenmiş PDF, diskteki bir PDF gibi işlenir. Örnek proje bunu altı statik metoda sarar ve sonucu JSON Lines olarak yazar; bu, herhangi bir gömme işi ya da vektör deposu tarafından yüklenebilir. Hiçbir RAG çerçevesi dahil edilmez; çıktı formatı entegrasyon noktasını oluşturur.
İlerlemek için şunlara ihtiyacınız var:
pom.xmliçin JDK 11 veya üzeri (kod kendisi Java 8 özelliklerine bağlıdır)- GroupDocs.Parser for Java 26.10 (geçici lisans alın)
- Bir avuç DOCX, PDF, EML veya ZIP dosyası
Projenin pom.xml dosyası https://releases.groupdocs.com/java/repo/ deposunu ve tek bağımlılığı bildirir, bu yüzden bir yapı bir komutla yapılır:
mvn compile exec:java
Alım Katmanını Adım Adım Uygulama
Aşağıdaki adımlar, bir iddia dosyasını gelen kutusundan indekse kadar izler. Her adım, RagChunksDemo.java içinde bir ya da iki metoda karşılık gelir. Bunları kasıtlı olarak düz statik metodlar olarak tuttuk, böylece herhangi birini mevcut bir işçiye alıp geri kalanını benimsemeden kullanabilirsiniz.
Adım 1 – Her Dosyayı Aç ve Yönlendir
Yüklenen her dosya kendi Parser’ına sahiptir. Dosya adı kaynak kimliği olur ve üst‑seviye dosyanın üst öğesi yoktur.
// One call per uploaded claim document
String sourceId = new File(path).getName();
try (Parser parser = new Parser(path)) {
return chunkParser(parser, sourceId, null, 0); // null parent: top-level file
} catch (UnsupportedDocumentFormatException ex) {
// An unknown format is logged and skipped, the batch keeps going
System.out.println("skipped (unsupported format): " + sourceId);
return new ArrayList<>();
}
chunkParser ardından gövdeyi çıkarır, parçalar ve ekleri derinlik 2’nin altında olduğu sürece altına iner.
Adım 2 – Markdown İste, Düz Metin Kabul Et
Çıkarma adımı, uzantı listesini sabit kodlamak yerine formatın ne desteklediğini sorgular.
if (parser.getFeatures().isFormattedText()) {
// Headings, lists and tables survive as Markdown
FormattedTextOptions options =
new FormattedTextOptions(FormattedTextMode.Markdown);
try (TextReader reader = parser.getFormattedText(options)) {
if (reader != null) {
return new ExtractedText("markdown", reader.readToEnd());
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
try (TextReader reader = parser.getText()) {
if (reader != null) { // fallback for formats without formatted text
return new ExtractedText("plain", reader.readToEnd());
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
return new ExtractedText("none", ""); // e.g. a photo with no OCR
Bu ayarların iddia verileri için önemi:
FormattedTextMode.Markdown: düzenleyicinin “Findings” başlığı, parçalama aracına## Findingsolarak ulaşır, böylece bir bölme noktası ve alıntı olur.isFormattedText(): örnek çalıştırmada DOCX ve e-posta Markdown olarak dönerken PDF düz metne geri döner veformatalanı ne olduğunu kaydeder.nonesonucu: ZIP içindeki iddia fotoğrafları OCR olmadan parça üretmez; bu dürüst ve izlenmesi kolaydır.
Adım 3 – Düzenleyicinin Başlıklarında Böl
Parçalayıcı, altı Markdown seviyesinin her birinde mevcut başlığı tutan bir yığın kullanır. Yeni bir başlık, önceki bölümü kapatır ve seviyesinin altındaki her şeyi sıfırlar.
for (String line : markdown.split("\\r?\\n", -1)) {
Matcher heading = HEADING.matcher(line); // "#" to "######" + title
if (heading.matches()) {
// Close the previous section under the old path
addSection(chunks, section.toString(), sourceId, parentId, path, format);
section.setLength(0);
int level = heading.group(1).length();
stack[level - 1] = heading.group(2).trim();
for (int i = level; i < stack.length; i++) {
stack[i] = null; // forget deeper headings
}
path = joinPath(stack); // "Heading 1 > Heading 1.2"
}
section.append(line).append('\n');
}
1500 karakteri aşan bölümler paragraf sonlarında kesilir, böylece uzun bir bulgu bölümü aynı başlık yolunu paylaşan birkaç parçaya dönüşür. Paketlenmiş Word dosyasında bu, Heading 1 > Heading 1.2 > Heading 1.2.1 gibi yollar üretir.
Adım 4 – Ekleri Takip Et ve JSON Lines Yaz
Bu, bir iddia masasının en çok önem verdiği adımdır. getContainer() e‑posta eklerini ve ZIP girdilerini listeler; her öğe bir alt belge olarak açılır ve üst öğenin kimliğini devralır.
Iterable<ContainerItem> items = parser.getContainer();
if (items == null) {
return chunks; // not an email or archive
}
for (ContainerItem item : items) {
// "claim-0412.eml/report.pdf" style ids keep the lineage readable
String childId = sourceId + "/" + item.getFilePath();
try (Parser child = item.openParser()) {
chunks.addAll(chunkParser(child, childId, sourceId, depth + 1));
} catch (UnsupportedDocumentFormatException ex) {
System.out.println("skipped (unsupported format): " + childId);
}
}
writeJsonl ardından her parçayı id, source, parent, heading_path, format ve text alanlarıyla UTF‑8 bir satır olarak yazar. Dört örnek girdiyle çalıştırma 22 satır üretir. Örnek e‑postanın ekinden gelen parça email-with-attachment.eml/attachment.txt#0 ve parentı email-with-attachment.eml olur. Bu çift, asistanın “14 Mart e‑postasına ekli rapordan” demesini, “bir yerden” demesini engeller.
Gerçek İş Akışı: Haftalık İddiaların Yeniden İndekslenmesi
Haftanın kapanan iddia posta kutularını her Cuma EML dosyaları ve destekleyici belgelerin ZIP paketleri olarak dışa aktaran bir iddia operasyon ekibini hayal edin. Bir Java işçisi bu dışa aktarmaları belge deposuna zaten taşıyor. Alım eklemek, her dosya için chunkDocument çağırmak ve JSON Lines çıktısını gömme kuyruğuna eklemek demektir.
Adım 4, raporun e‑postaya ekli olduğu izini korur. Adım 3, asistan “Findings” alıntıladığında alıntının dosya ve başlık adını, yalnızca bir parça numarasını değil, göstermesini sağlar. Bu tür bir indeks için benim kuralım şudur: bir parça dosya ve başlığa geri alıntılanamıyorsa, indeksde bulunmamalıdır.
İş Etkisi: Bu Değişiklik Ne Sağlar
| Özellik | Önceki tipik kurulum | GroupDocs.Parser boru hattı ile |
|---|---|---|
| Dosyaların nerede ayrıştırıldığı | Üçüncü‑taraf uç noktası | Kendi JVM’nizde |
| Ayrıştırma maliyet modeli | Sayfa başına, her yeniden indekslemede | Sayfa başına bulut ücreti yok |
| Parça sınırları | Sabit token pencereleri | Yazarın başlıkları, 1500 karakter sınırı |
| E‑posta ekleri | Çoğunlukla atlanır veya düzleştirilir | Alt belgeler olarak ayrıştırılır |
| Alıntı verileri | En iyi dosya adı | source, parent ve heading_path |
| Çalışma zamanı bağımlılıkları | SDK + ağ erişimi | Tek Maven artefaktı |
Bileşik etki, uyum ekibinin onaylayabileceği bir indeks ve yanıtları gerçek belge ve bölüme yönlendiren bir asistan yaratır.
GroupDocs.Parser’ın Uygun Olduğu Diğer Sigorta Senaryoları
Alım katmanı kurulduktan sonra aynı kod diğer belge‑ağır işler için de kullanılabilir:
- Poliçe metni araması: Bölüm başlıklarıyla bölünmüş Word poliçeleri, yanıtların tam bölümü alıntılamasını sağlar.
- Broker başvuruları: Karışık PDF ve elektronik tablo içeren ZIP yüklemeleri, her bir üye ayrı ayrı indekslenir ve başvuru ile ilişkilendirilir.
- Şikayet yönetimi: Müşteri e‑postaları ve ekleri birlikte indekslenir, e‑posta her ek parçasının üst öğesi olur.
İddia Ortamınızda Başlamak
Örneği klonlayın, kendi dışa aktardığınız birkaç e‑posta üzerinde çalıştırın ve output/chunks.jsonl dosyasını açarak başlık yollarını ve üst kimlikleri gömme işine bağlamadan önce kontrol edin. Aşama‑aşama mimari notları, bu boru hattı için belgelendirme kullanım senaryosu içinde ve hangi biçimlerin korunduğunu listeleyen Markdown çıktı referansı içinde bulunur.