AI Engineering Academy · पाठ

RAG आर्किटेक्चर: इंडेक्सिंग और पुनर्प्राप्ति

RAG के दो चरणों का खाका बनाएँ: ऑफ़लाइन इंडेक्सिंग चरण, जिसमें दस्तावेज़ों को खंडों में बाँटकर एम्बेड और संग्रहित किया जाता है, तथा ऑनलाइन पुनर्प्राप्ति चरण, जिसमें प्रत्येक क्वेरी के लिए प्रासंगिक संदर्भ खोजा जाता है।

पाठ 2, कुल 4 में से13 चरण

RAG आर्किटेक्चर: इंडेक्सिंग और पुनर्प्राप्ति, CoddyKit पर AI Engineering Academy का एक निःशुल्क पाठ है। यह 4 में से 2वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह AI Engineering Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। AI Engineering Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

RAG के दो अलग-अलग चरण होते हैं

RAG प्रणाली दो मूलतः अलग चरणों में काम करती है, जो अलग-अलग समय पर चलते हैं। ऑफ़लाइन अनुक्रमण चरण आपके दस्तावेज़ों को एक बार (या उनके बदलने पर) संसाधित करता है और खोज योग्य अनुक्रमणिका तैयार करता है। ऑनलाइन प्राप्ति चरण प्रत्येक उपयोगकर्ता क्वेरी के लिए वास्तविक समय में चलता है। इस विभाजन को समझना ऐसी प्रणालियाँ डिज़ाइन करने के लिए आवश्यक है जो क्वेरी के समय तेज़ और समय के साथ रखरखाव योग्य दोनों हों।

अनुक्रमण चरण: पहला कदम — लोड करना

अनुक्रमण की शुरुआत दस्तावेज़ लोड करने से होती है: आपके स्रोत प्रणालियों से कच्ची फ़ाइलें पढ़ी जाती हैं। दस्तावेज़ PDF, Word फ़ाइलें, HTML पृष्ठ, Markdown फ़ाइलें, डेटाबेस की पंक्तियाँ या कोई भी पाठ स्रोत हो सकते हैं। प्रत्येक दस्तावेज़ को जहाँ तक संभव हो, उसकी संरचना सुरक्षित रखते हुए सादे पाठ के रूप में स्मृति में लोड किया जाता है। pypdf, python-docx और unstructured जैसी लाइब्रेरी प्रारूप-विशिष्ट विश्लेषण का अधिकांश कठिन काम संभालती हैं।

from pypdf import PdfReader

def load_pdf(path):
    reader = PdfReader(path)
    pages = []
    for i, page in enumerate(reader.pages):
        text = page.extract_text()
        pages.append({'text': text, 'page': i + 1, 'source': path})
    return pages

docs = load_pdf('company_policy.pdf')
print(f'Loaded {len(docs)} pages')

अनुक्रमण चरण: दूसरा कदम — खंड बनाना

LLM की संदर्भ विंडो सीमित होती है और पूरे दस्तावेज़ों को प्राप्त करना अपव्ययी है। लोड किए गए पाठ को लगभग 200–1000 टोकन वाले छोटे खंडों में बाँटा जाता है। अच्छा खंड-विभाजन अर्थगत सामंजस्य बनाए रखता है: एक खंड में पूरी बात व्यक्त होनी चाहिए। एक सामान्य रणनीति में अतिव्यापी विंडो का उपयोग किया जाता है, ताकि खंड की सीमाओं के पास के वाक्य दो खंडों में दिखाई दें और विभाजन बिंदुओं पर जानकारी नष्ट न हो।

from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,      # characters per chunk
    chunk_overlap=50,    # overlap between chunks
    separators=['\n\n', '\n', '. ', ' ']
)

for page in docs:
    chunks = splitter.split_text(page['text'])
    for chunk in chunks:
        # Each chunk carries metadata from its source page
        print(f'Chunk ({len(chunk)} chars): {chunk[:80]}...')

अनुक्रमण चरण: तीसरा कदम — एम्बेड करना

प्रत्येक पाठ खंड को एक घने वेक्टर एम्बेडिंग में बदला जाता है, जो उसके अर्थ को संख्यात्मक रूप से दर्शाता है। आप प्रत्येक खंड के लिए text-embedding-3-small जैसे एम्बेडिंग मॉडल को कॉल करते हैं और उच्च-आयामी फ्लोट सारणी प्राप्त करते हैं। समान अर्थ वाले खंड ऐसे वेक्टर बनाते हैं जो इस उच्च-आयामी स्थान में एक-दूसरे के निकट होते हैं; यही अर्थगत समानता खोज को संभव बनाता है।

from openai import OpenAI

client = OpenAI()

def embed_chunks(chunks):
    texts = [c['text'] for c in chunks]
    response = client.embeddings.create(
        model='text-embedding-3-small',
        input=texts
    )
    for i, chunk in enumerate(chunks):
        chunk['embedding'] = response.data[i].embedding
    return chunks

# Batch up to 2048 texts per API call
embedded = embed_chunks(all_chunks)

अनुक्रमण चरण: चौथा कदम — संग्रहित करना

एम्बेड किए गए खंडों को उनके मेटाडेटा (स्रोत फ़ाइल, पृष्ठ संख्या, अनुभाग शीर्षक) के साथ वेक्टर डेटाबेस में संग्रहित किया जाता है। वेक्टर भंडार एक अनुक्रमण संरचना (आमतौर पर HNSW) बनाता है, जो निकटतम पड़ोसी की तेज़ अनुमानित खोज सक्षम करती है। यह अनुक्रमणिका डिस्क पर स्थायी रूप से रखी जाती है, इसलिए पुनः आरंभ करने के बाद भी बनी रहती है। अनुक्रमण आमतौर पर सेटअप के समय एक बार और नए दस्तावेज़ जोड़े जाने पर क्रमिक रूप से किया जाता है।

import pinecone

pc = pinecone.Pinecone(api_key='YOUR_KEY')
index = pc.Index('rag-documents')

# Upsert vectors with metadata
vectors_to_upsert = [
    (
        chunk['id'],
        chunk['embedding'],
        {'text': chunk['text'], 'source': chunk['source'], 'page': chunk['page']}
    )
    for chunk in embedded_chunks
]

# Upsert in batches of 100
for i in range(0, len(vectors_to_upsert), 100):
    index.upsert(vectors=vectors_to_upsert[i:i+100])
print('Indexing complete')

प्राप्ति चरण: क्वेरी एम्बेडिंग

जब कोई उपयोगकर्ता क्वेरी भेजता है, तो ऑनलाइन प्राप्ति चरण शुरू होता है। पहला कदम उपयोगकर्ता के प्रश्न को एम्बेड करना है, जिसके लिए उसी एम्बेडिंग मॉडल का उपयोग किया जाता है जो अनुक्रमण के दौरान इस्तेमाल हुआ था। यह अत्यंत महत्वपूर्ण है: यदि आपने text-embedding-3-small से अनुक्रमण किया है, तो क्वेरी भी text-embedding-3-small से ही करनी होगी। क्वेरी एम्बेडिंग एक ऐसा वेक्टर है जो उपयोगकर्ता के प्रश्न के अर्थ को कूटबद्ध करता है।

def embed_query(question):
    response = client.embeddings.create(
        model='text-embedding-3-small',  # MUST match indexing model
        input=[question]
    )
    return response.data[0].embedding

user_question = 'What is our parental leave policy?'
query_vector = embed_query(user_question)
print(f'Query embedded: {len(query_vector)}-dim vector')

प्राप्ति चरण: ANN खोज

क्वेरी एम्बेडिंग वेक्टर भंडार को भेजी जाती है, जो क्वेरी वेक्टर से सबसे अधिक मिलते-जुलते एम्बेडिंग वाले K खंड खोजने के लिए अनुमानित निकटतम पड़ोसी (ANN) खोज करता है। यह खोज अत्यंत तेज़ होती है (आमतौर पर 10 मिलीसेकंड से कम), क्योंकि HNSW अनुक्रमणिकाएँ बलपूर्वक खोज की तुलना में बहुत अधिक गति पाने के लिए थोड़ी-सी प्राप्ति क्षमता का समझौता करती हैं। आप शीर्ष-K खंड प्राप्त करते हैं—आमतौर पर K=5 से K=20 तक।

results = index.query(
    vector=query_vector,
    top_k=5,
    include_metadata=True
)

print(f'Retrieved {len(results.matches)} chunks:')
for match in results.matches:
    print(f'  Score: {match.score:.3f} | Source: {match.metadata["source"]}')
    print(f'  Text: {match.metadata["text"][:100]}...')
    print()

दोनों चरणों को जोड़ना

मुख्य बात यह है कि अनुक्रमण और प्राप्ति को साथ काम करने के लिए डिज़ाइन किया जाता है। दोनों चरणों में एम्बेडिंग मॉडल बिल्कुल समान होना चाहिए, क्योंकि जिस गणितीय स्थान में वेक्टर रहते हैं वह मॉडल-विशिष्ट होता है। यदि आप एम्बेडिंग मॉडल बदलते हैं, तो आपको सभी दस्तावेज़ों का फिर से अनुक्रमण करना होगा। वेक्टर भंडार एक सेतु का काम करता है: यह अनुक्रमण के दौरान वेक्टर स्वीकार करता है और प्राप्ति के दौरान वेक्टर लौटाता है, जिससे दोनों चरण समय के अनुसार अलग रहते हुए भी वेक्टर स्थान में संरेखित रहते हैं।

प्राप्ति के दौरान मेटाडेटा फ़िल्टर करना

वेक्टर खोज अर्थ की दृष्टि से समान खंड ढूँढ़ती है, लेकिन कभी-कभी आपको मेटाडेटा के आधार पर फ़िल्टर भी करना पड़ता है। उदाहरण के लिए: केवल 2025 में अपलोड किए गए दस्तावेज़ों से खंड प्राप्त करना, या केवल HR विभाग के फ़ोल्डर से खंड प्राप्त करना। वेक्टर भंडार मेटाडेटा क्षेत्रों पर पहले या बाद में फ़िल्टर लगाने की सुविधा देते हैं। पहले फ़िल्टर लगाने (Pinecone और Qdrant द्वारा समर्थित) में ANN खोज से पहले फ़िल्टर लागू होता है, जो शीर्ष-K परिणामों पर बाद में फ़िल्टर लगाने की तुलना में तेज़ और अधिक सटीक है।

# Retrieve only from HR department documents
results = index.query(
    vector=query_vector,
    top_k=5,
    filter={'department': {'$eq': 'HR'}},
    include_metadata=True
)

# Or filter by date range
results = index.query(
    vector=query_vector,
    top_k=5,
    filter={
        'upload_year': {'$gte': 2024},
        'doc_type': {'$eq': 'policy'}
    },
    include_metadata=True
)

अपडेट के लिए क्रमिक अनुक्रमण

वास्तविक प्रणालियों में आपके दस्तावेज़ संग्रह समय के साथ बदलता रहता है। एक प्रभावी अनुक्रमण संरचना क्रमिक अपडेट का समर्थन करती है: जब कोई दस्तावेज़ संपादित किया जाता है, तो उसके मौजूदा वेक्टर ID के आधार पर हटाएँ और नए वेक्टर जोड़ें। जब दस्तावेज़ हटा दिए जाएँ, तो उनके वेक्टर भी हटा दें। प्रत्येक खंड को स्रोत दस्तावेज़ के पथ और खंड की स्थिति पर आधारित एक नियतात्मक ID दें, ताकि हर बार सब कुछ फिर से अनुक्रमित किए बिना सही वेक्टर ढूँढ़कर अपडेट किए जा सकें।

import hashlib

def make_chunk_id(source_path, chunk_index):
    # Deterministic, stable ID for each chunk
    key = f'{source_path}::chunk_{chunk_index}'
    return hashlib.md5(key.encode()).hexdigest()

def update_document(source_path, index):
    # Delete old vectors for this document
    index.delete(filter={'source': source_path})
    # Re-index the updated document
    new_chunks = load_and_chunk(source_path)
    new_embedded = embed_chunks(new_chunks)
    index.upsert(vectors=new_embedded)
    print(f'Updated {source_path}: {len(new_chunks)} chunks')

एक नज़र में पूर्ण RAG पाइपलाइन

पूर्ण RAG संरचना इस प्रकार है: ऑफ़लाइन: दस्तावेज़ → लोडर → खंड-विभाजक → एम्बेडिंग मॉडल → वेक्टर भंडार। ऑनलाइन: उपयोगकर्ता क्वेरी → एम्बेडिंग मॉडल → वेक्टर भंडार (ANN खोज) → शीर्ष-K खंड → प्रॉम्प्ट संयोजन → LLM → उत्तर। ऑफ़लाइन पाइपलाइन प्रत्येक दस्तावेज़ अपडेट पर एक बार चलती है। ऑनलाइन पाइपलाइन प्रत्येक उपयोगकर्ता क्वेरी के लिए मिलीसेकंडों में चलती है; LLM को पूरे दस्तावेज़ संग्रह के बजाय केवल प्रासंगिक संदर्भ दिखाई देता है।

त्वरित जाँच

इस पाठ में AI इंजीनियरिंग की अवधारणाओं के बारे में अपनी समझ जाँचें।

पाठ का पुनरावलोकन

इस पाठ में आपने सीखा: ऑफ़लाइन अनुक्रमण चरण, जिसमें प्रत्येक दस्तावेज़ के लिए एक बार चलने वाले लोड, खंड-विभाजन, एम्बेडिंग और संग्रहण के कदम शामिल हैं; ऑनलाइन प्राप्ति चरण, जो क्वेरी को एम्बेड करता है, ANN खोज करता है और मिलीसेकंडों में शीर्ष-K खंड लौटाता है; तथा दस्तावेज़ों के बदलने पर वेक्टर भंडार को अद्यतन रखने की क्रमिक अनुक्रमण रणनीतियाँ। आगे हम प्रभावी संवर्धित प्रॉम्प्ट तैयार करना सीखेंगे, जो प्राप्त संदर्भ का अच्छे से उपयोग करते हैं।

शुरुआत निःशुल्क

एआई शिक्षक के साथ Python सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
30
पाठ
120

अक्सर पूछे जाने वाले प्रश्न

क्या “RAG आर्किटेक्चर: इंडेक्सिंग और पुनर्प्राप्ति” पाठ निःशुल्क है?

हाँ—“RAG आर्किटेक्चर: इंडेक्सिंग और पुनर्प्राप्ति” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और AI Engineering Academy पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। AI Engineering Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“RAG आर्किटेक्चर: इंडेक्सिंग और पुनर्प्राप्ति” में मैं क्या सीखूँगा?

RAG के दो चरणों का खाका बनाएँ: ऑफ़लाइन इंडेक्सिंग चरण, जिसमें दस्तावेज़ों को खंडों में बाँटकर एम्बेड और संग्रहित किया जाता है, तथा ऑनलाइन पुनर्प्राप्ति चरण, जिसमें प्रत्येक क्वेरी के लिए प्रासंगिक सं… आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ AI Engineering Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या AI Engineering Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर AI Engineering Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 2वाँ पाठ है।

“RAG आर्किटेक्चर: इंडेक्सिंग और पुनर्प्राप्ति” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस AI Engineering Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर AI Engineering Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. RAG किस समस्या का समाधान करता है
  2. RAG आर्किटेक्चर: इंडेक्सिंग और पुनर्प्राप्ति
  3. संवर्धित प्रॉम्प्ट तैयार करना
  4. RAG बनाम फ़ाइन-ट्यूनिंग: किसे कब उपयोग करें
← AI Engineering Academy पर वापस जाएँ