Merhaba !
Serinin ikinci yazısıyla kaldığımız yerden devam ediyoruz. İlk yazıda, “Neden RAG kullanmalıyız?”, “Hangi sorunlara çözüm sunar?”, “Büyük dil modellerinin darboğazları nelerdir?” gibi sorulara birlikte bakmıştık. Ayrıca dil modellerinin davranış biçimlerini ve RAG mimarisinin genel hatlarını yüzeysel de olsa tanımıştık.
Bu yazıda artık konuyu biraz daha derinleştiriyoruz. Eğer ilk bölümü henüz okumadıysanız, öncesinde ona göz atmanızı öneririm. Buradan ulaşabilirsiniz.
Bu yazıda neler var?
- Embedding modelleri
Serinin üçüncü ve son yazısında ise ileri düzey RAG senaryolarına geçeceğiz ve her bir başlığı uygulamaya dönük şekilde detaylandıracağız.
İlk bölümde kavramsal olarak ele aldığımız RAG mimarisine bu yazıda daha yakından bakacağız. Özellikle “Retrieval” (bilgi bulup getirme) aşamasına odaklanacağız.

Simülasyon üzerinden ilerlemek için basit bir örnek kurgulayalım. Aşağıda, bir kullanıcı girdi cümlesi ile iki farklı doküman kesiti yer alıyor. Yazının devamında, bu girdinin retrieval sürecinde bu kesitlerle nasıl eşleştirildiğini ve bu eşlemenin nasıl çalıştığını adım adım inceleyeceğiz.
Örneklerimiz:
- Doküman Kesiti 1: Kendin gibi davran
- Doküman Kesiti 2: Göründüğü gibi değil
- Kullanıcı Girdisi: Olduğun gibi görün
Bu girdinin, vektör uzayında nasıl temsil edildiğini, hangi doküman kesitiyle ne ölçüde eşleştiğini ve bu süreçte neler olup bittiğini birlikte keşfedeceğiz.
Word Embeddings
Bir metindeki kelimeleri, sayısal temsillere (vektörlere) dönüştürmeden dil modelleriyle çalışmak mümkün değil. İşte burada devreye “word embedding” yani kelime yerleştirme yöntemleri giriyor. Embedding’ler, kelimeler arası anlam ilişkilerini ve bağlamları modelleyebilmemizi sağlar.
1. İstatistiksel Yaklaşım: TF-IDF
TF-IDF (Term Frequency–Inverse Document Frequency), klasik bir yöntemdir. Belirli bir belgede sık geçen ama tüm belgeler arasında nadir görülen kelimeleri öne çıkartır.
Örneğin bir sağlık makalesinde “kanser” sık geçiyorsa ve bu kelime genel metinlerde nadirse, TF-IDF bu kelimeye daha yüksek bir ağırlık verir. Ancak bu yöntem yalnızca kelimenin frekansına bakar, anlamı veya bağlamı yakalayamaz.
2. Prediction-Based Embeddings: Bağlamı Yakalamak
İstatistiksel yöntemlerden farklı olarak, bu yöntemler kelimeler arası anlamsal ilişkileri öğrenir. Yani kelimeleri yalnızca kaç kez geçtiğine göre değil, hangi kelimelerle birlikte geçtiğine göre değerlendirir.
Örneğin:
- Köpek yüksek sesle havlıyor.
- Köpek kuyruğunu sallıyor.
Bu iki cümlede “köpek”, “havlamak”, “kuyruk” gibi kelimeler arasında anlamsal bir ilişki vardır. Prediction-based yöntemler, bu bağlamları öğrenmede çok başarılıdır.
Popüler Prediction-Based Embedding Modelleri:
Word2Vec
Google tarafından geliştirilen bu modelin iki temel mimarisi vardır:
- CBOW (Continuous Bag of Words)
Cümledeki bağlam kelimelerden yola çıkarak hedef kelimeyi tahmin eder.
Örneğin: “Ben … kahve içerim.” → hedef: “her sabah” - Skip-Gram
Bu kez tersine çalışır; hedef kelimeden yola çıkarak çevresindeki bağlamı tahmin etmeye çalışır.
Örneğin: “kahve” kelimesinden → “içerim”, “sabah”, “seviyorum” gibi kelimeleri tahmin etmeye çalışır.
GloVe (Global Vectors for Word Representation)
Stanford tarafından geliştirilen bu yöntem, kelimelerin metin içinde ne sıklıkla birlikte geçtiğine odaklanır.
Word2Vec anlık bağlamlara (lokal) odaklanırken, GloVe tüm metin boyunca kelimeler arası ilişkileri analiz ederek daha global bir perspektif sunar.
FastText
Facebook tarafından geliştirilen bu model, Word2Vec’e benzer şekilde çalışır ancak önemli bir fark içerir:
FastText, kelimeleri sadece tek bir birim olarak değil, karakter seviyesinde alt parçalara (subword units) ayırarak işler.
Bu sayede model, kelimenin tamamını daha önce hiç görmemiş olsa bile, içindeki parçalardan anlam çıkarabilir.
Örneğin “koşuyorum” kelimesi modelin eğitim verisinde yer almasa bile, “koş”, “yor”, “rum” gibi parçalar üzerinden anlamını sezebilir.
Şimdi, yazımızın başında verdiğimiz örnekleri, yani “Kendin gibi davran”, “Göründüğü gibi değil” ve “Olduğun gibi görün” cümlelerini birer vektörle temsil edelim. Bu, kelimelerin sayısal temsillere dönüştürülmesini ve dil modelleriyle nasıl işlendiğini daha net bir şekilde gösterecek.
Örneklerimizdeki kelimelere basit bir word embedding uygulayalım ve her kelimenin vektörel temsilini 4 boyutlu bir vektörle gösterelim. Bu temsili daha basit bir düzeyde, her kelimenin nasıl aynı vektörle temsil edilebileceğini göstermek için yapacağız.

Bu tablodan görülebileceği gibi, aynı kelimeler (“gibi”) aynı vektörlerle temsil edilir. Bu vektörler, kelimelerin metin içindeki anlamlarını ve bağlamlarını öğrenebilmek için dil modeline verilen sayısal temsillerdir.
Artık kelimeleri tek başına değil, bağlamıyla birlikte temsil edebilen yöntemlere geçiyoruz. Bu yöntemler yalnızca kelime anlamını değil, tüm metnin bağlamsal anlamını yakalayabiliyor. İşte bu yüzden bu yöntemleri text embedding üretiminde sıklıkla kullanıyoruz.
Text Embeddings
Kelimeyi vektöre dönüştürmekle iş bitmiyor. O vektörün anlamı taşıyabilmesi lazım. İşte bu noktada text embedding dediğimiz daha rafine bir temsile ihtiyaç duyuyoruz.
Bu dönüşümde ilk adım bir encoder’ın devreye girmesi. Encoder, kelimeleri alıyor; onların dil içindeki semantik özelliklerine (yani anlam katmanlarına) göre yeniden düzenliyor. Vektörleri öylece bırakmıyoruz; üstüne bir de lineer dönüşüm ve ardından bir ReLU fonksiyonu ekliyoruz.
Peki neden?
Şöyle düşün: yazının başında kullandığımız 4 boyutlu vektörler sadece temsildi. Gerçek hayatta kelimeler 300, 768 hatta 1024 boyutlu vektörlerle temsil ediliyor.Kullandığımız encoder ne kadar karmaşık ve derin olursa, öğrenilen temsil de o kadar başarılı olur. BERT veya GPT gibi transformer tabanlı modellerde encoder katmanları, kelimenin bağlam içindeki rolünü öğrenmekte oldukça yetkindir. Ama bu kadar büyük vektörlerle çalışmak her zaman pratik olmuyor. Bu yüzden önce lineer bir dönüşümle bu büyük boyutu daha düşük boyutlu bir uzaya taşıyoruz. Yani bir bakıma sadeleştiriyoruz.
Ama burada bir sorun var: dil doğrusal (linear) bir yapı değil. Beklenmedik sıçramalar, iniş çıkışlar var. Mesela:
- “Yemeği sıcak yedim.”
- “Sıcak biriyle tanıştım.”
Aynı kelime, ama bambaşka anlamlar. İşte dildeki bu doğrusal olmayan yapıyı modelimize kazandırmak için ReLU gibi aktivasyon fonksiyonlarından faydalanıyoruz. ReLU, bu sadeleştirilmiş vektörlere biraz esneklik katıyor, böylece modelimiz anlamı kaçırmadan daha derin bağlamları da yakalayabiliyor.
Kısacası, encoder dilin anlamını çözmeye çalışıyor, lineer dönüşüm vektörü sadeleştiriyor, ReLU ise dile özgü o “doğrusal olmayan” yapıyı geri kazandırıyor. Bu üçlü birlikte çalıştığında, elimizde artık sadece bir kelime vektörü değil; kelimenin bağlam içindeki anlamı saklı bir text embedding oluyor.

Mean Pooling
Kelime bazlı embedding’leri çıkardık, her birini sayısal olarak temsil ettik, hatta dilin karmaşıklığını modelleyebilmek için encoder’la ReLU’dan da yardım aldık. Şimdi sıra, bu kelime vektörlerini bir araya getirip tek bir anlamlı cümle temsiline dönüştürmekte.
Peki nasıl yapacağız bunu?
İşte burada devreye Mean Pooling giriyor.
Bu yöntem aslında adından da anlaşılacağı gibi çok basit bir mantığa dayanıyor:
Cümledeki tüm kelime embedding’lerini al, her boyuttaki değerleri topla ve kelime sayısına böl.
Yani her bir boyuttaki sayının ortalamasını alıyoruz. Bunu yaparak cümlenin genel bir anlamını taşıyan tek bir vektör elde etmiş oluyoruz.
Bir kelimenin tek başına anlamı olabilir ama biz bir sorguya ya da belgeye bütünsel bir anlam kazandırmak istiyorsak, kelimeler arasındaki bağlamı da hesaba katmamız gerekir. Mean pooling, bu bağlamı ortalama üzerinden taşır. Karmaşık yapılarla uğraşmadan, cümleye ait ortak bir temsili hızlıca oluştururuz.
Tabii bu yöntem çok basit. Daha gelişmiş modeller, örneğin attention ağırlıklı yöntemler, hangi kelimenin daha önemli olduğunu da hesaba katar. Ama şimdilik, temel mantığı kavramak için mean pooling gayet yeterli.
Indexing
Bir cümlenin ya da kelimenin embedding’ini oluşturduğumuza göre, bu embedding’leri verimli bir şekilde arayıp bulmamız gerekiyor. Çünkü milyonlarca metin arasından doğru cevabı bulmak için hızlı erişim çok kritik.
İşte burada Indexing devreye giriyor.
Indexing, tıpkı bir kitap indeksine benzer şekilde, verileri organize edip onları hızlıca erişilebilir kılmak için kullanılır. Ama burada işler biraz daha karmaşık, çünkü biz kelimeleri değil, yüksek boyutlu vektörleri indeksliyoruz.
Her bir embedding, çok boyutlu bir vektör olduğu için, bu vektörlerin boyutları arasında anlamlı bir ilişki kurmamız gerekiyor. Yani, benzer anlamdaki vektörler birbirine yakın olmalı, uzak olanlar ise farklı anlamlar taşımalı. Bu ilişkileri kurabilmek için vektör veri tabanları kullanılır. Bu veri tabanları, vektörleri organize eder ve bunları aradığınızda çok hızlı bir şekilde döndürür.
Ne tür indexleme teknikleri var?
- Flat Indexing:
En basit yöntemlerden biri. Tüm vektörler bir arada tutulur ve arama yapıldığında tüm veri seti üzerinden benzerlik hesaplaması yapılır. Bu yöntem doğru olsa da, büyük veri setlerinde oldukça yavaş olabilir. - Approximate Nearest Neighbor (ANN):
Bu yöntem, daha verimli ve hızlı aramalar için kullanılır. ANN, verileri belirli bir düzene göre organize eder ve en yakın komşuları hızlıca bulur. Ancak bu, kesinlikle doğru sonuçlar vermez; yalnızca yakın olanları döndürür. Ama çoğu durumda bu yeterli olur ve çok daha hızlıdır. - HNSW (Hierarchical Navigable Small World):
Bu, en modern ve etkili indexing tekniklerinden biridir. Vektörler bir graf yapısında organize edilir ve hızlıca en yakın komşuları bulmamıza olanak tanır. HNSW, özellikle büyük veri setlerinde çok verimli çalışır.
Sonuç olarak, doğru indexleme yaparak, bilgi getirme (retrieval) sürecini hem hızlı hem de doğru bir şekilde gerçekleştirebiliriz. Vektörlerin doğru bir şekilde indekslenmesi, her şeyin temelini oluşturur, çünkü doğru verilere ne kadar hızlı ulaşabilirsek, modelimizin de doğru sonuçları o kadar hızlı verebiliriz.
Retrivial
Artık elimizde embedding’ler var, bu embedding’leri indeksledik, yani vektörleri düzgün bir şekilde organize ettik. Şimdi esas amacımıza, yani doğru bilgiyi hızlıca geri getirme (retrieval) sürecine odaklanalım.
Retrieval aşaması, sistemin soru-cevap dinamiği gibi çalışır. Kullanıcıdan bir sorgu alıyoruz ve bu sorguyu daha önce oluşturduğumuz vektörler ile eşleştiriyoruz. Hedefimiz, bu sorguya en uygun ve en anlamlı veriyi hızlıca bulmak.
Retrieval Nasıl Çalışır?
- Sorgu Embedding’i Oluşturma
İlk adım, kullanıcının gönderdiği sorguyu alıp, aynı şekilde embedding’e dönüştürmek. Yani, sorgu da kelimelerden oluştuğu için tıpkı dokümanlarda olduğu gibi bir vektör temsili oluşturuyoruz. Burada kullandığımız aynı encoder ve transformasyonlar, sorgunun da semantik anlamını vektörler aracılığıyla modelimize kazandırıyor. - Vektör Eşleştirmesi Yapma
Artık sorgu embedding’i ile veri tabanındaki doküman embedding’leri arasındaki benzerlik hesaplamalarını yapmamız gerekiyor. Bu adımda kosinüs benzerliği (cosine similarity) veya Euclidean mesafesi gibi metrikler kullanarak, sorguya en yakın vektörleri belirliyoruz. - En Yakın Komşuları Bulma
Buradaki temel soru şu: “Sorgu embedding’ine en yakın vektörler hangileridir?” Bu adımda, indeksleme yaparken kullandığımız ANN teknikleri devreye giriyor. Bu teknikler, sorgu ile veri tabanındaki vektörler arasındaki en yakın komşuları hızlıca bulmamızı sağlar. Yani, tıpkı en yakın arkadaşınızı bulmak gibi, veritabanındaki tüm embedding’ler arasından en yakın olanları seçiyoruz. - En İyi Sonuçları Döndürme
Son olarak, benzerlik oranlarına göre sıraladığımız dokümanları kullanıcıya sunuyoruz. Bu dokümanlar, sorguya en uygun olanlardan en az uygun olanlara doğru sıralanmış olur. Kullanıcı artık, en doğru cevaba çok daha hızlı erişmiş olur.
Özetle
Retrieval aşaması, bilgi bulma ve getirme sürecidir. Başarılı bir retrieval için veritabanındaki embedding’lerin doğru indekslenmesi ve sorgu ile olan benzerliğin doğru bir şekilde hesaplanması gerekir. Bu aşamanın hızlı ve verimli bir şekilde yapılması, dil modellerinin başarısı için kritik bir faktördür. Vektörleri doğru şekilde eşleştirerek ve hızlıca arama yaparak, kullanıcıya en doğru sonucu sunabiliriz.
Bir sonraki yazıda görüşmek üzere…