Çoğu mühendislik ekibi, retrieval-augmented generation (RAG) konusunda aynı duvara toslar. Eğitim kılavuzlarındaki (tutorial playbook) adımları izlerler: belgeleri 512 veya 1024 token'lık sabit parçalara (chunks) bölerler, bunları tek bir embedding modelinden geçirirler ve basit bir top-k aramasıyla bir vektör veritabanını çağırırlar. Bir sunum dosyasında bu yöntem sağlam görünür; ancak üretim ortamında (production) her şey çöker.

Sabit parçalar içeriği umursamaz. Bir hukuk sözleşmesini cümle ortasından böler ve sorumluluk maddelerini (liability clauses) birbiriyle alakasız iki metin parçası arasında asılı bırakmaktan çekinmezler. Tüm bir API uç noktası (endpoint) açıklamasını, kullanıcınızın sorduğu özel parametrenin gürültü içinde kaybolacağı kadar büyük ve şişkin bir parçaya doldururlar. Ayrıca, geri çağırma (retrieval) yavaş olduğunda, her milisaniyelik gecikme (latency) doğrudan kullanıcı deneyimine yansır. Bunu acı yoldan öğrendik. Sonra geri çağırma katmanımızı tamamen yıktık ve yeniden inşa ettik. Recall at ten oranımız yüzde yetmiş sekizden yüzde doksan beşe çıktı. Gecikme artmadı; aksine ciddi oranda düştü.

Kopyala-Yapıştır RAG'ın Sorunu

Standart RAG yığını (stack) bir tür varsayılan ayar haline geldi. Küçük parçalar, tek bir embedding modeli, vektör araması; işte bu kadar. Bu yaklaşım bir demoda işe yarar çünkü demolar temiz sorular ve düzenli belgeler kullanır. Üretim verisi ise asla düzenli değildir.

Hukuki belgeler hiyerarşik bir yapıya sahiptir. Bölümler alt bölümleri, alt bölümler ise maddeleri içerir. Bunları kaba bir token sayacıyla dilimlerseniz, modelin muhakeme yapması için ihtiyaç duyduğu ilişkileri yok edersiniz. API dokümantasyonunun da bir yapısı vardır ancak bu farklıdır. Bir fonksiyon imzası (function signature), parametreleri, dönüş değeri ve örnek kullanımı mantıksal bir birim oluşturur. Bunu sabit bir token penceresine zorlarsanız, ya örneği kesip atarsınız ya da parçayı alakasız fonksiyonlarla doldurursunuz. Destek talepleri (support tickets) karmaşıktır, konuşma dilindedir ve ani konu değişiklikleriyle doludur. Wiki sayfaları ise geniş kapsamlıdır ve çapraz referanslar içerir. Tek bir parçalama (chunking) stratejisi tüm bunları karşılayamaz; buna rağmen ekipler rutin olarak tam da bunu uygular. Biz ise bunun mümkün olduğunu iddia etmekten vazgeçtik.

Stratejik Parçalama: Yöntemi Materyale Uyarlayın

İçerik duyarlı parçalamaya (content-aware chunking) geçtik. Hukuki belgeler için belge hiyerarşisine saygı duyan özyinelemeli parçalama (recursive chunking) kullanıyoruz. Bu yöntem, maddeleri bütünsel tutar ve bölümler arasındaki ebeveyn-çocuk ilişkilerini korur. API dokümantasyonu için, her fonksiyonu veya uç noktayı bir sınır olarak kabul eden fonksiyona duyarlı parçalama (function-aware chunking) geliştirdik. Eğer bir parametre açıklaması uzun sürerse, parça bir token sınırına göre değil, o fonksiyonun etrafında genişler. Destek talepleri için, doğal konu sınırlarını tespit eden anlamsal parçalama (semantic chunking) kullanıyoruz. Bir müşteri aniden fatura şikayetinden teknik bir hataya geçtiğinde, bölünme tam o noktada gerçekleşir. Wiki sayfaları ve yapılandırılmamış bilgi tabanları için ise hafif bir LLM'in metni değerlendirdiği ve anlamlı bir sınırın nerede olması gerektiğine karar verdiği ajan tabanlı parçalama (agentic chunking) kullanıyoruz. Bu yöntemin kurulumu karakter bazlı bölmeye göre daha yavaştır, ancak işe yarayan geri çağırma ile sadece tahmin yürüten geri çağırma arasındaki fark budur.

Hibrit Geri Çağırma: Vektör Araması Neden Tek Başına Yeterli Değildir?

Vektör araması anlamı anlar ancak tam eşleşmeleri kaçırabilir. Eğer bir kullanıcı ERR_CONNECTION_RESET_0x5F3 gibi bir hata kodu yapıştırırsa, anlamsal benzerlik (semantic similarity) bunu sadece genel ağ hatalarından bahseden paragrafların altına sıralayabilir. Öte yandan BM25, tam dizeleri bulur ancak kavramsal ilişkiselliği kaçırır. Her ikisine de ihtiyacınız var.

Vektör araması ve BM25'i paralel olarak çalıştırıyoruz. Ardından sonuçları, iki farklı arama alanından gelen puanları aynı ölçeğe zorlamadan normalize eden Reciprocal Rank Fusion (RRF) ile birleştiriyoruz. Birleştirmeden sonra, en iyi adayları bir cross-encoder reranker'dan geçiriyoruz. Bu, az miktarda gecikme ekler ancak hassasiyetteki (precision) artış çok önemlidir. Reranker, sorguyu ve her bir adayı birlikte okur ve başlangıçtaki embedding'in kosinüs benzerliğinden (cosine similarity) çok daha doğru bir alaka düzeyi puanı atar. Uygulamada bu kombinasyon, saf vektör aramasının kaçırdığı tam hata kodlarını yakalarken, anahtar kelime aramasının görmezden geleceği kavramsal olarak ilgili sorun giderme adımlarını da yüzeye çıkarır.

Sorgu Genişletme: Kullanıcı Girişini İndekse Ulaşmadan Önce Düzeltme

Kullanıcılar mükemmel arama sorguları yazmazlar. "Son dağıtımım (deploy) neden başarısız oldu ve bunu nasıl geri alabilirim (roll back)?" gibi, iki ayrı bilgi kümesini bulmayı ve bunları birbirine bağlamayı gerektiren çok adımlı (multi-hop) sorular sorarlar. Ya da indekse kötü eşleşen belirsiz sorular sorarlar.

Arama yapmadan önce sorguları dönüştürüyoruz. Çok adımlı (multi-hop) bir soru alt sorulara bölünür. Belirsiz bir niyet, birden fazla spesifik arama sorgusuna genişletilir. Tek bir kullanıcı sorgusunu beş farklı arama sorgusuna genişletmenin, geri çağırma (recall) oranını yüzde yetmiş sekizden yüzde doksan altıya çıkarabildiğini gördük. Bu, LLM'e daha zorlayıcı promptlar vermekle ilgili değildir. Bu, geri getirme (retrieval) sistemine doğru bağlamı bulması için daha fazla deneme şansı tanımakla ilgilidir. Üretilen her bir sorgu farklı bir bakış açısını veya terminolojiyi yakalar ve birleştirilen sonuçlar eksiksiz bir tablo çizer.

Bayesyen Optimizasyon: Tahmin Etmeyi Bırakın

Birden fazla parçalama (chunking) stratejisi, hibrit geri getirme ve sorgu genişletme yöntemine sahip olduğunuzda yeni bir sorunla karşılaşırsınız. Çok fazla ayar düğmesi vardır. Parça boyutu (chunk size), örtüşme yüzdesi (overlap percentage), vektör ağırlığına karşı BM25 ağırlığı, yeniden sıralama (reranking) eşikleri ve top-k değerlerinin tümü doğrusal olmayan şekillerde etkileşime girer. Manuel ayarlama bir tahmin oyununa dönüşür.

Tahmin etmeyi bıraktık. Şunu ele alıyoruz