Temel RAG Uygulaması: Adım Adım Rehber
Yeni başlayanlara uygun bu rehber, temel bir RAG uygulamasının nasıl çalıştığını açıklıyor, en iyi yöntemleri ele alıyor ve Python, ChromaDB ile Perplexity'nin gömme ve dil modellerini kullanarak çalışan bir komut satırı RAG sistemi oluşturma sürecinde adım adım yol gösteriyor.

RAG, modern LLM tabanlı altyapının temel bileşenlerinden biridir. Yapay zeka modellerinin harici verilere erişmesini sağlayarak halüsinasyonlar ve eksik eğitim verileri gibi sorunların giderilmesine yardımcı olur. Ayrıca şirketlerin hassas veya özel bilgiler içeren dahili bilgi tabanlarını kullanabilmesini mümkün kılar.
RAG uygulaması çok karmaşık olabilir. Ancak temel bir RAG sistemi kurmak şaşırtıcı derecede kolaydır. Yeni başlayanlar için basit bir mimari oluşturmak, RAG'ın gerçek dünyada nasıl çalıştığını anlamaya yardımcı olabilir ve sonraki denemeler için bir sıçrama tahtası sağlayabilir.
Bu makalede temel bir RAG uygulamasının ana hatlarını çizecek, en iyi yöntemleri ele alacak ve ardından Python'u, ChromaDB'yi ve gömme ile yanıt üretimi için iki Perplexity modelini kullanarak çalışan bir sistem oluşturacağız.
Temel RAG uygulama süreci: Genel bakış
Temel bir RAG sisteminin üç ana bileşeni vardır: bir orkestratör, bir bilgi kaynağı ve bir LLM. Tipik bir iş akışında kullanıcı bir istem girer ve orkestratör, bağlı bilgi kaynaklarında arama yapmak için bu istemi değiştirir. Ardından getirilen bilgiler özgün girdi bağlamına eklenir ve bir yanıt üretilebilmesi için LLM'e gönderilir.
RAG uygulamanızı oluştururken şu adımları hesaba katmanız gerekir:
- Dizinleme ve gömme: Bu aşamada belgeleriniz, orkestratörün arama yapabileceği bir bilgi kaynağına dönüştürülür. Bunu yapmanın en yaygın yollarından biri, aranabilir bir vektör dizini oluşturmaktır. Belge parçalarınızı gömmelere dönüştürmek için Perplexity'nin bu iş için özel olarak geliştirilmiş bir modelini kullanacağız. Ardından gömmeleri, popüler bir açık kaynaklı vektör veritabanı olan ChromaDB ile depolayacağız.
- Orkestrasyon: Bu, harici bilgi kaynağı (bizim örneğimizde bir vektör veritabanı) ile LLM arasında yer alan uygulamadır. Orkestratör görevi görmesi için basit bir Python betiği oluşturacağız.
- Getirme ve üretme: Kullanıcı sohbet arayüzü üzerinden bir soru sorduğunda orkestratör bu soruyu alır, bir vektör araması çalıştırır ve genişletilmiş girdiyi LLM'e iletir. Özel bir ön yüz oluşturmak yerine Python orkestratörümüzle iletişim kurmak için komut satırını kullanacağız.
En iyi yöntemler: Bir RAG uygulamasını etkili kılan nedir?
Birden çok RAG mimarisi türü vardır ve her kullanım senaryosu farklı yaklaşımlar gerektirir. Bununla birlikte, bazı en iyi yöntemler her durumda geçerlidir ve doğru, uygun maliyetli, ölçeklenebilir ve bakımı kolay sistemler elde edilmesini sağlar.
Aşağıdaki en iyi yöntemler tüm RAG uygulaması türleri için geçerlidir:
- Temiz bir veri alımı işlem hattı oluşturun: Kaynak verileriniz dizinlemeden önce olabildiğince temiz olmalıdır. Ayrıca içeriğinize uygun bir gömme modeli kullanmalısınız.
- Hibrit arama kullanın: Vektör veritabanı araması, API tabanlı web araması, bilgi grafiği taraması, anahtar kelime araması veya başka yöntemler olsun, en iyi getirme yöntemleri kullanım senaryosuna göre değişir. Maliyetleri en aza indirmek için doğru karışımı seçmek önemlidir.
- Sisteminizi değerlendirin: Uygulamadan sonra sisteminizi üç temel ölçüte göre değerlendirmelisiniz: doğruluk, alaka düzeyi ve gecikme. Doğruluk, bilgilerin olgusal açıdan doğru olmasını; alaka düzeyi, getirilen bilgilerin kullanıcı sorgularına ne kadar uygun olduğunu; gecikme ise bilgilerin ne kadar hızlı getirildiğini ifade eder.
- Bilgileri güvenli şekilde işleyin: RAG sisteminiz özel dahili bilgilerden yararlanıyorsa bu bilgilerin güvenli şekilde depolandığından ve sistem arayüzüne erişimin yönetildiğinden emin olun. API anahtarları asla paylaşılmamalıdır.
Temel RAG uygulaması: 7 adımlık rehber
Bu rehberde tek bir belgeyle ilgili soruları yanıtlayan bir komut satırı uygulaması oluşturacağız. Python, ChromaDB ve Perplexity API'sini kullanacağız.
Amaç, üretime hazır bir RAG sistemi oluşturmak değil. Bu, temel bir RAG mimarisinin pratikte nasıl çalıştığını göstermek için tasarlanmış, yeni başlayanlara uygun bir rehberdir.
Adım 1: Yazılımları yükleyin
Bilgisayarınızda aşağıdakilerin yüklü olduğundan ve bir Perplexity API hesabınız bulunduğundan emin olun:
- Python: Gömme modeli, ChromaDB ve Perplexity arasındaki veri akışını koordine edecek orkestratörü oluşturmak için kullanacağımız programlama dilidir.
- Visual Studio: Kod düzenleyici olarak Visual Studio'yu kullanacağız. Yükledikten sonra Extensions panelini açın ve Python uzantısını indirin.
- Perplexity API hesabı: Perplexity hem gömme modelini (verilerinizi vektör gömmelerine dönüştüren model) hem de genişletilmiş istemi işleyecek LLM'i sağlayacaktır. Bunun için ücretli bir hesaba ihtiyacınız yok, ancak az miktarda kredi harcanacaktır.
Adım 2: Bir proje klasörü oluşturun
İlk olarak rag-project adlı bir klasör oluşturun ve File > Open Folder seçeneğini belirleyerek bu klasörü VS Code'da açın. Ardından entegre terminali şu yolla açın: Terminal > New Terminal.
Sanal bir Python ortamı oluşturmak için aşağıdakini girin:
py -3.12 -m venv .venvŞimdi dört Python kütüphanesi yüklemeniz gerekiyor: perplexityai, chromadb, python-dotenv ve numpy. Perplexity SDK, Perplexity modellerine API üzerinden bağlanmanızı sağlar. ChromaDB vektör veritabanını oluşturur ve yerel olarak çalışır. Python-dotenv API anahtarlarınızı yerel bir dosyadan güvenli bir şekilde yükler; NumPy ise veri alımı sürecinde gereklidir.
Bunları aşağıdaki komutla yükleyin:
.\.venv\Scripts\python.exe -m pip install perplexityai chromadb python-dotenv numpyAdım 3: Dosyalarınızı hazırlayın
Aşağıdaki dosyaları rag-project klasörüne (proje kök dizini) eklemek için Explorer kenar çubuğunda New File… seçeneğini belirleyin:
- index.py: Belgenizi dizinleyecek uygulamadır. Daha fazla metin eklemek için yeniden çalıştırabilirsiniz.
- rag.py: Orkestratör görevi görecek Python uygulamasıdır.
- document.txt: Vektör veritabanına dönüştüreceğiniz belgeleri içerir.
- .env: Perplexity API anahtarınızı saklayacağınız yerdir.
.env dosyasına aşağıdakini girin:
PERPLEXITY_API_KEY=your_api_key_hereyour_api_key_here ifadesini gerçek anahtarınızla değiştirin. Bunun için Perplexity API Console ana panosuna gidip Create an API key seçeneğini belirlemeniz gerekir. Bu API anahtarını gizli tutun.
İki model kullanacağız: belgelerimizi ChromaDB'ye yüklemeden önce gömmek için Perplexity'nin pplx-embed-v1-0.6b modelini ve getirilen bilgileri işleyecek olan, Perplexity'nin API'si üzerinden erişilen GPT-5.6-Luna'yı.
document.txt dosyasına RAG işlem hattınızın getireceği metni ekleyin. Elinizde bir belge yoksa bu rehber için Project Gutenberg'deki William Blake'in Songs of Innocence and of Experience eserini kullanabilirsiniz. Kamu malı olan, kısa ve anlaşılması kolay bir metindir.
Adım 4: Dizinleme programını yazın
Aşağıdaki kodu kopyalayıp index.py dosyasına yapıştırın. Her alt başlık, ardından gelen kod bölümünün ne yaptığını kısaca açıklar. Bu program, Perplexity'nin pplx-embed-v1-0.6b gömme modelini ve NumPy kütüphanesini kullanarak kaynak materyalinizi vektör gömmelerine dönüştürecek ve bunları bir ChromaDB veritabanında depolayacaktır.
Program şunları yapar:
- document.txt dosyasını açar.
- Metni birbiriyle örtüşen parçalara böler.
- Bu parçaları Perplexity'nin pplx-embed-v1-0.6b gömme modeline gönderir.
- Döndürülen vektörlerin kodunu, hesaplama işlevlerinden oluşan bir Python kütüphanesi olan NumPy ile çözer ve vektörleri normalleştirir.
- Vektörleri ve özgün parçaları bir ChromaDB veritabanında depolar (bu veritabanının proje dizininizde belirdiğini göreceksiniz).
Program, her çalıştırdığınızda belgenizi yeniden dizinlemeyecek şekilde ayarlanmıştır. document.txt dosyasındaki bilgilere ekleme yaparsanız yalnızca yeni metni gömer.
from pathlib import Path
from collections import defaultdict, deque
from hashlib import sha256
import base64
import numpy as np
import chromadb
from dotenv import load_dotenv
from perplexity import Perplexity
# 1. Connect to Perplexity and ChromaDB
load_dotenv()
ai = Perplexity()
db = chromadb.PersistentClient(path="./rag_database_perplexity")
collection = db.get_or_create_collection(
name="documents",
metadata={"hnsw:space": "cosine"}
)
# Convert Perplexity's encoded embeddings into numerical vectors
def decode_embedding(encoded):
vector = np.frombuffer(base64.b64decode(encoded), dtype=np.int8).astype(np.float32)
norm = np.linalg.norm(vector)
if norm == 0:
raise ValueError("Received a zero-length embedding vector.")
return (vector / norm).tolist()
# 2. Read the document and split it into chunks
text = Path("document.txt").read_text(encoding="utf-8")
words = text.split()
chunk_size = 180
overlap = 30
step = chunk_size - overlap
chunks = [" ".join(words[i:i + chunk_size]) for i in range(0, len(words), step)]
if not chunks:
raise ValueError("document.txt is empty.")
# 3. Retrieve the chunks already stored in ChromaDB
existing = collection.get(include=["documents"])
stored_chunks = defaultdict(deque)
existing_ids = set(existing["ids"])
for chunk_id, document in zip(existing["ids"], existing["documents"]):
stored_chunks[document].append(chunk_id)
# 4. Identify unchanged and new chunks
new_chunks = []
new_ids = []
kept_ids = set()
unchanged = 0
for chunk in chunks:
if stored_chunks[chunk]:
chunk_id = stored_chunks[chunk].popleft()
kept_ids.add(chunk_id)
unchanged += 1
else:
chunk_hash = sha256(chunk.encode("utf-8")).hexdigest()
chunk_id = f"chunk-{chunk_hash}"
suffix = 1
while chunk_id in existing_ids or chunk_id in kept_ids or chunk_id in new_ids:
chunk_id = f"chunk-{chunk_hash}-{suffix}"
suffix += 1
new_chunks.append(chunk)
new_ids.append(chunk_id)
kept_ids.add(chunk_id)
# 5. Generate embeddings in batches of up to 100 chunks
batch_size = 100
for i in range(0, len(new_chunks), batch_size):
batch_chunks = new_chunks[i:i + batch_size]
batch_ids = new_ids[i:i + batch_size]
embeddings = ai.embeddings.create(
model="pplx-embed-v1-0.6b",
input=batch_chunks,
encoding_format="base64_int8"
)
vectors = [decode_embedding(item.embedding) for item in embeddings.data]
# 6. Store each batch in ChromaDB
collection.upsert(
ids=batch_ids,
documents=batch_chunks,
embeddings=vectors
)
print(f"Indexed batch {(i // batch_size) + 1}")
# 7. Remove outdated chunks
old_ids = [chunk_id for chunk_id in existing["ids"] if chunk_id not in kept_ids]
if old_ids:
collection.delete(ids=old_ids)
# 8. Display indexing results
print("Indexing complete!")
print("Unchanged chunks:", unchanged)
print("New or modified chunks:", len(new_chunks))
print("Removed chunks:", len(old_ids))
print("Total stored chunks:", collection.count())Adım 5. RAG sisteminin orkestratörünü yazın
Aşağıdaki kodu kopyalayıp rag.py dosyasına yapıştırın. Bu kod, Perplexity SDK'yı ve ChromaDB'nin yerel vektör veritabanı işlevselliğini kullanan eksiksiz ama minimal bir RAG uygulamasıdır.
Programı çalıştırdığınızda şunlar gerçekleşir:
- Perplexity'ye ve yeni ChromaDB veritabanınıza bağlanır.
- Veritabanının dizinlenmiş belgeler içerdiğini kontrol eder.
- Kullanıcıdan bir soru alır.
- Soruyu Perplexity'nin gömme modeline gönderir.
- Elde edilen gömmenin kodunu NumPy ile çözer ve gömmeyi normalleştirir.
- ChromaDB'de en benzer üç belge parçasını arar.
- Getirilen parçaları ve kullanıcının sorusunu içeren bir istem oluşturur.
- İstemi Perplexity'nin Agent API'si üzerinden GPT-5.6 Luna'ya gönderir.
- Yanıtı görüntüler ve bir sonraki soruyu bekler.
import base64
import numpy as np
import chromadb
from dotenv import load_dotenv
from perplexity import Perplexity
# 1. Connect to Perplexity and the existing ChromaDB database
load_dotenv()
ai = Perplexity()
db = chromadb.PersistentClient(path="./rag_database_perplexity")
collection = db.get_collection("documents")
# Convert Perplexity's encoded embeddings into numerical vectors
def decode_embedding(encoded):
vector = np.frombuffer(base64.b64decode(encoded), dtype=np.int8).astype(np.float32)
norm = np.linalg.norm(vector)
if norm == 0:
raise ValueError("Received a zero-length embedding vector.")
return (vector / norm).tolist()
# 2. Check that the database contains indexed documents
count = collection.count()
if count == 0:
raise ValueError("The database is empty. Run index.py first.")
print("Connected to existing ChromaDB database.")
print("Stored chunks:", count)
# 3. Accept questions from the user
while True:
question = input("\nAsk a question (or type exit): ")
if question.lower().strip() == "exit":
break
if not question.strip():
continue
# 4. Convert the question into a Perplexity embedding
question_response = ai.embeddings.create(
model="pplx-embed-v1-0.6b",
input=[question],
encoding_format="base64_int8"
)
question_vector = decode_embedding(question_response.data[0].embedding)
# 5. Retrieve the most similar document chunks from ChromaDB
results = collection.query(
query_embeddings=[question_vector],
n_results=min(3, count)
)
context = "\n\n".join(results["documents"][0])
# 6. Construct a prompt and send it to the fixed LLM
response = ai.responses.create(
model="openai/gpt-5.6-luna",
instructions=(
"Answer using only the supplied document excerpts. "
"Do not use external information. "
"If the answer is not present, say you don't know."
),
input=f"Document excerpts:\n{context}\n\nQuestion: {question}"
)
# 7. Display the answer
print("\nAnswer:\n", response.output_text)Adım 6: Uygulamaları çalıştırın
document.txt dosyasındaki içeriği gömmek için VS Code PowerShell terminaline aşağıdakini girin:
.\.venv\Scripts\python.exe index.pyBelgeniz başarıyla dizinlendiyse buna benzer bir çıktı görmelisiniz:
Indexing complete!
Unchanged chunks: 0
New or modified chunks: 58
Removed chunks: 0
Total stored chunks: 58Şimdi ana orkestratör uygulamasını çalıştırma zamanı. Şu komutu girin:
.\.venv\Scripts\python.exe rag.pyUygulama başarıyla çalışırsa aşağıdakini göreceksiniz:
Connected to existing ChromaDB database.
Stored chunks: 58
Ask a question (or type exit): Artık oluşturduğunuz vektör veritabanından yararlanacak sorular sorabilirsiniz, örneğin:
Ask a question (or type exit): What animals does William Blake talk about?
Answer: The excerpts mention sheep, lambs, birds, beasts, wolves, tigers, and a lion.Adım 7: Ne oluşturduğunuzu anlayın
Oluşturduğunuz sistem, her RAG mimarisinde bulunan iki temel işlem hattını içerir: bir dizinleme veya “veri alımı” işlem hattı ile bir getirme ve üretme işlem hattı.
Temel RAG uygulamanız artık aşağıdakilerin tümünü yapıyor:
- Vektör depolama: Gömmeler, bilgi dosyanız temel alınarak yerel ortamınızdaki ChromaDB veritabanına kaydedilir.
- Artımlı dizinleme: Değişmeyen belge parçaları yeniden gömülmez ve belgeyi istediğiniz zaman güncelleyebilirsiniz.
- Anlamsal getirme: ChromaDB, parçaları vektör benzerliğine göre getirir (işlemi orkestratör başlatır).
- Kaynağa dayalı yanıt üretimi: LLM, getirilen pasajları bağlam olarak alır ve bunları bir yanıta dahil eder.
- Bağımsız dizinleme ve sorgulama: Bilgi dosyanızdaki metnin tamamını yeniden işlemeden soru sorabilirsiniz.
- API tabanlı model bağlantısı: Tüm yanıtlar, bilgisayarınızda çalışan bir model yerine Perplexity üzerinden GPT-5.6 Luna kullanılarak üretilir.
Sonraki adımlar: Bu uygulamayı nasıl daha ileriye taşıyabilirsiniz?
Bu rehberin amacı basit ve temel bir uygulama oluşturmaktır. Rehber, modern sistemlerde bulunan temel RAG mimarisi bileşenlerinden bazılarını kapsar. Daha ileri gitmek isterseniz bu uygulamayı geliştirmenin çeşitli yolları vardır.
Uygulamanızın kapsamını genişletmek için bazı fikirler:
- LangChain ile denemeler yapın: LangChain, en popüler açık kaynaklı orkestrasyon çerçevelerinden biridir. Karmaşık RAG işlem hatlarını çalıştırabilen uygulamalar oluşturmaya yönelik hazır bileşenler içerir.
- Arama işlevselliğini genişletin: Yoğun vektör aramasını BM25 gibi sözcüksel (anahtar kelime) aramayla birleştirin. Perplexity Search API ile web araması eklemek de yanıtları güncel verilere dayandırmanızı sağlar.
- Yeniden sıralama modeli ekleyin: Getirilen pasajları ilk isteme göre sıralayan ve LLM'e sağlanan girdi bağlamına dahil edilmek üzere en alakalı olanları seçen bir yeniden sıralama modeli entegre edin.
- Uyarlanabilir bir RAG sistemi oluşturun: Uyarlanabilir RAG, modüler bir RAG sisteminde hangi getirme yönteminin kullanılacağını belirlemek için bir LLM'den ya da bir sınıflandırıcıdan (orkestratör içindeki bir bileşen) yararlanır. Böyle bir sistem oluşturmak, daha gelişmiş RAG uygulamalarını keşfetmenin iyi bir yoludur.
Tüm bunlar karmaşık gelebilir, ancak Perplexity gibi yaygın yapay zeka platformlarının gelişmiş kodlama desteği sunabildiğini unutmayın. Bu platformlar kişisel projeler ve denemeler için mükemmeldir ve maliyetler görece düşük tutulabilir.
Not: Bu rehberde GPT-5.6 Luna kullanılmaktadır. Model kullanılabilirliği değişebileceğinden API çağrısını güncellemeniz gerekebilir.