بڑے زبان کے ماڈلز (LLMs) جیسے GPT-4 اور Claude غیر معمولی طور پر طاقتور ہیں، لیکن وہ ایک بنیادی حد سے دوچار ہیں: ان کا علم تربیت کے وقت منجمد ہو جاتا ہے۔ وہ آپ کے اندرونی دستاویزات، آپ کے ڈیٹابیس، یا حقیقی وقت کی معلومات تک رسائی حاصل نہیں کر سکتے۔ ریٹریول-آگمینٹڈ جنریشن (RAG) بالکل اسی مسئلے کو حل کرتا ہے، LLMs کی تخلیقی طاقت کو بیرونی ذرائع سے معلومات حاصل کرنے کی صلاحیت کے ساتھ جوڑ کر۔
مسئلہ: LLM کی حدود
RAG کے بارے میں بات کرنے سے پہلے، یہ سمجھنا ضروری ہے کہ ہمیں اس کی ضرورت کیوں ہے۔
- جامد علم: ایک LLM صرف وہی جانتا ہے جو اس نے تربیت کے دوران دیکھا۔ اگر آپ اس کی کٹ آف کے بعد ہونے والے واقعے کے بارے میں پوچھیں، تو یہ جواب نہیں دے سکتا۔
- ہیلوسینیشنز: جب ایک LLM جواب نہیں جانتا، تو یہ ایک بنانے کا رجحان رکھتا ہے، قابل فہم لیکن مکمل طور پر غلط معلومات پیدا کرتا ہے۔
- نجی ڈیٹا تک رسائی نہیں: ایک عام LLM کے پاس آپ کی کمپنی کی اندرونی دستاویزات، ٹکٹوں، یا کوڈ بیس تک رسائی نہیں ہے۔
RAG ان تینوں مسائل کو حل کرتا ہے، کیوری کے وقت بیرونی ذرائع سے حاصل کردہ متعلقہ سیاق و سباق ماڈل کو فراہم کر کے۔
RAG کیا ہے؟
ریٹریول-آگمینٹڈ جنریشن ایک فن تعمیر ہے جو LLM کو بھیجے گئے پرامپٹ کو بیرونی نالج بیس سے حاصل کردہ معلومات سے افزودہ کرتا ہے۔ ماڈل کے پیرامیٹرک علم پر مکمل انحصار کرنے کی بجائے، RAG پہلے متعلقہ معلومات تلاش کرتا ہے اور پھر اسے پرامپٹ میں داخل کرتا ہے، ماڈل کو درست، بنیاد پر مبنی جوابات پیدا کرنے کے قابل بناتا ہے۔
RAG تفصیل سے کیسے کام کرتا ہے
RAG فن تعمیر دو اہم مراحل پر مشتمل ہے: انڈیکسنگ (آف لائن) اور ریٹریول + جنریشن (آن لائن)۔
مرحلہ 1: انڈیکسنگ (دستاویز انجیشن)
انڈیکسنگ کا مرحلہ آپ کے دستاویزات کو سیمینٹک تلاش کے لیے تیار کرتا ہے۔ یہ چار اقدامات پر مشتمل ہے۔
1. دستاویز لوڈنگ
دستاویزات کسی بھی ذریعے سے آ سکتی ہیں: PDF فائلز، ویب صفحات، ڈیٹابیسز، Markdown فائلز، APIs۔ Document Loader ان دستاویزات کو پڑھتا ہے اور انہیں منظم متن میں تبدیل کرتا ہے۔
2. متن تقسیم (Chunking)
LLMs کی سیاق و سباق کی ونڈو محدود ہوتی ہے، اور دستاویزات بہت لمبی ہو سکتی ہیں۔ Text Splitter دستاویزات کو chunks نامی چھوٹے ٹکڑوں میں تقسیم کرتا ہے۔ چنکنگ کا معیار اہم ہے: بہت چھوٹے chunks سیاق و سباق کھو دیتے ہیں، جبکہ بہت بڑے chunks مطابقت کو کم کر دیتے ہیں۔
سب سے عام حکمت عملیاں ہیں:
- ریکرسو کریکٹر اسپلٹنگ:
\n\n،\n،.جیسے جداکاروں کا استعمال کرتے ہوئے متن کو بار بار تقسیم کرتا ہے، دستاویز کی ساخت کا احترام کرتے ہوئے۔ - سیمینٹک اسپلٹنگ: متن میں قدرتی وقفے تلاش کرنے کے لیے embeddings استعمال کرتا ہے۔
- Chunk اوورلیپ: حدود پر سیاق و سباق محفوظ رکھنے کے لیے لگاتار chunks کے درمیان اوورلیپ شامل کرتا ہے۔
3. Embedding
ہر chunk کو ایک embedding ماڈل (جیسے OpenAI کا text-embedding-3-small) کے ذریعے ایک عددی ویکٹر (embedding) میں تبدیل کیا جاتا ہے۔ یہ ویکٹرز متن کے سیمینٹک معنی کو حاصل کرتے ہیں: ملتے جلتے معانی والے جملوں کے ویکٹرز کثیر جہتی فضا میں قریب ہوں گے۔
4. Vector Store
ویکٹرز ایک Vector Store (یا ویکٹر ڈیٹابیس) میں محفوظ کیے جاتے ہیں، جیسے ChromaDB، Pinecone، Weaviate، یا FAISS۔ یہ ڈیٹابیس مشابہت کی تلاش کے لیے بہینہ بنایا گیا ہے: ایک کیوری دیے جانے پر، یہ سب سے ملتے جلتے ویکٹرز (اور اس لیے سب سے متعلقہ ٹیکسٹ chunks) تلاش کرتا ہے۔
مرحلہ 2: ریٹریول + جنریشن
جب صارف سوال پوچھتا ہے:
- سوال کو اسی embedding ماڈل کا استعمال کرتے ہوئے ایک embedding میں تبدیل کیا جاتا ہے۔
- Vector Store مشابہت کی تلاش کے ذریعے سب سے ملتے جلتے chunks تلاش کرتا ہے (عام طور پر cosine similarity یا Euclidean فاصلہ)۔
- حاصل کردہ chunks کو سیاق و سباق کے طور پر پرامپٹ میں داخل کیا جاتا ہے۔
- LLM فراہم کردہ سیاق و سباق کی بنیاد پر جواب تیار کرتا ہے۔
LangChain کے ساتھ RAG پائپ لائن بنانا
LangChain LLM پر مبنی ایپلی کیشنز بنانے کے لیے سب سے مقبول Python (اور JavaScript) فریم ورک ہے۔ یہ RAG پائپ لائن کے ہر جزو کے لیے اعلیٰ سطحی تجریدات فراہم کرتا ہے۔
انسٹالیشن
pip install langchain langchain-openai langchain-community chromadb
مرحلہ 1: دستاویزات لوڈ کریں
LangChain مختلف ڈیٹا سورسز کے لیے درجنوں Document Loaders فراہم کرتا ہے۔
from langchain_community.document_loaders import ( PyPDFLoader, WebBaseLoader, DirectoryLoader, TextLoader, ) # Load a PDF pdf_loader = PyPDFLoader("docs/manual.pdf") pdf_docs = pdf_loader.load() # Load a web page web_loader = WebBaseLoader("https://docs.example.com/guide") web_docs = web_loader.load() # Load all .md files from a directory dir_loader = DirectoryLoader("./knowledge_base", glob="**/*.md", loader_cls=TextLoader) md_docs = dir_loader.load() all_docs = pdf_docs + web_docs + md_docs
مرحلہ 2: دستاویزات کو Chunks میں تقسیم کریں
from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, chunk_overlap=200, separators=["\n\n", "\n", ". ", " ", ""], ) chunks = text_splitter.split_documents(all_docs) print(f"Original documents: {len(all_docs)}, Chunks: {len(chunks)}")
chunk_overlap پیرامیٹر بہت اہم ہے: یہ لگاتار chunks کے درمیان اوورلیپ بناتا ہے تاکہ حدود پر سیاق و سباق ضائع نہ ہو۔
مرحلہ 3: Embeddings اور Vector Store بنائیں
from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma embedding_model = OpenAIEmbeddings(model="text-embedding-3-small") vectorstore = Chroma.from_documents( documents=chunks, embedding=embedding_model, persist_directory="./chroma_db", )
مرحلہ 4: Retriever بنائیں
Retriever وہ جزو ہے جو، ایک کیوری دیے جانے پر، vector store سے سب سے متعلقہ chunks حاصل کرتا ہے۔
retriever = vectorstore.as_retriever( search_type="similarity", search_kwargs={"k": 4}, ) relevant_docs = retriever.invoke("How does authentication work?") for doc in relevant_docs: print(doc.page_content[:200]) print("---")
مرحلہ 5: RAG چین بنائیں
اب آئیے سب کچھ ایک LLM اور پرامپٹ ٹیمپلیٹ کے ساتھ جوڑیں۔
from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser llm = ChatOpenAI(model="gpt-4o", temperature=0) prompt = ChatPromptTemplate.from_template(""" Answer the question based only on the provided context. If the context does not contain enough information, say you don't know. Context: {context} Question: {question} Answer: """) def format_docs(docs): return "\n\n".join(doc.page_content for doc in docs) rag_chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) response = rag_chain.invoke("How does authentication work in the system?") print(response)
RAG کی جدید تکنیکیں
بنیادی پائپ لائن اچھی طرح کام کرتی ہے، لیکن جواب کے معیار کو نمایاں طور پر بہتر بنانے کے لیے کئی تکنیکیں ہیں۔
ملٹی-کیوری ریٹریول
بعض اوقات صارف کی کیوری مبہم ہوتی ہے یا دستاویزات میں استعمال ہونے والی زبان سے ہم آہنگ نہیں ہوتی۔ Multi-Query Retriever خود بخود اصل سوال کے مختلف ورژن تیار کرتا ہے تاکہ متعدد نقطہ نظر حاصل ہوں۔
from langchain.retrievers import MultiQueryRetriever multi_retriever = MultiQueryRetriever.from_llm( retriever=vectorstore.as_retriever(), llm=llm, ) docs = multi_retriever.invoke("What are the security best practices?")
سیاقی کمپریشن
ایک chunk کا سارا مواد کیوری سے متعلق نہیں ہوتا۔ Contextual Compression Retriever ہر حاصل کردہ chunk سے صرف متعلقہ حصے نکالنے کے لیے ایک LLM استعمال کرتا ہے۔
from langchain.retrievers import ContextualCompressionRetriever from langchain.retrievers.document_compressors import LLMChainExtractor compressor = LLMChainExtractor.from_llm(llm) compression_retriever = ContextualCompressionRetriever( base_compressor=compressor, base_retriever=retriever, )
ہائبرڈ تلاش
خالص سیمینٹک تلاش ہمیشہ بہترین نہیں ہوتی۔ ہائبرڈ تلاش بہتر نتائج حاصل کرنے کے لیے سیمینٹک تلاش (embeddings) کو لغوی تلاش (BM25، کی ورڈ میچنگ) کے ساتھ ملاتی ہے۔
from langchain.retrievers import EnsembleRetriever from langchain_community.retrievers import BM25Retriever bm25_retriever = BM25Retriever.from_documents(chunks) bm25_retriever.k = 4 semantic_retriever = vectorstore.as_retriever(search_kwargs={"k": 4}) hybrid_retriever = EnsembleRetriever( retrievers=[bm25_retriever, semantic_retriever], weights=[0.4, 0.6], )
مکالماتی RAG (میموری کے ساتھ)
ایک RAG چیٹ بوٹ بنانے کے لیے جو بات چیت کا سیاق و سباق یاد رکھے، آپ کو ایسی میموری شامل کرنی ہوگی جو بات چیت کی تاریخ کو مدنظر رکھتے ہوئے صارف کے سوالات دوبارہ تشکیل دے۔
from langchain.chains import create_history_aware_retriever from langchain_core.prompts import MessagesPlaceholder contextualize_prompt = ChatPromptTemplate.from_messages([ ("system", "Given the chat history and the user's latest question, " "reformulate the question so it is understandable without the history."), MessagesPlaceholder("chat_history"), ("human", "{input}"), ]) history_aware_retriever = create_history_aware_retriever( llm, retriever, contextualize_prompt )
بہترین طریقے
- صحیح chunk سائز کا انتخاب کریں: مختلف سائز (500-1500 ٹوکنز) کے ساتھ تجربہ کریں۔ درست جوابات کے لیے چھوٹے chunks، وسیع تر سیاق و سباق کے لیے بڑے chunks۔
- دستاویز میٹا ڈیٹا استعمال کریں: chunks میں میٹا ڈیٹا کے طور پر ماخذ، تاریخ اور زمرہ شامل کریں۔ یہ ریٹریول کے دوران نتائج فلٹر کرنے کی اجازت دیتا ہے۔
- معیار کا جائزہ لیں: faithfulness، relevancy اور context precision جیسے میٹرکس ماپنے کے لیے RAGAS جیسے فریم ورک استعمال کریں۔
- دستاویز اپ ڈیٹس کا انتظام کریں: اپنے ڈیٹا سورسز کے ساتھ vector store کو ہم آہنگ رکھنے کے لیے دوبارہ انجیشن پائپ لائن نافذ کریں۔
- re-ranker شامل کریں: ابتدائی ریٹریول کے بعد، اصل مطابقت کی بنیاد پر نتائج کو دوبارہ ترتیب دینے کے لیے re-ranking ماڈل (جیسے Cohere Rerank) استعمال کریں۔
نتیجہ
RAG ان AI ایپلی کیشنز کی تعمیر کے لیے معیاری فن تعمیر بن گیا ہے جن کو مخصوص، تازہ ترین علم تک رسائی کی ضرورت ہے۔ LangChain پائپ لائن کے ہر جزو کے لیے تجریدات فراہم کرتے ہوئے عمل درآمد کو بہت آسان بناتا ہے۔
اگلے اقدامات:
- مقامی طور پر تجربہ کریں: پائپ لائن سے واقفیت حاصل کرنے کے لیے ChromaDB اور چند دستاویزات سے شروع کریں۔
- LangSmith دریافت کریں: پروڈکشن میں اپنی چینز کی نگرانی اور ڈیبگ کرنے کے لیے LangSmith استعمال کریں۔
- مختلف embedding ماڈلز آزمائیں:
text-embedding-3-small،text-embedding-3-largeاور Sentence Transformers کے اوپن سورس ماڈلز کا موازنہ کریں۔ - دستاویزات چیک کریں: LangChain دستاویزات ایک بہترین اور مسلسل اپ ڈیٹ ہونے والا ذریعہ ہے۔