RAG nedir ve neden yerelde kurmalısınız?
Retrieval-Augmented Generation (RAG), büyük dil modellerinin (LLM) kurumsal veya özel verilerle beslendiğinde daha güncel, doğru ve izlenebilir cevaplar üretmesini sağlayan bir yaklaşım. Kısaca, önce vektör veritabanı üzerinden ilgili doküman parçalarını buluyor, sonra bu parçaları modelin istemine ekleyerek yanıt oluşturuyoruz. Yerel RAG ise verinizin cihazınızda kalmasına, maliyetin düşmesine ve düşük gecikme ile çalışmanıza olanak tanır. Bu yazıda Ollama, ChromaDB ve açık kaynak modellerle tamamen yerel bir RAG sistemi kuracağız.
Mimari ve gereksinimler
Mimari: (1) Gömme (embedding) modeli ile dokümanları vektörleştir, (2) ChromaDB’ye kaydet, (3) Soru geldiğinde en alakalı parçaları geri getir (retrieve), (4) LLM’e bu bağlamı vererek cevabı üret.
Gereksinimler: 8 GB+ RAM (tercihen 16 GB), modern CPU; GPU varsa daha iyi. macOS, Linux veya Windows üzerinde çalışabilir. Python 3.10+, ve terminal erişimi gerekir.
Kurulum: Ollama, model ve ChromaDB
1) Ollama kurulummacOS: brew install ollamaLinux: curl -fsSL https://ollama.com/install.sh | shWindows: Resmi MSI kurulum paketini indirip çalıştırın
Ardından servis: ollama serve
2) Modelleri indirollama pull llama3.1:8b-instructollama pull nomic-embed-text
Not: Kaynaklar kısıtlıysa daha ufak bir model (ör. llama3.2:3b-instruct) seçebilirsiniz. Embed modeli olarak mxbai-embed-large da iyi sonuç verir.
3) Python bağımlılıklarıpython -m venv .venv && source .venv/bin/activatepip install chromadb fastapi uvicorn pydantic
İsteğe bağlı: yeniden sıralama (re-ranking) için pip install sentence-transformers
Veri yükleme ve vektörleştirme
Dokümanlarınızı data/ klasörüne (PDF, TXT, MD) yerleştirdiğinizi varsayalım. Basitlik için düz metin örnekliyoruz. Üretim ortamında PDF parçalama (chunking) ve OCR katmanı düşünebilirsiniz.
Basit Python ingestorimport os, requests, uuid
import chromadb
from chromadb.utils import embedding_functions
OLLAMA_URL = "http://localhost:11434/api/embeddings"
EMBED_MODEL = "nomic-embed-text"
def embed_texts(texts):
vecs = []
for t in texts:
r = requests.post(OLLAMA_URL, json={"model": EMBED_MODEL, "input": t})
r.raise_for_status()
vecs.append(r.json()["embedding"])
return vecs
client = chromadb.PersistentClient(path="chroma_store")
collection = client.get_or_create_collection(name="docs", embedding_function=embed_texts)
def chunk(text, size=700, overlap=120):
out=[]; i=0
while i < len(text):
out.append(text[i:i+size])
i += size - overlap
return out
docs_dir = "data"
for fname in os.listdir(docs_dir):
path = os.path.join(docs_dir, fname)
if not os.path.isfile(path): continue
text = open(path, "r", encoding="utf-8").read()
chunks = chunk(text)
ids = [str(uuid.uuid4()) for _ in chunks]
metas = [{"source": fname} for _ in chunks]
collection.add(documents=chunks, metadatas=metas, ids=ids)
print("Indeksleme tamam.")
Sorgulama ve yanıt üretimi
Sorguda, ChromaDB’den en alakalı parçaları çekip bunları LLM istemine ekleyeceğiz. Ollama’nın üretim API’sini kullanacağız.
Basit sorgu/cevapimport requests
GEN_URL = "http://localhost:11434/api/generate"
def ask(query, k=4):
res = collection.query(query_texts=[query], n_results=k)
contexts = [d for d in res["documents"][0]]
sources = [m["source"] for m in res["metadatas"][0]]
context_block = "\\n\\n".join([f"[{i+1}] {c}" for i,c in enumerate(contexts)])
prompt = f"Kontekstten yararlanarak yanıtla. Bilgiyi uydurma. Kaynak numaralarını belirt.\\nKontekst:\\n{context_block}\\n\\nSoru: {query}\\nCevap:"
r = requests.post(GEN_URL, json={"model":"llama3.1:8b-instruct","prompt":prompt,"stream":False,"options":{"temperature":0.2}})
r.raise_for_status()
answer = r.json()["response"]
return answer, list(set(sources))
print(ask("Şirketimizin yedekleme politikası nedir?"))
FastAPI ile basit REST API
Uygulamanızı diğer servislerin kullanabilmesi için REST olarak sunabilirsiniz.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Q(BaseModel):
query: str
@app.post("/ask")
def api_ask(q: Q):
answer, sources = ask(q.query)
return {"answer": answer, "sources": sources}
# Çalıştır: uvicorn app:app --reload --port 8000
Doğrulama, kalite ve ölçüm
- Halüsinasyonları azaltmak için sıcaklığı 0.0–0.3 aralığında tutun, prompt’a “bilgiyi uydurma, bilmiyorsan söyle” ifadesini ekleyin.
- Geri getirilen parça sayısını (k) 3–8 arası deneyin; çok yüksek k, gürültü katar.
- Parça boyutu (chunk size) 500–1000 arası genelde iyi sonuç verir, 10–15% örtüşme koruyun.
- Yeniden sıralama: Sentence-Transformers ile cross-encoder/ms-marco-MiniLM-L-6-v2 gibi bir re-ranker, isabeti belirgin artırabilir.
- Değerlendirme: Küçük bir altın soru-cevap seti hazırlayın; doğru kaynağa referans verilip verilmediğini ölçün.
Performans ve maliyet ipuçları
- Kantizasyon: Ollama’da llama3.1:8b-instruct-q4_K_M gibi kantize varyantlar RAM tüketimini düşürür.
- Önbellek: Sorgu → bağlam → cevap üçlüsünü dosya veya Redis ile önbelleğe alın. Yinelenen sorularda gecikme dramatik düşer.
- GPU: Metal (macOS) veya CUDA (Linux/Windows) desteği varsa model çıkarımı hızlanır.
- İndeks: ChromaDB’de kalıcı depolama (PersistentClient) ile büyük koleksiyonlarda yeniden başlatma maliyeti azalır.
Güvenlik ve uyumluluk
Yerel RAG’in en büyük artısı veri egemenliği. Yine de şu tedbirleri alın: hassas alanları maskeyle; kaynak metaverileri log’layın; modeli “yanlış kullanım” prompt’larına karşı kıstırın; uç noktalara (FastAPI) kimlik doğrulama ekleyin; yedekleri şifreleyin.
Hata ayıklama ve sık görülen problemler
- Bağlantı hatası: Ollama servisinin 11434 portunda çalıştığını doğrulayın (curl localhost:11434).
- Out-of-memory: Daha küçük/quantize model çekin; eşzamanlı istekleri düşürün.
- Alakasız sonuçlar: Farklı embedding modeli deneyin; chunk’ları daha iyi bölün; re-ranker ekleyin.
- Dil karışması: Prompt’u Türkçe olarak sabitleyin ve cevabı Türkçe isteyin.
Sonuç
Bu rehberle, Ollama ve ChromaDB kullanarak tamamen yerelde çalışan, ölçeklenebilir ve gizlilik dostu bir RAG sistemi kurdunuz. Temeller oturduktan sonra re-ranking, çoklu koleksiyon, rol tabanlı erişim ve kullanım analitiği gibi katmanları ekleyerek üretim kalitesine taşıyabilirsiniz. Küçük bir dizüstü bilgisayarda bile tatmin edici yanıtlar alınabildiğini görmek, RAG’in 2025’te neden “uygulamaya dönük yapay zekânın” omurgası olduğunu net biçimde gösteriyor.