spinny:~/writing $ vim rag-langchain-deep-dive.md
1~2GPT-4 और Claude जैसे Large Language Models (LLMs) असाधारण रूप से शक्तिशाली हैं, लेकिन वे एक मूलभूत सीमा से ग्रस्त हैं: उनका ज्ञान ट्रेनिंग के समय जम जाता है। वे आपके आंतरिक दस्तावेज़ों, आपके डेटाबेस या वास्तविक समय की जानकारी तक नहीं पहुँच सकते। **Retrieval-Augmented Generation (RAG)** LLMs की जनरेटिव शक्ति को बाहरी स्रोतों से जानकारी प्राप्त करने की क्षमता के साथ जोड़कर इस समस्या को हल करती है।3~4## समस्या: LLMs की सीमाएं5~6RAG के बारे में बात करने से पहले, यह समझना ज़रूरी है कि हमें इसकी आवश्यकता क्यों है।7~81. **स्थिर ज्ञान**: एक LLM केवल वही जानता है जो उसने ट्रेनिंग के दौरान देखा। यदि आप उसके कटऑफ के बाद हुई किसी घटना के बारे में पूछते हैं, तो वह उत्तर नहीं दे सकता।92. **हैलुसिनेशन**: जब LLM को उत्तर नहीं पता होता, तो वह एक गढ़ने की प्रवृत्ति रखता है, विश्वसनीय लेकिन पूरी तरह से गलत जानकारी उत्पन्न करता है।103. **निजी डेटा तक पहुँच नहीं**: एक सामान्य LLM के पास आपकी कंपनी के आंतरिक दस्तावेज़ों, टिकट या कोडबेस तक पहुँच नहीं है।11~12RAG क्वेरी के समय बाहरी स्रोतों से प्राप्त **प्रासंगिक संदर्भ** प्रदान करके इन तीनों समस्याओं का समाधान करती है।13~14## RAG क्या है?15~16Retrieval-Augmented Generation एक आर्किटेक्चर है जो LLM को भेजे गए प्रॉम्प्ट को बाहरी ज्ञान आधार से प्राप्त जानकारी से समृद्ध करती है। मॉडल के पैरामेट्रिक ज्ञान पर पूरी तरह निर्भर रहने के बजाय, RAG पहले प्रासंगिक जानकारी **खोजती** है और फिर उसे प्रॉम्प्ट में **इंजेक्ट** करती है, जिससे मॉडल सटीक, आधारित प्रतिक्रियाएं उत्पन्न कर सकता है।17~18```mermaid19graph LR20 User["उपयोगकर्ता"] -- "प्रश्न" --> Retriever21 Retriever -- "प्रासंगिक दस्तावेज़\nखोजें" --> VectorStore["वेक्टर स्टोर"]22 VectorStore -- "प्रासंगिक\nदस्तावेज़" --> Retriever23 Retriever -- "संदर्भ + प्रश्न" --> LLM24 LLM -- "आधारित\nउत्तर" --> User25```26~27## RAG विस्तार से कैसे काम करता है28~29RAG आर्किटेक्चर दो मुख्य चरणों से बना है: **इंडेक्सिंग** (ऑफलाइन) और **रिट्रीवल + जनरेशन** (ऑनलाइन)।30~31### चरण 1: इंडेक्सिंग (दस्तावेज़ इंजेशन)32~33इंडेक्सिंग चरण आपके दस्तावेज़ों को सिमेंटिक खोज के लिए तैयार करता है। इसमें चार कदम शामिल हैं।34~35```mermaid36graph TD37 A["दस्तावेज़\n(PDF, HTML, MD, DB)"] --> B["डॉक्यूमेंट लोडर"]38 B --> C["टेक्स्ट स्प्लिटर"]39 C --> D["टेक्स्ट चंक्स"]40 D --> E["एम्बेडिंग मॉडल"]41 E --> F["संख्यात्मक वेक्टर"]42 F --> G["वेक्टर स्टोर\n(ChromaDB, Pinecone, FAISS)"]43```44~45#### 1. दस्तावेज़ लोडिंग46~47दस्तावेज़ किसी भी स्रोत से आ सकते हैं: PDF फाइलें, वेब पेज, डेटाबेस, Markdown फाइलें, APIs। **डॉक्यूमेंट लोडर** इन दस्तावेज़ों को पढ़ता है और उन्हें संरचित टेक्स्ट में बदलता है।48~49#### 2. टेक्स्ट स्प्लिटिंग (चंकिंग)50~51LLMs की कॉन्टेक्स्ट विंडो सीमित होती है, और दस्तावेज़ बहुत लंबे हो सकते हैं। **टेक्स्ट स्प्लिटर** दस्तावेज़ों को *चंक्स* नामक छोटे टुकड़ों में विभाजित करता है। चंकिंग की गुणवत्ता महत्वपूर्ण है: बहुत छोटे चंक्स संदर्भ खो देते हैं, बहुत बड़े चंक्स प्रासंगिकता को कम करते हैं।52~53सबसे आम रणनीतियां हैं:54- **रिकर्सिव कैरेक्टर स्प्लिटिंग**: `\n\n`, `\n`, `. ` जैसे सेपरेटर्स का उपयोग करके टेक्स्ट को रिकर्सिव रूप से विभाजित करता है, दस्तावेज़ संरचना का सम्मान करता है।55- **सिमेंटिक स्प्लिटिंग**: टेक्स्ट में प्राकृतिक ब्रेकपॉइंट खोजने के लिए एम्बेडिंग का उपयोग करता है।56- **चंक ओवरलैप**: सीमाओं पर संदर्भ को संरक्षित करने के लिए लगातार चंक्स के बीच ओवरलैप शामिल करता है।57~58#### 3. एम्बेडिंग59~60प्रत्येक चंक को एम्बेडिंग मॉडल (जैसे OpenAI का `text-embedding-3-small`) के माध्यम से एक **संख्यात्मक वेक्टर** (एम्बेडिंग) में बदला जाता है। ये वेक्टर टेक्स्ट के सिमेंटिक अर्थ को कैप्चर करते हैं: समान अर्थ वाले वाक्यों के वेक्टर बहुआयामी स्थान में पास होंगे।61~62#### 4. वेक्टर स्टोर63~64वेक्टर ChromaDB, Pinecone, Weaviate या FAISS जैसे **वेक्टर स्टोर** (वेक्टर डेटाबेस) में सहेजे जाते हैं। यह डेटाबेस **समानता खोज** के लिए अनुकूलित है: एक क्वेरी दिए जाने पर, यह सबसे समान वेक्टर (और इसलिए सबसे प्रासंगिक टेक्स्ट चंक्स) खोजता है।65~66### चरण 2: रिट्रीवल + जनरेशन67~68जब उपयोगकर्ता प्रश्न पूछता है:69~701. प्रश्न को उसी एम्बेडिंग मॉडल का उपयोग करके एम्बेडिंग में बदला जाता है।712. वेक्टर स्टोर **समानता खोज** (आमतौर पर कोसाइन समानता या यूक्लिडियन दूरी) के माध्यम से सबसे समान चंक्स खोजता है।723. प्राप्त चंक्स को संदर्भ के रूप में प्रॉम्प्ट में डाला जाता है।734. LLM प्रदान किए गए संदर्भ के आधार पर उत्तर उत्पन्न करता है।74~75## LangChain के साथ RAG पाइपलाइन बनाना76~77**LangChain** LLM-आधारित एप्लिकेशन बनाने के लिए सबसे लोकप्रिय Python (और JavaScript) फ्रेमवर्क है। यह RAG पाइपलाइन के प्रत्येक घटक के लिए उच्च-स्तरीय एब्स्ट्रैक्शन प्रदान करता है।78~79### इंस्टॉलेशन80~81```bash82pip install langchain langchain-openai langchain-community chromadb83```84~85### स्टेप 1: दस्तावेज़ लोड करें86~87LangChain विभिन्न डेटा स्रोतों के लिए दर्जनों डॉक्यूमेंट लोडर प्रदान करता है।88~89```python90from langchain_community.document_loaders import (91 PyPDFLoader,92 WebBaseLoader,93 DirectoryLoader,94 TextLoader,95)96~97# एक PDF लोड करें98pdf_loader = PyPDFLoader("docs/manual.pdf")99pdf_docs = pdf_loader.load()100~101# एक वेब पेज लोड करें102web_loader = WebBaseLoader("https://docs.example.com/guide")103web_docs = web_loader.load()104~105# एक डायरेक्टरी से सभी .md फाइलें लोड करें106dir_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### स्टेप 2: दस्तावेज़ों को चंक्स में विभाजित करें113~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"मूल दस्तावेज़: {len(all_docs)}, चंक्स: {len(chunks)}")125```126~127`chunk_overlap` पैरामीटर महत्वपूर्ण है: यह लगातार चंक्स के बीच ओवरलैप बनाता है ताकि सीमाओं पर संदर्भ न खोए।128~129### स्टेप 3: एम्बेडिंग और वेक्टर स्टोर बनाएं130~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### स्टेप 4: रिट्रीवर बनाएं145~146रिट्रीवर वह घटक है जो, एक क्वेरी दिए जाने पर, वेक्टर स्टोर से सबसे प्रासंगिक चंक्स प्राप्त करता है।147~148```python149retriever = vectorstore.as_retriever(150 search_type="similarity",151 search_kwargs={"k": 4},152)153~154relevant_docs = retriever.invoke("प्रमाणीकरण कैसे काम करता है?")155for doc in relevant_docs:156 print(doc.page_content[:200])157 print("---")158```159~160### स्टेप 5: RAG चेन बनाएं161~162अब सब कुछ एक LLM और प्रॉम्प्ट टेम्पलेट के साथ जोड़ते हैं।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("""173केवल प्रदान किए गए संदर्भ के आधार पर प्रश्न का उत्तर दें।174यदि संदर्भ में पर्याप्त जानकारी नहीं है, तो कहें कि आप नहीं जानते।175~176संदर्भ:177{context}178~179प्रश्न: {question}180~181उत्तर: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("सिस्टम में प्रमाणीकरण कैसे काम करता है?")195print(response)196```197~198## उन्नत RAG तकनीकें199~200बुनियादी पाइपलाइन अच्छी तरह काम करती है, लेकिन उत्तर की गुणवत्ता में उल्लेखनीय सुधार करने के लिए कई तकनीकें हैं।201~202### मल्टी-क्वेरी रिट्रीवल203~204कभी-कभी उपयोगकर्ता की क्वेरी अस्पष्ट होती है या दस्तावेज़ों में प्रयुक्त भाषा से मेल नहीं खाती। **मल्टी-क्वेरी रिट्रीवर** कई दृष्टिकोणों को कैप्चर करने के लिए मूल प्रश्न के वेरिएंट स्वचालित रूप से उत्पन्न करता है।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("सुरक्षा की सर्वोत्तम प्रथाएं क्या हैं?")215```216~217### कॉन्टेक्स्चुअल कम्प्रेशन218~219चंक की सारी सामग्री क्वेरी के लिए प्रासंगिक नहीं होती। **कॉन्टेक्स्चुअल कम्प्रेशन रिट्रीवर** प्रत्येक प्राप्त चंक से केवल प्रासंगिक भागों को निकालने के लिए LLM का उपयोग करता है।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### हाइब्रिड सर्च233~234शुद्ध सिमेंटिक खोज हमेशा इष्टतम नहीं होती। **हाइब्रिड सर्च** बेहतर परिणाम प्राप्त करने के लिए सिमेंटिक खोज (एम्बेडिंग) को लेक्सिकल खोज (BM25, कीवर्ड मैचिंग) के साथ जोड़ती है।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### कन्वर्सेशनल RAG (मेमोरी के साथ)252~253बातचीत के संदर्भ को याद रखने वाला RAG चैटबॉट बनाने के लिए, एक मेमोरी जोड़ना आवश्यक है जो बातचीत के इतिहास को ध्यान में रखते हुए उपयोगकर्ता के प्रश्नों को पुनर्निर्मित करे।254~255```python256from langchain.chains import create_history_aware_retriever257from langchain_core.prompts import MessagesPlaceholder258~259contextualize_prompt = ChatPromptTemplate.from_messages([260 ("system", "चैट इतिहास और उपयोगकर्ता के नवीनतम प्रश्न को देखते हुए, "261 "प्रश्न को इस तरह पुनर्निर्मित करें कि यह इतिहास के बिना भी समझ में आए।"),262 MessagesPlaceholder("chat_history"),263 ("human", "{input}"),264])265~266history_aware_retriever = create_history_aware_retriever(267 llm, retriever, contextualize_prompt268)269```270~271## सर्वोत्तम प्रथाएं272~2731. **सही चंक आकार चुनें**: विभिन्न आकारों (500-1500 टोकन) के साथ प्रयोग करें। सटीक उत्तरों के लिए छोटे चंक्स, व्यापक संदर्भ के लिए बड़े चंक्स।2742. **दस्तावेज़ मेटाडेटा का उपयोग करें**: स्रोत, तिथि और श्रेणी को चंक्स में मेटाडेटा के रूप में जोड़ें। यह रिट्रीवल के दौरान परिणामों को फिल्टर करने की अनुमति देता है।2753. **गुणवत्ता का मूल्यांकन करें**: *faithfulness*, *relevancy* और *context precision* जैसे मेट्रिक्स मापने के लिए [RAGAS](https://docs.ragas.io/) जैसे फ्रेमवर्क का उपयोग करें।2764. **दस्तावेज़ अपडेट प्रबंधित करें**: वेक्टर स्टोर को अपने डेटा स्रोतों के साथ सिंक्रनाइज़ रखने के लिए री-इंजेशन पाइपलाइन लागू करें।2775. **री-रैंकर जोड़ें**: प्रारंभिक रिट्रीवल के बाद, वास्तविक प्रासंगिकता के आधार पर परिणामों को पुनर्क्रमित करने के लिए री-रैंकिंग मॉडल (जैसे Cohere Rerank) का उपयोग करें।278~279## निष्कर्ष280~281RAG विशिष्ट, अद्यतन ज्ञान तक पहुँच की आवश्यकता वाले AI एप्लिकेशन बनाने के लिए मानक आर्किटेक्चर बन गई है। LangChain पाइपलाइन के प्रत्येक घटक के लिए एब्स्ट्रैक्शन प्रदान करके कार्यान्वयन को बहुत सरल बनाता है।282~283**अगले कदम:**284- **स्थानीय रूप से प्रयोग करें**: पाइपलाइन से परिचित होने के लिए ChromaDB और कुछ दस्तावेज़ों से शुरू करें।285- **LangSmith का अन्वेषण करें**: प्रोडक्शन में अपनी चेन की निगरानी और डिबगिंग के लिए [LangSmith](https://smith.langchain.com/) का उपयोग करें।286- **विभिन्न एम्बेडिंग मॉडल आज़माएं**: `text-embedding-3-small`, `text-embedding-3-large` और Sentence Transformers के ओपन-सोर्स मॉडल की तुलना करें।287- **दस्तावेज़ देखें**: [LangChain दस्तावेज़](https://python.langchain.com/docs/) एक उत्कृष्ट और लगातार अपडेट होने वाला संसाधन है।288~
NORMAL · rag-langchain-deep-dive.md [readonly]288 lines · :q to close