spinny:~/writing $ vim rag-langchain-deep-dive.md
1~2GPT-4 ve Claude gibi Büyük Dil Modelleri (LLM) olağanüstü güçlüdür, ancak temel bir sınırlamadan muzdariptirler: bilgileri eğitim anında dondurulmuştur. İç belgelerinize, veritabanınıza veya gerçek zamanlı bilgilere erişemezler. **Getirme ile Zenginleştirilmiş Üretim (RAG)**, LLM'lerin üretim gücünü harici kaynaklardan bilgi getirme yeteneğiyle birleştirerek tam olarak bu sorunu çözer.3~4## Sorun: LLM Sınırlamaları5~6RAG hakkında konuşmadan önce, neden buna ihtiyacımız olduğunu anlamak önemlidir.7~81. **Statik bilgi**: Bir LLM yalnızca eğitim sırasında gördüklerini bilir. Kesim tarihinden sonra meydana gelen bir olay hakkında sorarsanız, yanıt veremez.92. **Halüsinasyonlar**: Bir LLM yanıtı bilmediğinde, makul ama tamamen yanlış bilgiler üreterek uydurma eğilimindedir.103. **Özel verilere erişim yok**: Genel bir LLM, şirketinizin iç belgelerine, destek taleplerine veya kod tabanına erişimi yoktur.11~12RAG, sorgu anında harici kaynaklardan getirilen **ilgili bağlamı** modele sağlayarak bu üç sorunun tamamını ele alır.13~14## RAG Nedir?15~16Getirme ile Zenginleştirilmiş Üretim, bir LLM'ye gönderilen istemi harici bir bilgi tabanından getirilen bilgilerle zenginleştiren bir mimaridir. Modelin yalnızca parametrik bilgisine güvenmek yerine, RAG önce ilgili bilgileri **arar** ve ardından isteme **enjekte eder**, böylece modelin doğru, temelli yanıtlar üretmesini sağlar.17~18```mermaid19graph LR20 User["User"] -- "Question" --> Retriever21 Retriever -- "Search relevant\ndocuments" --> VectorStore["Vector Store"]22 VectorStore -- "Relevant\ndocuments" --> Retriever23 Retriever -- "Context + Question" --> LLM24 LLM -- "Grounded\nresponse" --> User25```26~27## RAG Nasıl Detaylı Çalışır28~29RAG mimarisi iki ana aşamadan oluşur: **İndeksleme** (çevrimdışı) ve **Getirme + Üretim** (çevrimiçi).30~31### Aşama 1: İndeksleme (Belge Alımı)32~33İndeksleme aşaması belgelerinizi semantik arama için hazırlar. Dört adımdan oluşur.34~35```mermaid36graph TD37 A["Documents\n(PDF, HTML, MD, DB)"] --> B["Document Loader"]38 B --> C["Text Splitter"]39 C --> D["Text Chunks"]40 D --> E["Embedding Model"]41 E --> F["Numerical Vectors"]42 F --> G["Vector Store\n(ChromaDB, Pinecone, FAISS)"]43```44~45#### 1. Belge Yükleme46~47Belgeler herhangi bir kaynaktan gelebilir: PDF dosyaları, web sayfaları, veritabanları, Markdown dosyaları, API'ler. **Document Loader** bu belgeleri okur ve yapılandırılmış metne dönüştürür.48~49#### 2. Metin Bölme (Chunking)50~51LLM'lerin sınırlı bağlam penceresi vardır ve belgeler çok uzun olabilir. **Text Splitter** belgeleri *chunks* adı verilen daha küçük parçalara böler. Chunking kalitesi kritiktir: çok küçük chunks bağlamı kaybeder, çok büyük chunks ise ilgililik düzeyini seyreltir.52~53En yaygın stratejiler şunlardır:54- **Özyinelemeli Karakter Bölme**: `\n\n`, `\n`, `. ` gibi ayırıcılar kullanarak belge yapısına saygı göstererek metni özyinelemeli olarak böler.55- **Semantik Bölme**: Metinde doğal kırılma noktalarını bulmak için embeddings kullanır.56- **Chunk Örtüşmesi**: Sınırlarda bağlamı korumak için ardışık chunks arasında örtüşme içerir.57~58#### 3. Embedding59~60Her chunk, bir embedding modeli (OpenAI'nin `text-embedding-3-small` gibi) aracılığıyla bir **sayısal vektöre** (embedding) dönüştürülür. Bu vektörler metnin anlamsal anlamını yakalar: benzer anlamlara sahip cümleler, çok boyutlu uzayda birbirine yakın vektörlere sahip olacaktır.61~62#### 4. Vector Store63~64Vektörler, ChromaDB, Pinecone, Weaviate veya FAISS gibi bir **Vector Store**'da (veya vektör veritabanında) kaydedilir. Bu veritabanı **benzerlik araması** için optimize edilmiştir: bir sorgu verildiğinde, en benzer vektörleri (ve dolayısıyla en ilgili metin chunks'larını) bulur.65~66### Aşama 2: Getirme + Üretim67~68Kullanıcı bir soru sorduğunda:69~701. Soru, aynı embedding modeli kullanılarak bir embedding'e dönüştürülür.712. Vector Store, **benzerlik araması** (genellikle kosinüs benzerliği veya Öklid mesafesi) yoluyla en benzer chunks'ları bulur.723. Getirilen chunks, bağlam olarak isteme eklenir.734. LLM, sağlanan bağlama dayalı bir yanıt üretir.74~75## LangChain ile RAG Pipeline Oluşturma76~77**LangChain**, LLM destekli uygulamalar oluşturmak için en popüler Python (ve JavaScript) çerçevesidir. RAG pipeline'ının her bileşeni için üst düzey soyutlamalar sağlar.78~79### Kurulum80~81```bash82pip install langchain langchain-openai langchain-community chromadb83```84~85### Adım 1: Belgeleri Yükle86~87LangChain, farklı veri kaynakları için düzinelerce Document Loader sağlar.88~89```python90from langchain_community.document_loaders import (91 PyPDFLoader,92 WebBaseLoader,93 DirectoryLoader,94 TextLoader,95)96~97# Load a PDF98pdf_loader = PyPDFLoader("docs/manual.pdf")99pdf_docs = pdf_loader.load()100~101# Load a web page102web_loader = WebBaseLoader("https://docs.example.com/guide")103web_docs = web_loader.load()104~105# Load all .md files from a directory106dir_loader = DirectoryLoader("./knowledge_base", glob="**/*.md", loader_cls=TextLoader)107md_docs = dir_loader.load()108~109all_docs = pdf_docs + web_docs + md_docs110```111~112### Adım 2: Belgeleri Chunks'lara Böl113~114```python115from langchain.text_splitter import RecursiveCharacterTextSplitter116~117text_splitter = RecursiveCharacterTextSplitter(118 chunk_size=1000,119 chunk_overlap=200,120 separators=["\n\n", "\n", ". ", " ", ""],121)122~123chunks = text_splitter.split_documents(all_docs)124print(f"Original documents: {len(all_docs)}, Chunks: {len(chunks)}")125```126~127`chunk_overlap` parametresi kritik öneme sahiptir: ardışık chunks arasında örtüşme oluşturur, böylece sınırlarda bağlam kaybedilmez.128~129### Adım 3: Embeddings ve Vector Store Oluştur130~131```python132from langchain_openai import OpenAIEmbeddings133from langchain_community.vectorstores import Chroma134~135embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")136~137vectorstore = Chroma.from_documents(138 documents=chunks,139 embedding=embedding_model,140 persist_directory="./chroma_db",141)142```143~144### Adım 4: Retriever Oluştur145~146Retriever, bir sorgu verildiğinde vector store'dan en ilgili chunks'ları getiren bileşendir.147~148```python149retriever = vectorstore.as_retriever(150 search_type="similarity",151 search_kwargs={"k": 4},152)153~154relevant_docs = retriever.invoke("How does authentication work?")155for doc in relevant_docs:156 print(doc.page_content[:200])157 print("---")158```159~160### Adım 5: RAG Zinciri Oluştur161~162Şimdi her şeyi bir LLM ve bir istem şablonuyla bir araya getirelim.163~164```python165from langchain_openai import ChatOpenAI166from langchain_core.prompts import ChatPromptTemplate167from langchain_core.runnables import RunnablePassthrough168from langchain_core.output_parsers import StrOutputParser169~170llm = ChatOpenAI(model="gpt-4o", temperature=0)171~172prompt = ChatPromptTemplate.from_template("""173Answer the question based only on the provided context.174If the context does not contain enough information, say you don't know.175~176Context:177{context}178~179Question: {question}180~181Answer:182""")183~184def format_docs(docs):185 return "\n\n".join(doc.page_content for doc in docs)186~187rag_chain = (188 {"context": retriever | format_docs, "question": RunnablePassthrough()}189 | prompt190 | llm191 | StrOutputParser()192)193~194response = rag_chain.invoke("How does authentication work in the system?")195print(response)196```197~198## Gelişmiş RAG Teknikleri199~200Temel pipeline iyi çalışır, ancak yanıt kalitesini önemli ölçüde artırmak için çeşitli teknikler vardır.201~202### Çoklu Sorgu Getirme203~204Bazen kullanıcının sorgusu belirsizdir veya belgelerde kullanılan dille uyumlu değildir. **Multi-Query Retriever**, birden fazla bakış açısı yakalamak için orijinal sorunun varyantlarını otomatik olarak üretir.205~206```python207from langchain.retrievers import MultiQueryRetriever208~209multi_retriever = MultiQueryRetriever.from_llm(210 retriever=vectorstore.as_retriever(),211 llm=llm,212)213~214docs = multi_retriever.invoke("What are the security best practices?")215```216~217### Bağlamsal Sıkıştırma218~219Bir chunk'taki tüm içerik sorguyla ilgili değildir. **Contextual Compression Retriever**, getirilen her chunk'tan yalnızca ilgili kısımları çıkarmak için bir LLM kullanır.220~221```python222from langchain.retrievers import ContextualCompressionRetriever223from langchain.retrievers.document_compressors import LLMChainExtractor224~225compressor = LLMChainExtractor.from_llm(llm)226compression_retriever = ContextualCompressionRetriever(227 base_compressor=compressor,228 base_retriever=retriever,229)230```231~232### Hibrit Arama233~234Tamamen semantik arama her zaman optimal değildir. **Hibrit Arama**, daha iyi sonuçlar elde etmek için semantik aramayı (embeddings) sözcüksel arama (BM25, anahtar kelime eşleştirme) ile birleştirir.235~236```python237from langchain.retrievers import EnsembleRetriever238from langchain_community.retrievers import BM25Retriever239~240bm25_retriever = BM25Retriever.from_documents(chunks)241bm25_retriever.k = 4242~243semantic_retriever = vectorstore.as_retriever(search_kwargs={"k": 4})244~245hybrid_retriever = EnsembleRetriever(246 retrievers=[bm25_retriever, semantic_retriever],247 weights=[0.4, 0.6],248)249```250~251### Konuşmalı RAG (Bellekli)252~253Konuşma bağlamını hatırlayan bir RAG sohbet robotu oluşturmak için, konuşma geçmişini dikkate alarak kullanıcının sorularını yeniden formüle eden bir bellek eklemeniz gerekir.254~255```python256from langchain.chains import create_history_aware_retriever257from langchain_core.prompts import MessagesPlaceholder258~259contextualize_prompt = ChatPromptTemplate.from_messages([260 ("system", "Given the chat history and the user's latest question, "261 "reformulate the question so it is understandable without the history."),262 MessagesPlaceholder("chat_history"),263 ("human", "{input}"),264])265~266history_aware_retriever = create_history_aware_retriever(267 llm, retriever, contextualize_prompt268)269```270~271## En İyi Uygulamalar272~2731. **Doğru chunk boyutunu seçin**: Farklı boyutlarla (500-1500 token) deneyler yapın. Kesin yanıtlar için küçük chunks, daha geniş bağlam için büyük chunks.2742. **Belge meta verilerini kullanın**: Chunks'lara meta veri olarak kaynak, tarih ve kategori ekleyin. Bu, getirme sırasında sonuçları filtrelemeye olanak tanır.2753. **Kaliteyi değerlendirin**: *faithfulness*, *relevancy* ve *context precision* gibi metrikleri ölçmek için [RAGAS](https://docs.ragas.io/) gibi çerçeveleri kullanın.2764. **Belge güncellemelerini yönetin**: Vector store'u veri kaynaklarınızla senkronize tutmak için yeniden alım pipeline'ı uygulayın.2775. **Re-ranker ekleyin**: İlk getirmeden sonra, sonuçları gerçek ilgililiğe göre yeniden sıralamak için bir re-ranking modeli (Cohere Rerank gibi) kullanın.278~279## Sonuç280~281RAG, belirli, güncel bilgiye erişim gerektiren AI uygulamaları oluşturmak için standart mimari haline gelmiştir. LangChain, pipeline'ın her bileşeni için soyutlamalar sağlayarak uygulamayı büyük ölçüde basitleştirir.282~283**Sonraki adımlar:**284- **Yerel olarak deneyin**: Pipeline'a aşina olmak için ChromaDB ve birkaç belgeyle başlayın.285- **LangSmith'i keşfedin**: Üretimde zincirlerinizi izlemek ve hata ayıklamak için [LangSmith](https://smith.langchain.com/) kullanın.286- **Farklı embedding modelleri deneyin**: `text-embedding-3-small`, `text-embedding-3-large` ve Sentence Transformers'dan açık kaynak modelleri karşılaştırın.287- **Belgeleri kontrol edin**: [LangChain belgeleri](https://python.langchain.com/docs/) mükemmel ve sürekli güncellenen bir kaynaktır.288~
NORMAL · rag-langchain-deep-dive.md [readonly]288 lines · :q to close