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.
// 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:
// 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
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:`; ```