RAG Sistemi Nedir?
RAG (Retrieval-Augmented Generation), büyük dil modellerinin (LLM) bilgi tabanlarından ilgili verileri çekerek daha doğru ve güncel yanıtlar üretmesini sağlayan bir mimari yaklaşımdır. Geleneksel LLM'ler yalnızca eğitim verilerine dayanırken, RAG sistemi harici bilgi kaynaklarını sorgu anında modele sunarak halüsinasyonları azaltır ve güncel bilgiye erişim sağlar.
Bir RAG sistemi temelde üç ana bileşenden oluşur:
- Retrieval (Geri Getirme): Kullanıcı sorgusuna en uygun dokümanları vektör veritabanından çekme
- Augmentation (Zenginleştirme): Çekilen dokümanları prompt'a bağlam olarak ekleme
- Generation (Üretim): LLM'in bu zenginleştirilmiş bağlamla yanıt üretmesi
RAG Mimarisi: Bileşenler ve Veri Akışı
Bir RAG sistemi kurarken verilerin işlenme sürecini iki ana aşamada düşünebiliriz: indeksleme aşaması ve sorgu aşaması.
1. İndeksleme Aşaması
Bu aşamada dokümanlar parçalara ayrılır, vektörlere dönüştürülür ve bir vektör veritabanına yazılır. Doküman parçalama (chunking) stratejisi, sistemin başarısını doğrudan etkileyen kritik bir karardır.
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
# Dokümanları parçalara ayırma
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=512,
chunk_overlap=64,
separators=["\n\n", "\n", ". ", " ", ""]
)
chunks = text_splitter.split_documents(documents)
# Embedding modeli ile vektörlere dönüştürme
embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")
# Vektör veritabanına yazma
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embedding_model,
persist_directory="./chroma_db"
)
Burada chunk_size ve chunk_overlap parametreleri çok önemlidir. Çok küçük parçalar bağlam kaybına, çok büyük parçalar ise gürültüye neden olur. Genel bir kural olarak 256-1024 token arası chunk boyutları iyi sonuç verir.
2. Sorgu Aşaması
Kullanıcı bir soru sorduğunda, bu soru aynı embedding modeli ile vektöre dönüştürülür ve vektör veritabanında benzerlik araması yapılır:
from langchain_community.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
# Retriever oluşturma
retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={"k": 5}
)
# LLM ile zincir kurma
llm = ChatOpenAI(model="gpt-4o", temperature=0)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
# Sorgu çalıştırma
result = qa_chain.invoke({"query": "RAG sistemlerinde chunk boyutu nasıl belirlenir?"})
print(result["result"])
Gelişmiş RAG Teknikleri
Hybrid Search (Hibrit Arama)
Yalnızca vektör benzerliği (semantic search) kullanmak her zaman yeterli olmaz. Özellikle teknik terimler, ürün kodları veya özel isimler söz konusu olduğunda anahtar kelime tabanlı arama (BM25) ile vektör aramasını birleştirmek çok daha iyi sonuçlar verir.
from langchain.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever
# BM25 (anahtar kelime tabanlı) retriever
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 5
# Vektör tabanlı retriever
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
# Hibrit retriever: her iki yöntemi birleştir
hybrid_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.4, 0.6]
)
Re-Ranking (Yeniden Sıralama)
İlk arama sonuçlarını bir cross-encoder modeli ile yeniden sıralamak, en alakalı dokümanların üstte yer almasını sağlar. Bu adım hesaplama maliyetini artırsa da doğruluğu önemli ölçüde yükseltir:
from sentence_transformers import CrossEncoder
reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")
# İlk arama sonuçlarını al
initial_docs = hybrid_retriever.get_relevant_documents(query)
# Yeniden sırala
pairs = [(query, doc.page_content) for doc in initial_docs]
scores = reranker.predict(pairs)
# Skora göre sırala ve en iyi 3'ü al
ranked_docs = [doc for _, doc in sorted(zip(scores, initial_docs), reverse=True)][:3]
Contextual Compression
Getirilen dokümanların tamamı her zaman soruyla ilgili olmayabilir. Contextual compression tekniği, çekilen parçalardan yalnızca soruyla ilgili kısımları ayıklayarak LLM'e daha temiz bir bağlam sunar ve token maliyetini düşürür.
Vektör Veritabanı Seçimi
RAG sisteminin performansı büyük ölçüde vektör veritabanı seçimine bağlıdır. Yaygın kullanılan seçenekler:
- Chroma: Hafif, yerel geliştirme için ideal, hızlı prototipleme
- Pinecone: Tam yönetilen bulut servisi, ölçeklenebilir
- Weaviate: Açık kaynak, hibrit arama desteği yerleşik
- Qdrant: Yüksek performanslı, Rust tabanlı, filtreleme özellikleri güçlü
- pgvector: PostgreSQL eklentisi, mevcut veritabanı altyapısıyla entegrasyon kolaylığı
Küçük ve orta ölçekli projeler için Chroma veya pgvector iyi bir başlangıç noktasıdır. Üretim ortamında yüksek ölçeklenebilirlik gerekiyorsa Pinecone veya Qdrant değerlendirilmelidir.
Değerlendirme ve Metrikler
RAG sisteminin kalitesini ölçmek için iki boyutlu değerlendirme yapılmalıdır:
- Retrieval kalitesi: Doğru dokümanlar getiriliyor mu? Precision@k, Recall@k ve MRR (Mean Reciprocal Rank) metrikleri kullanılır.
- Generation kalitesi: Üretilen yanıt doğru ve tutarlı mı? Faithfulness (sadakat), answer relevancy (yanıt ilgililik) ve hallucination rate (halüsinasyon oranı) ölçülür.
RAGAS kütüphanesi bu metrikleri otomatik olarak hesaplamak için kullanışlı bir araçtır:
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision
result = evaluate(
dataset=eval_dataset,
metrics=[faithfulness, answer_relevancy, context_precision]
)
print(result)
Üretim Ortamı İçin Pratik Öneriler
- Metadata filtreleme: Her chunk'a kaynak, tarih ve kategori gibi metadata ekleyin. Sorgu sırasında bu alanlarla filtreleme yaparak arama alanını daraltın.
- Önbellek (cache): Sık sorulan sorguların sonuçlarını önbellekleyerek hem maliyet hem gecikme süresini azaltın.
- Chunk stratejisini test edin: Farklı chunk boyutları ve overlap değerleri ile A/B testleri yapın; veri türüne göre optimal ayarlar değişir.
- Guardrails ekleyin: LLM'in yalnızca sağlanan bağlama dayanarak yanıt vermesini, bilmediği konularda "bilgim yok" demesini sağlayan sistem prompt'ları kullanın.
- Kaynak gösterimi: Yanıtla birlikte kaynak dokümanları kullanıcıya sunarak şeffaflık ve güvenilirlik sağlayın.
- İzleme ve loglama: Her sorgu için getirilen dokümanları, LLM giriş/çıkışını ve gecikme sürelerini kaydedin. Bu veriler iteratif iyileştirme için çok değerlidir.
Sonuç
RAG, büyük dil modellerini kurum içi veya alan özelinde bilgiyle güçlendirmenin en etkili yollarından biridir. Doğru chunking stratejisi, uygun embedding modeli, hibrit arama ve re-ranking gibi gelişmiş tekniklerin bir arada kullanılmasıyla yüksek kaliteli bir soru-cevap sistemi inşa etmek mümkündür. Önemli olan, sistemi sürekli ölçmek ve geri bildirimlerle iteratif olarak iyileştirmektir.