Küçük Prens’i Anlamak: MongoDB Vektör Veritabanları ve RAG Kullanımı

Mustafa Durmuş
albert-health
Published in
5 min readMay 5, 2024

Küçük bir çocuğun gözünden evreni ve büyüklerin hayatını keşfeden Küçük Prens kitabı dünyada en çok okunan kitaplardan biridir. Bu yazıda Küçük Prens kitabı kullanılarak vektör veritabanları, RAG (Retrieval Augmented Generation) gibi yaklaşımlar incelenecek ve bir soru-cevap sistemi geliştirilecektir.

1. Vektör Veritabanları

Günümüzde üretken yapay zeka modellerinin yükselişiyle beraber vektör veritabanları önemli bir hale gelmiştir. Vektör veritabanları, ana veriyi ve embedding işlemi uygulanmış vektörleri geleneksel ilişkisel veritabanlarının yerine çok boyutlu alanlarda saklar. Vektör veritabanlarını anlamak için öncelikle vektörü ve embedding işlemini anlamamız gerekir.

1.1. Vektörizasyon (Vector Embeddings)

Doğal dil işleme problemlerinde oldukça sık kullanılan embedding tekniği sayesinde anlamsal verinin çok boyutlu bir uzayda nümerik vektör karşılığı oluşturulur. Bu vektörlerin başarılı modellenmesi sayesinde veriler arasındaki semantik ilişki tespit edilebilmekte ve birçok doğal dil işleme modelinin başarısı bu aşamada yatmaktadır.

Figür 1. Vektör Veritabanı Diyagramı

Vektör veritabanları bu vektörleri saklamasının yanı sıra, üzerinde arama (vector-search) ve bilgi alma (retrieve) işlemlerini de yapabilmektedir. Vektör veritabanında search işlemi yapmak geleneksel veritabanlarındaki bir query çalıştırmak işleminden farklıdır. Buradaki search işlemi; kesin eşleşmeleri bulmak yerine çok boyutlu uzayda en benzer vektörleri (similarity-search) bulmayı hedefler. Eğer bir generative AI uygulaması geliştiriyorsanız probleminize uygun bir vektör veritabanı seçmeniz veriyi doğru şekilde saklanamız, işlemeniz, üzerinde arama yapmanız için oldukça önemlidir.

1.2. MongoDB Atlas Vector

MongoDB, belge tabanlı bir NoSQL veritabanıdır ve birçok farklı tipte veri barındıran vektör veritabanları için kullanışlı bir ortam sağlar. Bu projede MongoDB’nin yakın zamanda geliştirdiği Atlas Vector platformu kullanıldı.

Atlas Vector üzerinde bir veritabanı oluşturduktan sonra pymongo kütüphanesini kullanıp bir client oluşturup veritabanına erişebilir, vektörlerinizi atabilir veya arama işlemi gerçekleştirebilirsiniz. Aşağıda platform üzerinde oluşturulmuş örnek veritabanını görebilirsiniz.

Figür 2. MongoDB Atlas Vector

2. Uygulama

Projede kullanılan kodlara buradan erişilebilir. Uygulama aşamasına gerekli kütüphanelerin kurulumuyla başlayalım.

python3 -m venv venv
source venv venv/bin/activate
pip3 install pymongo
pip3 install langchain
pip3 install openai
pip3 install python-dotenv

Bir vektör veritabanına veri atarken gerekli aşamalar Figür 3 üzerinde görülmektedir. Bu aşamalar başlıklar altında detaylandıracaktır.

Figür 3. Vektör Veritabanı Aşamaları

2.1. Yükle (Load)

Verinin kaynağından toplanma aşamasıdır. Birden fazla veri kaynağı olabileceği gibi bu projede olduğu üzere tek bir kaynak da olabilir.

Figür 4. Küçük Prens Kitabı
from langchain_community.document_loaders import TextLoader
file_path = "litte_prince.txt"
loader = TextLoader(file_path)
documents = loader.load()

2.2. Dönüştür (Transform)

Veriyi yükledikten sonra embedding modelini beslemek için önce küçük parçalara (chunk) ayrılması gerekir. Chunk boyutu 1024 ve her chunk içindeki overlap miktarı 100 karakter olarak belirlendi. Hiper parametreler için optimum değeri yakalamak için search işleminin sonucuna göre optimizasyon yapmak önemlidir.

from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_size=1024, chunk_overlap=100)
docs = text_splitter.split_documents(documents)

2.3. Vektörize Et (Embedding)

Embedding model olarak OpenAI ADA modeli kullanıldı.

from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(openai_api_key=os.getenv("OPENAI_API_KEY"))

2.4. Kaydet (Store)

Vektör veritabanına MongoDB client ile bağlantı sağlandı.

from pymongo.mongo_client import MongoClient

def create_mongo_client() -> MongoClient:
username = os.getenv("MONGO_DB_ATLAS_USER_NAME")
password = os.getenv("MONGO_DB_ATLAS_USER_PASSWORD")
cluster = os.getenv("MONGO_DB_ATLAS_CLUSTER_NAME")

uri = f"mongodb+srv://{username}:{@cluster0.osiqvwu.mongodb.net">password}@cluster0.osiqvwu.mongodb.net/?retryWrites=true&w=majority&appName={cluster}"
client = MongoClient(uri, server_api=ServerApi('1'))
try:
client.admin.command('ping')
print("Pinged your deployment. You successfully connected to MongoDB!")
except Exception as e:
print(e)

return client

client = create_mongo_client()

Veritabanına bağlantı sağlandıktan sonra veri ve embedding modeli ile MongoDBAtlasVectorSearch fonksiyonu çağrılır ve veri veritabanına aktarılır.

from langchain_community.vectorstores import MongoDBAtlasVectorSearch

db_name = "llm"
collection_name = "little_prince"
index_name = "vector_index"
collection = client[db_name][collection_name]

MongoDBAtlasVectorSearch.from_documents(docs, embeddings, collection=collection, index_name=index_name)
Figür 5. MongoDB Embedding Vektörler

Tüm aşamaları create_vectors.py içerisinde görebilirsiniz.

2.5. Bilgi Alma (Retrieve)

Bu aşamada oluşturduğumuz vektör veritabanı üzerinde bir sorgu ile arama yapıp en yakın vektörleri toplayacağız. Retrieve işleminde elde edilen veri aynı zamanda RAG tekniğinin de ilk aşamasını oluşturmaktadır.

3. Retrieval Augmented Generation

Figür 6. RAG Pipeline

RAG 2 aşamadan oluşur; bilgi alma ve üretim. İlk aşamada toplanan veri bir sistem prompt ile birleştirilir ve kullanılan LLM (Large Language Model) beslenir. Bu teknik LLM’lerde sıkça rastlanan halüsinasyon problemine çözüm olarak geliştirilmiştir. Bu projede LLM olarak GPT-4 modeli kullanıldı.

Langchain ile bir RAG zinciri (chain) oluşturalım. Bu pipeline’ın ilk aşaması daha önce oluşturduğumuz vektör veritabanında yaptığımız aramanın çıktısı olmalıdır.

Öncelikle bir prompt-template oluşturalım.

from langchain_core.prompts import ChatPromptTemplate

prompt_template = ChatPromptTemplate.from_messages([
("system", "you are a helpful assistant."),
("user", """Now let's continue with the user's query:
Question: {input}
===
Be short and on the point.
<context>
{context}
</context>
===
Answer:""")])

Prompt-template, LLM ve retrieve ettiğimiz veri ile chain’i oluşturalım.

def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)

rag_chain_from_docs = (
RunnablePassthrough.assign(context=(lambda x: format_docs(x["context"])))
| self.prompt_template
| self.llm_model
| StrOutputParser()
)

retriever = MONGO_VECTOR_STORE.as_retriever(search_kwargs={'k': 2}, similarity_type="similarity")

rag_chain_with_source = RunnableParallel({"context": retriever, "input": RunnablePassthrough()}).assign(
answer=rag_chain_from_docs)

Chain’i kullanarak artık kitap ile alakalı sorularımızı sorabilir ve cevap alabiliriz. Bu kısımdaki kodun tamamına buradan ulaşabilirsiniz.

4. Sonuç: Küçük Prens’i Anlamak

Bu proje Küçük Prens kitabını MongoDB vektör veritabanı ve Langchain üzerinden RAG kullanarak analiz etmek, hem teknik zorlukları hem de edebi metinlerle yapay zeka teknolojilerini entegre etmenin potansiyelini ortaya koymuştur.

Aşağıda oluşturulan pipeline üzerinden sorulmuş bazı örnek soru ve cevapları görebilirsiniz. Okuduğunuz için teşekkür ederim, bir sonraki yazıda görüşmek dileğiyle.

Figür 7. Örnek soru ve LLM cevabı
Figür 8. Örnek soru ve LLM cevabı
Figür 9. Örnek soru ve LLM cevabı

5. Kaynaklar

--

--