Tüm Yazılara Dön
AI & LLM Mimarisi 2024 7 dk okuma Önder Şahin

Temel LLM Mimarisi ve RAG Sistemlerinde Hibrit Arama & Reranking

#LLM#RAG#VectorDB#Embeddings#HybridSearch#Reranking

Retrieval-Augmented Generation (RAG) Mimarisine Bakış

Büyük Dil Modelleri (LLM), parametrik hafızalarında geniş bilgi barındırsalar da güncel kurumsal verilere, özel şirket içi dokümanlara veya dinamik API sonuçlarına doğrudan erişemezler. **RAG (Retrieval-Augmented Generation)**, kullanıcının sorgusuyla ilgili en alakalı bilgi parçacıklarını dış bir kaynaktan çekerek LLM'in bağlam penceresine (Context Window) enjekte eden mimaridir.


1. Yalnızca Vektör Araması Neden Yetmez?

Geleneksel RAG pipeline'ları metinleri embedding vektörlerine çevirerek **Cosine Similarity** ile semantik arama yapar. Ancak salt yoğun (dense) vektör aramasının iki temel zayıflığı vardır: 1. **Anahtar Kelime Hassasiyeti**: Ürün kodları, hata ID'leri veya özel isimlerde semantik benzerlik zayıf kalabilir. 2. **Kavramsal Dağılma**: Benzer anlamlı fakat bağlam dışı paragraflar üst sıralara çıkabilir.

Bu sorunu çözmek için **Hibrit Arama (Dense Vector + Sparse BM25)** yaklaşımı uygulanır.

typescriptCode Snippet
// Hibrit Arama Mantığı (Reciprocal Rank Fusion - RRF)
interface SearchResult {
  docId: string;
  content: string;
  score: number;
}

function reciprocalRankFusion( vectorResults: SearchResult[], keywordResults: SearchResult[], k = 60 ): SearchResult[] { const scoreMap = new Map<string, { doc: SearchResult; score: number }>();

const processList = (list: SearchResult[]) => { list.forEach((item, rank) => { const current = scoreMap.get(item.docId) || { doc: item, score: 0 }; current.score += 1 / (k + rank + 1); scoreMap.set(item.docId, current); }); };

processList(vectorResults); processList(keywordResults);

return Array.from(scoreMap.values()) .sort((a, b) => b.score - a.score) .map((entry) => ({ ...entry.doc, score: entry.score })); } ```


2. Cross-Encoder Reranking Adımı

İlk arama aşamasında getirilen ilk 20-30 aday doküman, daha hassas bir **Cross-Encoder Reranker** (örneğin `bge-reranker-large` veya Cohere Rerank) modelinden geçirilerek gerçek anlamsal ilgi sırasına dizilir ve en iyi 3-5 parça seçilir:

typescriptCode Snippet
// Reranking Pipeline
const initialCandidates = await vectorDB.hybridQuery({ query, topK: 25 });
const rankedDocuments = await reranker.rank({
  query: query,
  documents: initialCandidates.map(d => d.content),
  topN: 4
});

3. Bağlam Enjeksiyonu ve Deterministik Prompt Şablonu

typescriptCode Snippet
const prompt = `Aşağıdaki bağlam bilgilerini temel alarak soruyu yanıtla. Bağlamda yer almayan bilgiler için tahmin yürütme.

BAĞLAM: ${rankedDocuments.map((doc, i) => `[${i + 1}] ${doc.text}`).join('\n\n')}

SORU: ${userQuery}

YANIT:`; ```

Özet ve En İyi Uygulamalar - **Chunking Stratejisi**: Sabit karakter bölme yerine semantik paragraf ve başlık tabanlı chunking kullanın. - **Metadata Filtreleme**: Tarih, kategori ve yetki etiketlerini vektör aramasında pre-filter olarak uygulayın.