Retrieval-Augmented Generation (RAG)

Hibrit Aramayı Ustalaşmak: RAG Doğruluğu İçin Altın Standart

Getiri Güçlendirilmiş Üretim (RAG), büyük dil modellerinin (LLM) özel verilerle etkileşimini devrim niteliğinde değiştirdi. Ancak, tamamen anlamsal arama (vektör tabanlı) kritik bir kusura sahiptir: Spesifik tanımlayıcılar, özel isimler veya kesin teknik terimlerle başa çıkmakta zorlanır. RAG sistemine "Hata Kodu 40412" diye sorduğunuzda, bir vektör veritabanı genel 404 hatalarıyla veya ilgili olmayan "400 seviyesi" hatalarıyla ilgili sayfaları getirebilir, ancak nadiren ihtiyacınız olan kesin tanımı bulur.

Çözüm? Hibrit Arama.

Hibrit arama, vektör gömmeleminin bağlamsal anlayışını geleneksel anahtar kelime eşleştirmesinin (seyrek arama) hassasiyetiyle birleştirir. Bu iki yöntemi harmanlayarak, geri çağırma ve kesinliği önemli ölçüde artırır ve LLM'inizin her zaman en alakalı belgeleri getirmesini sağlar.

Neden Saf Vektör Arama Yetersiz Kalır

Vektör gömmelemeleri metnin anlamını yakalar. "Ucuz uçuşlar" ve "düşük maliyetli havayolu bileti"nin benzer olduğunu anlamakta mükemmeldirler. Ancak, kesin dize eşleştirmesinin olmadığı yüksek boyutlu bir uzayda çalışırlar.

  • Spesifiklik Eksikliği: Vektörler, "A Parçası" ve "B Parçası" benzer bağlamlarda görünüyorsa bunları ayırt edemez.
  • Tokenizasyon Sorunları: Benzersiz kimlikler, ürün kodları veya nadir özel isimler, eğitim verilerinde bağlamsal sıklık eksikliği nedeniyle kötü gömmeleme temsilcilerine sahip olabilir.
  • Geri Çağırma Boşlukları: Bir sorgu, hedef belgeden anlamsal olarak uzak ama sözlük açısından aynı olan bir anahtar kelime içeriyorsa, vektör araması bunu kaçırır.

Buna karşılık, geleneksel anahtar kelime araması (BM25 gibi) kesin eşleşmeleri bulmakta harikadır ancak niyeti anlamakta başarısız olur. Kelimeler örtüşmediği sürece "sızdıran bir boruyu nasıl onarılır" ile "musluklar için tesisat tamiri"nin ilgili olduğunu söyleyemez.

Hibrit Arama Mimarisi

Tipik bir hibrit arama boru hattı üç ana adımdan oluşur:

  1. Yoğun Getiri: Sorguyu gömmeleyin ve kosinüs benzerliğine dayalı olarak en iyi K sonucu getirin.
  2. Seyrek Getiri: Sözlüksel örtüşmeye (BM25) dayalı olarak en iyi K sonucu getirmek için geleneksel bir arama motoru kullanın (ör. Elasticsearch, PostgreSQL tam metin araması).
  3. Birleştirme: Sonuç kümelerini Reciprocal Rank Fusion (RRF) gibi bir sıralama algoritması kullanarak birleştirin.

Uygulama Örneği

Aşağıda, vektörler için LangChain ve Chroma ile basit bir BM25 uygulaması kullanan bir Python örneği verilmiştir. Üretim ortamında, seyrek bileşen için Elasticsearch veya OpenSearch kullanabilirsiniz.

import numpy as np
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_community.retrievers import ParentDocumentRetriever
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 1. Vektör Deposu Kurulumu (Yoğun Arama)
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_texts(texts, embeddings=embeddings)
vector_retriever = vectorstore.as_retriever(k=5)

# 2. Seyrek Arama Kurulumu (BM25)
# Not: Gerçek bir uygulamada, Elasticsearch veya TF-IDF/BM25 dizini kullanırdınız
def bm25_search(query, documents, top_k=5):
    # BM25 sıralama için sözde kod
    # (document_id, score) listesi döndürür
    pass

def reciprocal_rank_fusion(rank_lists, k=60):
    """
    Birden fazla sıralı listeyi tek bir sıralı listeye birleştirir.
    k, alt sıralı öğelerin etkisini azaltmak için bir sabittir (genellikle 60).
    """
    scores = {}
    for i, rank_list in enumerate(rank_lists):
        for rank, item in enumerate(rank_list, start=1):
            if item not in scores:
                scores[item] = 0
            scores[item] += 1.0 / (k + rank)
    
    # Skora göre azalan şekilde sırala
    return sorted(scores.items(), key=lambda x: x[1], reverse=True)

# 3. Hibrit Getirme Fonksiyonu
def hybrid_search(query, documents):
    # Vektör aramasından sonuçları al
    vector_results = vector_retriever.get_relevant_documents(query)
    vector_ids = [doc.metadata['id'] for doc in vector_results]
    
    # BM25'ten sonuçları al
    bm25_results = bm25_search(query, documents, top_k=5)
    bm25_ids = [res[0] for res in bm25_results]
    
    # Sonuçları birleştir
    fused_ids, fused_scores = reciprocal_rank_fusion([vector_ids, bm25_ids])
    
    # İlk 3 belgeyi döndür
    return fused_ids[:3]

Ayarlama İçin Pratik İpuçları

  • Ağırlıklandırma: Bir arama yöntemi alanınız için tarihsel olarak daha güvenilirse, RRF formülüne ağırlıklar uygulayabilirsiniz. Örneğin, teknik belgeler parça numaralarına büyük ölçüde güveniyorsa, seyrek aramaya daha yüksek ağırlık verin.
  • Gömmeleme Modelleri: Yoğun arama bileşeninin kalitesini en üst düzeye çıkarmak için daha yeni, yüksek performanslı gömmeleme modelleri kullanın (ör. text-embedding-3-large).
  • Dizinleme: Seyrek dizininizin optimize edildiğinden emin olun. Kısaltmaları ve çoğulları etkili bir şekilde işlemek için arama motoru yapılandırmanızda n-gramlar veya eş anlamlı listeler kullanın.

Sonuç

Hibrit arama, RAG sistemleri için artık isteğe bağlı bir iyileştirme değil; üretim düzeyinde uygulamalar için bir en iyi uygulamadır. Anlamsal anlayış ile sözlüksel hassasiyet arasındaki boşluğu doldurarak, hem sağlam hem de doğru bir getirme katmanı oluşturursunuz. Mevcut vektör ve anahtar kelime aramalarınızın basit bir RRF birleştirmesiyle başlayın, cevap kalitesindeki iyileşmeyi ölçün ve oradan itibaren iterasyon yapın. Sonuç, bir kavramın anlamını mı yoksa bir bileşenin kesin kimliğini mi soruyor olursa olsun, verilerinizi gerçekten anlayan bir sistem olacaktır.

Share: