ChromaDB etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
ChromaDB etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

10 Aralık 2025 Çarşamba

Ollama, LangChain ve ChromaDB ile Yerel RAG Chatbotu Kurulum Rehberi

Özet

Bu rehberde, internet bağlantısına ihtiyaç duymadan çalışan bir RAG (Retrieval-Augmented Generation) chatbotunu yerelde nasıl kurabileceğinizi adım adım anlatıyorum. Kullandığımız bileşenler: Ollama (yerel LLM çalıştırma), LangChain (zincirleme ve orkestrasyon), ChromaDB (vektör veritabanı) ve yerel gömlemeler. Amaç; PDF, teknik doküman veya notlarınızı indeksleyip, LLM modeline belgelerden alıntı yaparak daha doğru yanıtlar ürettirmek.

Neden Yerel RAG?

RAG yaklaşımı, dil modelinin yanıtlarını belgelerinizle zenginleştirerek halüsinasyonları azaltır ve güncel bilgi sağlar. İşin “yerel” tarafı ise verinin bilgisayarınızdan çıkmaması, maliyetin düşük ve sistemin offline çalışabilmesi demek. Özellikle kurumsal dokümanlar, Ar-Ge notları veya gizli veriler için bu yaklaşım idealdir.

Gereksinimler

- 16 GB RAM önerilir (8 GB ile küçük modeller çalışabilir).
- macOS, Linux veya Windows (WSL destekli).
- Python 3.10+.
- Temel terminal bilgisi.
- Bazı modellerde GPU varsa hız artar (Metal/CUDA desteği).

Adım 1: Ollama ve Modelleri Kurma

Ollama, LLM modellerini tek komutla indirip yerelde çalıştırmanızı sağlar. Sisteminizde kurulu değilse resmi talimatları izleyerek kurun. Linux için tipik kurulum şu şekildedir:

curl -fsSL https://ollama.com/install.sh | sh
# Servisi başlat (Linux)
ollama serve

Şimdi bir sohbet modeli ve bir gömleme modeli çekelim. Küçük ve hızlı bir sohbet modeli için Llama 3.1 8B iyi bir başlangıçtır. Gömlemeler için “nomic-embed-text” yaygın ve hızlıdır:

ollama pull llama3.1:8b
ollama pull nomic-embed-text

Model adlarını ihtiyacınıza göre değiştirebilirsiniz (örn. mistral veya phi-3). Büyük modeller daha iyi kalite, daha fazla RAM/GPU kullanımı demektir. İlk denemelerde 7B–8B aralığı pratik bir seçimdir.

Adım 2: Python Ortamını Hazırlama

Proje klasörünüzü oluşturup sanal ortam açın ve gerekli paketleri yükleyin. LangChain ile Ollama’nın entegrasyonu için “langchain-ollama” paketini kullanalım. Vektör veritabanı için Chroma’yı ekleyelim.

python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install --upgrade pip
pip install langchain langchain-community langchain-ollama chromadb pydantic

Basit metin dosyalarıyla başlayacağız. PDF’ler için ekstra dönüştürücüler (örn. pypdf, unstructured) ekleyebilirsiniz.

Adım 3: Belgeleri İndeksleme ve RAG Zinciri

Aşağıdaki örnekte, “docs/” klasöründeki metin dosyalarını parçalara ayırıp Chroma’ya yükleyeceğiz. Ardından bir sorgu geldiğinde ilgili parçaları geri çağırıp modelin bağlamıyla birlikte yanıtlamasını sağlayacağız.

# rag_app.py
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain.prompts import PromptTemplate
from langchain.schema import Document

# 1) Belgeleri yükle
loader = DirectoryLoader("docs", glob="**/*.txt", loader_cls=TextLoader, show_progress=True, use_multithreading=True)
docs = loader.load()

# 2) Parçala
splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=120)
chunks = splitter.split_documents(docs)

# 3) Gömleme ve vektör veritabanı
embeddings = OllamaEmbeddings(model="nomic-embed-text")
vectordb = Chroma.from_documents(chunks, embedding=embeddings, collection_name="yerel_rag")

# 4) Retriever ve LLM
retriever = vectordb.as_retriever(search_kwargs={"k": 4})
llm = ChatOllama(model="llama3.1:8b", temperature=0.2)

# 5) İstem şablonu
template = """Aşağıdaki bağlamı KESİNLİKLE dikkate alarak soruyu yanıtla.
Bağlam:
{context}

Soru: {question}
Cevap: """
prompt = PromptTemplate.from_template(template)

def ask(question: str):
    # İlgili parçaları getir
    rel_docs = retriever.get_relevant_documents(question)
    context = "\n\n".join([d.page_content for d in rel_docs])
    # İstemi oluştur ve yanıtı al
    final_prompt = prompt.format(context=context, question=question)
    return llm.invoke(final_prompt).content

if __name__ == "__main__":
    print(ask("Bu belgelerde performans optimizasyonu için öneriler neler?"))

Uygulamayı çalıştırmadan önce “docs/” klasörüne örnek metinler koymayı unutmayın. Eğer PDF kullanacaksanız “pypdf” ile yükleyebilir veya metne dönüştürüp aynı adımları uygulayabilirsiniz.

Performans ve Kalite İpuçları

Gömleme modeli seçimi: “nomic-embed-text” hızlı ve yeterli doğruluk sağlıyor. Çok dilli dokümanlarda “bge-m3” gibi çok dilli gömlemelere bakabilirsiniz.

Parça boyutu ve örtüşme: chunk_size=600–1200, chunk_overlap=80–200 aralığı pratik. Metin türüne göre ayarlayın. Uzun form teknik belgelerde daha büyük parçalar, soru-cevap notlarında daha küçük parçalar işe yarar.

Arama türü: Chroma varsayılan kosinüs benzerliği ile iyi çalışır. Farklı “k” değerlerini deneyin. Çok sayıda belge olduğunda metadata filtreleri eklemek doğruluğu artırır.

İstem mühendisliği: Şablona “Cevabın sonunda kaynak alıntısı ver” gibi kurallar eklemek kullanıcı güvenini artırır. Yanıt formatını (madde işaretleri, kısa özet + detaylar) açıkça belirtin.

Model ve nicemleme: Ollama üzerinde “:q4_0” gibi nicemlenmiş sürümler daha az RAM kullanır ve hızlanır; kalite az da olsa düşebilir. GPU mevcutsa GPU kullanımını etkinleştirmek büyük fark yaratır.

Güvenlik ve Gizlilik

Yerel RAG’in en önemli avantajı verilerin cihazınızda kalmasıdır. Ancak indeks dizininizi şifreli disk üzerinde tutmak, yedekleri güvenli almak ve işletim sistemi düzeyinde erişim izinlerini doğru ayarlamak gerekir. Paylaşılan makinelerde servis portlarını dışa açmayın.

Sorun Giderme

- “Connection refused”: Ollama servisi çalışmıyor olabilir. “ollama serve” komutunu kontrol edin.
- “CUDA/Metal hataları”: Sürücü/güncelleme gerekli olabilir. Geçici olarak CPU ile deneyin.
- “Bellek yetersiz”: Daha küçük model deneyin (ör. 3B–7B) veya nicemlenmiş varyant çekin.
- “Cevaplar ilgisiz”: chunk_size ve k değerlerini ayarlayın, gömleme modelini değiştirin, istemi netleştirin.

Sonuç

Bu kurulumla, Ollama + LangChain + Chroma üçlüsü sayesinde tamamen yerel çalışan bir RAG chatbotu elde ettiniz. Küçük boyutlu bir modelle bile belgeye dayalı arama ve yanıt üretiminde tatmin edici sonuçlar alabilirsiniz. Zamanla daha iyi gömlemeler, gelişmiş istem şablonları ve daha hızlı modellerle doğruluğu ve hızı artırabilirsiniz. Sonraki adım olarak bir REST API ekleyip (ör. FastAPI) web arayüzü veya Slack/Teams entegrasyonu kurmayı düşünebilirsiniz.

24 Ekim 2025 Cuma

Yerel LLM ile RAG: Ollama + LangChain + ChromaDB ile Türkçe Soru-Cevap Sistemi Kurulumu (2025 Rehberi)

RAG nedir, neden yerel?

RAG (Retrieval-Augmented Generation), büyük dil modellerini (LLM) kendi verinizle güçlendirmenin en pratik yollarından biridir. Model, önce vektör veritabanından ilgili pasajları arar (retrieval), ardından yanıtı bu pasajları referans alarak üretir (generation). Bu yaklaşım, hem doğruluk hem de güncellik sağlar. Yerel (on-prem/edge) kurulum ise hassas veriyi dışarı çıkarmadan çalıştığı için KVKK uyumu, gecikme ve maliyet açısından avantajlıdır.

Mimari genel bakış

Ollama yerel LLM’i (ör. Qwen2.5 7B) çalıştırır, LangChain iş akışını yönetir, ChromaDB vektör veritabanı olarak belgeleri tutar, Sentence-Transformers ise Türkçe uyumlu gömme (embedding) üretir. Sorgu akışı: Kullanıcı sorusu → Embedding → Chroma’dan benzer parçaların bulunması → Seçilmiş LLM ile bağlamsal yanıt.

Gereksinimler ve ortam

- İşletim sistemi: macOS, Linux veya WSL2’li Windows
- Python 3.10+
- 16 GB RAM önerilir (8 GB ile quantize modeller çalışır).
- GPU hızlandırma varsa avantajlı; yoksa 4-bit quantize modelleri tercih edin.

Kurulum adımları

1) Ollama’yı kurun ve modeli çekin:
curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen2.5:7b
Qwen2.5 çok dilli yapısıyla Türkçe’de başarılıdır. Daha hafif bir seçenek gerekiyorsa qwen2.5:3b veya llama3.1:8b-instruct da tercih edilebilir.

2) Python ortamını hazırlayın:
python -m venv .venv && source .venv/bin/activate
pip install langchain langchain-community chromadb sentence-transformers pypdf fastapi uvicorn
Embedding için Türkçe’de güçlü bir seçenek: intfloat/multilingual-e5-base veya sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2.

Veri hazırlama ve indeksleme

Belgelerinizi data/ klasörüne koyun (PDF, TXT, MD). PDF’ler için pypdf ile metin çıkarabilirsiniz. Amaç, büyük belgeleri 500–1000 karakterlik, 50–100 karakter örtüşmeli parçalara ayırmaktır. Bu sayede arama daha isabetli olur ve bağlam penceresini verimli kullanırsınız.

Örnek akış (özet):
- Belgeleri yükle: PDF/TXT okuma
- Parçala: 800 karakter, 120 örtüşme
- Embedding üret: multilingual-e5-base
- ChromaDB’ye yaz: kalıcı (persist) bir dizinde tut

Basit bir betik iskeleti:
from langchain_community.document_loaders import PyPDFLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings

loader = PyPDFLoader("data/rapor.pdf")
docs = loader.load()

splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=120)
chunks = splitter.split_documents(docs)

emb = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-base")
vect = Chroma.from_documents(chunks, emb, persist_directory="chroma_store")
vect.persist()

Arama + üretim zinciri

LangChain ile basit bir RAG zinciri kurabilirsiniz. Retriever’ı Chroma’dan oluşturun, Ollama LLM’i bağlayın ve istem (prompt) şablonu ile bağlamı enjekte edin. MMR (Maximal Marginal Relevance) ve top_k gibi ayarlarla oynayarak tekrar eden içerikleri azaltın ve çeşitliliği artırın.

Örnek sorgulama iskeleti:
from langchain_community.llms import Ollama
from langchain.prompts import PromptTemplate

vect = Chroma(persist_directory="chroma_store", embedding_function=emb)
retriever = vect.as_retriever(search_type="mmr", search_kwargs={"k": 5, "fetch_k": 20})

llm = Ollama(model="qwen2.5:7b", temperature=0.2)
template = ("Aşağıdaki bağlama dayanarak Türkçe, kaynaklara sadık ve kısa bir yanıt ver. "
"Bağlam:\n{context}\n\nSoru: {question}\nYanıt:")
prompt = PromptTemplate.from_template(template)

docs = retriever.get_relevant_documents("2024 finansal özet nedir?")
context = "\n\n".join([d.page_content for d in docs])
print(llm.invoke(prompt.format(context=context, question="2024 finansal özet nedir?")))

Doğruluk ve optimizasyon

- Chunk boyutu: 600–1000 karakter arası pratik. Daha küçük parça daha hassas arama, daha fazla parçayı LLM’e göndermek demektir. Bağlam penceresiyle dengeleme yapın.
- Reranker: GPU’nuz varsa bge-reranker-large gibi çapraz-encoder modeller ekleyerek bağlam kalitesini artırın.
- Top-k: 3–8 arası iyi bir başlangıç. Soru karmaşıksa artırın.
- Sıcaklık (temperature): 0.1–0.3 arası daha tutarlı, kaynaklara sadık yanıt sağlar.
- GYS/Değerlendirme: Küçük bir altın veri kümesi ile doğruluk ölçün. RAGAS gibi metriklerle bağlamsal doğruluğu takip edin.

Üretimde çalıştırma

Basit bir API için FastAPI idealdir. İsteğe göre streaming açarak ilk token’ı daha hızlı iletebilirsiniz. Chroma’yı kalıcı dizinle (persist_directory) başlatın ve yalnızca “okuma” modunda koşturun. Döküman güncellemeleri için zamanlanmış yeniden indeksleme (ör. günlük) stratejisi belirleyin.

Örnek uç nokta iskeleti:
from fastapi import FastAPI
app = FastAPI()

@app.get("/ask")
def ask(q: str):
  docs = retriever.get_relevant_documents(q)
  ctx = "\n\n".join(d.page_content for d in docs)
  ans = llm.invoke(prompt.format(context=ctx, question=q))
  return {"answer": ans}

uvicorn main:app --reload

Güvenlik, maliyet ve lisans notları

- Veri gizliliği: PII içeren alanları maskeleyin; loglarda ham sorgu ve belgeleri tutmayın. Diskte Chroma klasörünü şifreli bir birimde saklayın.
- Lisans: Kullandığınız model ve embedding lisansını kontrol edin; ticarî kullanımlarda kısıtlar olabilir.
- Maliyet: Yerel kurulum bulut token maliyetini düşürür, ancak donanım kaynağına ihtiyaç duyar. 4-bit quantize modeller düşük RAM’de dengeli performans sağlar.

Sorun giderme

- Yavaş yanıt: Embedding modelini daha hafife çekin (MiniLM), top_k’yı düşürün, quantize LLM kullanın.
- Alakasız bağlam: Chunk boyutunu artırın, MMR’ı açın, gerekirse reranker ekleyin.
- Bozuk indeks: chroma_store klasörünü temizleyip yeniden indeksleyin; gömme modelini değiştirdiyseniz indeksin de değişmesi gerekir.
- Hallüsinasyon: Prompt’a “Kaynak verilmeyen bilgiyi üretme” kuralını ekleyin, temperature’ı düşürün ve bağlamı zenginleştirin.

Sonuç

Bu rehberde Ollama + LangChain + ChromaDB ve çok dilli embedding’lerle yerel bir Türkçe RAG sistemi kurmanın hızlı yolunu gördünüz. Doğru chunking, iyi bir retriever ve tutarlı istem tasarımıyla, Türkçe dokümanlarınıza dayalı güvenilir bir soru-cevap deneyimi sağlayabilirsiniz. İhtiyaca göre model boyutunu, indeks ayarlarını ve dağıtım mimarisini optimize ederek sistemi üretim kalitesine taşıyın.

29 Eylül 2025 Pazartesi

Ollama ve ChromaDB ile RAG: Kendi Verinizle Yerel Yapay Zekâ Sohbet Botu Nasıl Kurulur?

RAG nedir ve neden önemli?

Retrieval-Augmented Generation (RAG), bir dil modelinin cevap üretmeden önce bir vektör veritabanından ilgili parçaları geri çağırdığı, bu sayede daha doğru ve kaynaklı yanıtlar ürettiği bir yaklaşımdır. Güncel kurumsal ihtiyaçlarda gizlilik, maliyet kontrolü ve özelleştirme kritik hale geldiği için RAG, özellikle şirket içi dokümanlar, bilgi tabanları ve politikalar üzerinde çalışan sohbet botları için en verimli yöntemlerden biri olarak öne çıkıyor.

Bu rehberde, tamamen yerel çalışan bir kurulumla Ollama (yerel LLM çalıştırma), ChromaDB (vektör veritabanı) ve Python kullanarak adım adım bir RAG sistemi kurulumu yapacağız. Amaç, Türkçe metinlerle yüksek doğrulukta, düşük gecikmeli ve veri gizliliği korunan bir sohbet deneyimi sunmak.

Gerekenler ve mimari

Bileşenler: Ollama (Llama 3 veya benzeri açık kaynak model), ChromaDB (kalıcı vektör deposu), bir gömme (embedding) modeli (örn. intfloat/multilingual-e5-base), Python 3.10+, LangChain veya minimal kendi kodunuz. İsteğe bağlı olarak PDF/Word dosyaları için pypdf veya docx desteği ekleyebilirsiniz.

Akış: Dokümanları parçalara ayır → Embedding ile vektörleştir → ChromaDB’de indeksle → Soru geldiğinde benzer parçaları getir → Model için talimat şablonuna (prompt) enjekte et → Yanıtı oluştur ve kaynakları göster.

Kurulum adımları

1) Ollama’yı kurun. Resmi site üzerinden işletim sisteminize uygun paketi indirin. Model indirmek için komut satırında şu adımı uygulayın:
ollama pull llama3
Ardından test amaçlı kısa bir deneme yapabilirsiniz:
ollama run llama3

2) Python ortamını hazırlayın. Ayrı bir sanal ortam tercih edin:
python -m venv .venv && source .venv/bin/activate (Windows için .venv\Scripts\activate)
pip install chromadb sentence-transformers langchain langchain-community pypdf

Veri hazırlığı: parçalama ve temizleme

İyi bir RAG’in temeli, doğru parça boyutları ve temiz veridir. Türkçe belgelerde 300–500 token’lık parçalar pratikte iyi sonuç verir. Parçaları ayırırken başlık bilgilerini ve içerik konusunu korumaya çalışın. Örneğin bir politika belgesinde bölüm başlığını her parçaya meta veri olarak ekleyin. Bu, hem geri çağırmayı hem de kaynakları kullanıcıya göstermeyi kolaylaştırır.

Temizlik aşamasında gereksiz boşlukları, tekrar eden sayfa altbilgilerini ve tablo görsellerinden gelen çöp metinleri temizleyin. PDF okuyucu olarak pypdf kullanabilir, Markdown veya HTML dokümanlarını doğrudan metne dönüştürebilirsiniz.

ChromaDB ile vektör indeksleme

Embedding için çok dilli ve Türkçe performansı yüksek bir model seçin. “intfloat/multilingual-e5-base”, hız/doğruluk dengesiyle güvenilir bir tercih. Basit bir akış şöyle olabilir: Belgeleri oku → Böl → Her parça için embedding hesapla → ChromaDB’ye “persist_directory” ile kalıcı olarak yaz. Bu sayede uygulama yeniden başladığında indeksi tekrar oluşturmadan kullanabilirsiniz.

Koleksiyonlarınızı konuya göre ayırın (örn. “insan_kaynaklari”, “urun_dokumantasyonu”). Meta veriye kaynak adı, sayfa numarası, bölüm ve tarih gibi alanlar eklemek, yanıtların izlenebilirliğini artırır.

Sorgulama: RAG adım adım

Kullanıcıdan gelen soruyu önce bir sorgu embedding’ine dönüştürün, ardından ChromaDB’den en ilgili 3–5 parçayı çekin. Bu parçaları modelinize şu yapıda verin: kısa bir talimat + kullanıcı sorusu + “bağlam” bölümü (geri çağrılan parçalar). Örnek şablon yaklaşımı: “Aşağıdaki bağlamdan faydalanarak soruya kısa ve kaynaklı bir yanıt ver. Bağlamda yoksa tahmin yürütme.”

Ollama tarafında llama3 modelini çağırırken sıcaklık (temperature) düşük (0.1–0.3) tutulduğunda halüsinasyon azalır. Yanıtın sonuna “Kaynaklar” başlığı ile geri çağrılan parçaların referanslarını eklemek, güven inşa eder ve SEO açısından “uzman” hissiyatı yaratır.

İyileştirme: yeniden sıralama ve çoklu sorgu

Bazı senaryolarda temel benzerlik araması yeterli olmaz. Açık kaynak yeniden sıralayıcılar (örn. bge-reranker-large) ile ilk 20 sonucu alıp en iyi 5’ini rerank ederek doğruluğu yükseltebilirsiniz. Ayrıca multi-query tekniği ile kullanıcı sorusunu farklı biçimlerde genişletip (eş anlamlılar, farklı bağlamlar) birleştirilmiş sonuçlar elde etmek de hatırlamayı artırır.

Soru ön-işleme katmanında yazım hatalarını düzeltmek, alan terimlerini sözlükten normalleştirmek ve tarih-sayı gibi varlıkları standart forma getirmek, özellikle kurumsal dokümanlarda fark yaratır. Halüsinasyonları azaltmak için “sadece bağlamdan yanıt ver, bağlam yoksa ‘yok’ de” gibi net kurallar koyun.

Performans, güvenlik ve üretime alma

CPU ile başlayıp gerekirse GPU’ya geçin. Düşük bellekli sistemlerde quantized (örneğin Q4_0) model varyantları iyi sonuç verir. ChromaDB tarafında kalıcı dizin SSD üzerinde olmalı ve düzenli olarak koleksiyon boyutu ile gecikmeyi izleyin. Top_k değerini 3–8 arasında test ederek doğruluk/performans dengesini bulun.

Üretim ortamında bir FastAPI uç noktası ile sorgulama zincirinizi sunabilirsiniz. Yanıtları ve kullanılan kaynakları log’layarak kalite ölçümü yapın. Kişisel veriler içeren dokümanlarda yerel çalışmanın avantajı büyüktür; ağ dışına veri çıkarmadan kurumsal uyumluluk hedeflerine yaklaşabilirsiniz.

Sonuç

Ollama + ChromaDB ile kurulan yerel RAG yığını, maliyeti düşük, gizliliği yüksek ve yönetilebilir bir yapay zekâ çözümü sunar. Doğru parça boyutu, iyi bir embedding modeli ve dikkatli şablonlama ile Türkçe içerikte dahi oldukça isabetli yanıtlar elde edebilirsiniz. Bu rehberi temel alarak önce küçük bir pilot oluşturun, ardından veri kapsamını ve değerlendirme metriklerini (doğruluk, geri çağırma, MRR) aşamalı olarak genişletin. Böylece güncel ve ileri seviye bir deneyimi, tamamen kendi verinizle kontrol ederek hayata geçirebilirsiniz.

9 Eylül 2025 Salı

Ollama ve ChromaDB ile Yerel RAG Sistemi Kurulumu: Adım Adım Geliştirici Rehberi (2025)

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 kurulum
macOS: brew install ollama
Linux: curl -fsSL https://ollama.com/install.sh | sh
Windows: Resmi MSI kurulum paketini indirip çalıştırın
Ardından servis: ollama serve

2) Modelleri indir
ollama pull llama3.1:8b-instruct
ollama 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/activate
pip 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 ingestor
import 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/cevap
import 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.