RAG কী?

LLM-এর সাথে RAG কেন দরকার? — Retrieval, Embedding, Vector Search ও Generation-এর সম্পূর্ণ Mental Model (Series 1, Episode 01)

📑 বিষয়বস্তু

🧩 ১. Introduction: একটি বাস্তব সমস্যা দিয়ে শুরু

ধরুন আপনার কাছে আছে:

১০,০০০ PDF documents ১,০০,০০০ company documents ৪০,০০০ Hadith records ৬,০০০ Quran verses

এবং আপনি একটি প্রশ্ন করতে চান:

"Knowledge base অনুযায়ী ধৈর্য (patience) সম্পর্কে কী বলা হয়েছে?"

স্বাভাবিক প্রশ্ন হলো — কেন আমরা এই সব document সরাসরি একটি LLM-কে পাঠিয়ে দিচ্ছি না? LLM তো টেক্সট পড়ে উত্তর দিতে পারে।

কেন সব document সরাসরি LLM-কে পাঠানো যায় না?

কারণ ১ — Context Window সীমিত।
প্রতিটি LLM-এর একটি নির্দিষ্ট context window আছে (একবারে কতটুকু text পড়তে পারে, token-এ পরিমাপ করা হয়)। ৪১,০০০+ document বা ১,১০,০০০+ PDF কখনোই একটি single request-এ পাঠানো সম্ভব না।

কারণ ২ — খরচ ও গতি।
প্রতিটি token processing-এর একটি খরচ ও সময় আছে। পুরো knowledge base প্রতিটি প্রশ্নের সাথে পাঠানো practically অসম্ভব ও ব্যয়বহুল।

কারণ ৩ — Relevance।
"ধৈর্য" সম্পর্কিত প্রশ্নের জন্য মাত্র কয়েকটি অংশ প্রাসঙ্গিক (relevant) — বাকি হাজার হাজার document সম্পূর্ণ অপ্রাসঙ্গিক। এগুলো পাঠানো শুধু noise বাড়ায়।

তাহলে সমাধান কী? সমাধানটা আসলে খুব স্বাভাবিক যুক্তিতে দাঁড়িয়ে আছে:

User Question ↓ Find Relevant Information ↓ Give Relevant Information to LLM ↓ LLM Generates Answer

অর্থাৎ, পুরো knowledge base না পাঠিয়ে — শুধুমাত্র প্রশ্নের সাথে সম্পর্কিত অংশটুকু খুঁজে বের করে, সেটুকুই LLM-কে দেওয়া হয়। এই সহজ ধারণাটির একটি নাম আছে:

Retrieval + Augmented + Generation = RAG

প্রতিটি শব্দ আলাদা করে দেখা যাক:

শব্দ মানে
Retrieval প্রাসঙ্গিক তথ্য খুঁজে বের করা (knowledge base থেকে)
Augmented সেই তথ্য দিয়ে মূল prompt/context-কে "সমৃদ্ধ" (augment) করা
Generation সেই সমৃদ্ধ context ব্যবহার করে LLM দিয়ে natural-language উত্তর তৈরি করা
RAG (Retrieval-Augmented Generation) মূলত এই তিনটি ধাপের সমন্বয় — আগে relevant তথ্য খুঁজে বের করা, তারপর সেই তথ্য দিয়ে LLM-এর prompt সমৃদ্ধ করা, এবং শেষে LLM দিয়ে উত্তর generate করা।

এই Episode-এ আমরা কোনো FAISS code লিখব না। আগে একটি শক্ত mental model তৈরি করব — কেন RAG দরকার, এর প্রতিটি অংশ কী কাজ করে, এবং এই অংশগুলো কীভাবে একসাথে বসে। পরবর্তী Episode-গুলোতে আমরা ধাপে ধাপে এই architecture বাস্তবায়ন করব।

🤖 ২. LLM কী?

RAG বোঝার আগে LLM সম্পর্কে একটি স্পষ্ট, ব্যবহারিক ধারণা থাকা দরকার — গভীর transformer গণিতে না গিয়ে।

LLM (Large Language Model) হলো একটি model, যা বিপুল পরিমাণ text data দিয়ে train করা হয়েছে, এবং যা একটি ইনপুট text (prompt) দেখে পরবর্তী, সম্ভাব্য text generate করতে পারে।

গুরুত্বপূর্ণ পরিভাষা

টার্ম সহজ ব্যাখ্যা
Training বিপুল পরিমাণ text data দেখিয়ে model-এর ভেতরের parameter-গুলো সমন্বয় (adjust) করার প্রক্রিয়া — এটি একবার, আগে থেকে করা হয়
Inference Training শেষ হওয়া model ব্যবহার করে বাস্তব সময়ে (real-time) নতুন input-এর জন্য output তৈরি করা
Parameters Training-এর সময় শেখা numerical মান, যেগুলো model-এর "জ্ঞান" ধারণ করে (কোটি থেকে বিলিয়ন সংখ্যক হতে পারে)
Token Text-কে ভাঙার ছোট একক (শব্দ, শব্দাংশ, বা character-এর সমষ্টি হতে পারে) — LLM টেক্সট নয়, token নিয়ে কাজ করে
Context Window একবারে LLM কতগুলো token (input + output মিলিয়ে) প্রক্রিয়া করতে পারে তার সীমা
Prompt LLM-কে দেওয়া input text, যার ভিত্তিতে এটি output তৈরি করে
Generation Prompt-এর ভিত্তিতে LLM-এর token-by-token output তৈরি করার প্রক্রিয়া
এই Episode-এ আমরা transformer architecture, attention mechanism, বা training math নিয়ে বিস্তারিত যাব না। এখানে লক্ষ্য শুধু এটুকু বোঝা — LLM একটি prompt নেয়, এবং তার training-এ শেখা প্যাটার্ন অনুযায়ী একটি output generate করে।

🔒 ৩. LLM-এর সীমাবদ্ধতা: Training Knowledge ≠ Private Database

RAG বোঝার জন্য এই একটি distinction সবচেয়ে গুরুত্বপূর্ণ:

Training Knowledge ≠ Your Private Database

একটি LLM যখন train করা হয়, তখন এটি একটি নির্দিষ্ট সময় পর্যন্ত সংগৃহীত publicly available text থেকে শেখে। Training শেষ হওয়ার পর, model-এর "জ্ঞান" সেই মুহূর্তে freeze হয়ে যায়।

এর মানে, একটি LLM স্বয়ংক্রিয়ভাবে নিচের কোনোটির সাথেই পরিচিত না:

উদাহরণস্বরূপ, আমাদের Islamic RAG project-এর ক্ষেত্রে — একটি সাধারণ, general-purpose LLM হয়তো ইসলাম সম্পর্কে সাধারণ জ্ঞান রাখে (কারণ এটি public training data-তে ছিল), কিন্তু এটি নির্দিষ্টভাবে আমাদের curated ৪১,০০০+ entry-র Quran ও Hadith dataset-এর সাথে পরিচিত না, এবং নির্দিষ্ট reference/সূত্র (citation) দিয়ে উত্তর দিতে পারবে না — যতক্ষণ না আমরা সেই তথ্য স্পষ্টভাবে সরবরাহ করি।

মূল সমস্যা: LLM-এর training knowledge static (স্থির) এবং general। কিন্তু আমাদের প্রয়োজন প্রায়ই dynamic (পরিবর্তনশীল) এবং specific (নির্দিষ্ট) — যেমন সাম্প্রতিক document, ব্যক্তিগত data, বা কোনো নির্দিষ্ট curated dataset। RAG ঠিক এই ফাঁকটাই পূরণ করে।

🌀 ৪. Hallucination কী?

যখন একটি LLM-এর কাছে সঠিক তথ্য থাকে না, তখন সেটি কী করে? এটি সাধারণত "জানি না" বলে না — বরং এটি একটি plausible (বিশ্বাসযোগ্য শোনায় এমন) কিন্তু ভুল উত্তর তৈরি করতে পারে। এই সমস্যাটির নাম Hallucination

ইংরেজি term: Hallucination
সহজ বাংলায়: LLM যখন এমন তথ্য তৈরি করে যা শুনতে স্বাভাবিক ও আত্মবিশ্বাসী মনে হয়, কিন্তু আসলে ভুল, বানানো, বা যাচাইযোগ্য নয় — তখন সেটাকে Hallucination বলা হয়।
উদাহরণ: কাউকে যদি জিজ্ঞাসা করা হয় একটি নির্দিষ্ট Hadith-এর exact reference number কী, আর সে সঠিক উত্তর না জানে, তাহলে দুই ধরনের মানুষ থাকে — একজন বলে "আমি নিশ্চিত না", আরেকজন আত্মবিশ্বাসের সাথে একটি ভুল নম্বর বলে দেয়। একটি সাধারণ LLM, প্রাসঙ্গিক context ছাড়া প্রশ্ন করা হলে, অনেকটা দ্বিতীয় মানুষটির মতো আচরণ করতে পারে।

কেন এটা হয়? কারণ LLM মূলত পরিসংখ্যানগতভাবে (statistically) সবচেয়ে সম্ভাব্য পরবর্তী token predict করে। এটি "সত্য যাচাই" করার কোনো built-in mechanism রাখে না — এটি শুধু ভাষাগতভাবে সামঞ্জস্যপূর্ণ (coherent) টেক্সট তৈরি করতে পারদর্শী।

RAG কি Hallucination সম্পূর্ণ দূর করে?

না। RAG প্রাসঙ্গিক external context সরবরাহ করে model-কে সঠিক তথ্যের দিকে "grounded" (ভিত্তিযুক্ত) করার চেষ্টা করে, যার ফলে hallucination কমতে পারে। কিন্তু এটি সম্পূর্ণ সমাধান নয়। Retrieval-এর মান (quality), context-এর প্রাসঙ্গিকতা, prompt design, এবং model-এর নিজস্ব আচরণ — এই সবকিছুর উপর চূড়ান্ত ফলাফল নির্ভর করে।
যদি retrieval ধাপ ভুল বা অপ্রাসঙ্গিক document নিয়ে আসে, তাহলে LLM সেই ভুল তথ্যের উপর ভিত্তি করেই একটি confidently ভুল উত্তর দিতে পারে। তাই RAG-এ শুধু "একটা LLM-এর সামনে কিছু text রেখে দেওয়া" যথেষ্ট না — প্রতিটি ধাপের quality গুরুত্বপূর্ণ।

⚖️ ৫. Traditional LLM Usage বনাম RAG

এখন দুটো approach পাশাপাশি রেখে পার্থক্য স্পষ্ট করা যাক।

🔹 Traditional LLM Usage

User ↓ Prompt ↓ LLM ↓ Answer
শুধুমাত্র model-এর training knowledge-এর উপর নির্ভরশীল।
🔸 RAG

User ↓ Query ↓ Retriever ↓ Relevant Documents ↓ Context ↓ LLM ↓ Grounded Answer
External knowledge base থেকে প্রাসঙ্গিক তথ্য এনে ব্যবহার করা হয়।

তুলনামূলক টেবিল

বিষয় Traditional LLM RAG
তথ্যের উৎস শুধুমাত্র training data Training data + external knowledge base
নতুন/private data স্বয়ংক্রিয়ভাবে জানে না Retrieval-এর মাধ্যমে দেওয়া যায়
Hallucination ঝুঁকি তুলনামূলক বেশি (context ছাড়া অনুমান করে) কম হতে পারে (grounded context থাকলে), তবে শূন্য নয়
Source/Citation দেখানো সাধারণত সম্ভব না Retrieved document থেকে source দেখানো সম্ভব
Knowledge আপডেট শুধু re-training/fine-tuning দিয়ে শুধু knowledge base আপডেট করলেই যথেষ্ট
জটিলতা কম (শুধু prompt পাঠানো) বেশি (retrieval pipeline maintain করতে হয়)

🧠 ৬. RAG কী? (Retrieval + Augmented + Generation)

RAG (Retrieval-Augmented Generation) হলো এমন একটি architecture, যেখানে একটি LLM উত্তর তৈরি করার আগে, একটি external knowledge base থেকে প্রাসঙ্গিক তথ্য retrieve (খুঁজে বের) করা হয়, এবং সেই তথ্য LLM-এর prompt-এ context হিসেবে যুক্ত (augment) করা হয়।

RAG কেন তৈরি হয়েছিল?

সহজভাবে: RAG আমাদের বলে — "LLM-কে সব কিছু মুখস্থ করতে বলার দরকার নেই। বরং LLM-কে দরকারের সময় সঠিক বই-এর সঠিক পাতা খুলে দেখিয়ে দাও।"

🏗️ ৭. RAG Architecture — সম্পূর্ণ ডায়াগ্রাম, বক্স বাই বক্স

এখন সম্পূর্ণ RAG architecture-টি একসাথে দেখি:

┌─────────────────┐ │ User │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ User Query │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Query Embedding │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Vector Search │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Relevant Chunks │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Context Builder │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ LLM │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Answer │ └─────────────────┘

প্রতিটি বক্স আলাদা করে ব্যাখ্যা করা যাক:

ধাপ কী ঘটে
User ব্যবহারকারী একটি প্রশ্ন নিয়ে system-এ আসে
User Query প্রশ্নটি একটি raw text string হিসেবে system-এ প্রবেশ করে (যেমন: "ধৈর্য নিয়ে কী বলা আছে?")
Query Embedding প্রশ্নটিকে একটি embedding model দিয়ে একটি numerical vector-এ রূপান্তর করা হয়
Vector Search সেই query vector-এর সাথে knowledge base-এর সব document vector-এর similarity তুলনা করা হয়
Relevant Chunks সবচেয়ে similar (Top-K) document অংশগুলো (chunk) নির্বাচিত হয়
Context Builder নির্বাচিত chunk-গুলো একত্র করে, মূল প্রশ্নের সাথে যুক্ত করে একটি সুসংগঠিত prompt তৈরি করা হয়
LLM এই সমৃদ্ধ (augmented) prompt পেয়ে LLM একটি উত্তর generate করে
Answer চূড়ান্ত, প্রাসঙ্গিক তথ্যে ভিত্তিযুক্ত (grounded) উত্তর ব্যবহারকারীকে ফেরত দেওয়া হয়

🔀 ৮. দুটি প্রধান Pipeline: Ingestion vs Query

RAG বোঝার সময় সবচেয়ে গুরুত্বপূর্ণ একটি বিভ্রান্তি এড়ানো দরকার — RAG আসলে একটি নয়, দুটি আলাদা pipeline-এর সমন্বয়। এই পার্থক্যটি স্পষ্টভাবে বোঝা অত্যন্ত জরুরি।

১. Ingestion Pipeline (Offline)

Documents ↓ Parsing ↓ Cleaning ↓ Chunking ↓ Embedding ↓ Vector Index ↓ Metadata Storage
এই pipeline চলে user প্রশ্ন করার আগেই, সাধারণত একবার (বা document আপডেট হলে আবার)। এখানে raw document (PDF, text file, database record) পড়া, পরিষ্কার করা (cleaning), ছোট ছোট অংশে ভাগ করা (chunking), প্রতিটি অংশের embedding তৈরি করা, এবং সেগুলো একটি vector index-এ সংরক্ষণ করা হয়।

আমাদের Islamic RAG project-এ এটি হলো সেই ধাপ যেখানে Quran ও Hadith dataset প্রক্রিয়াজাত করে faiss_index.bin এবং documents.npy ফাইল দুটি তৈরি করা হয়েছে।

২. Query Pipeline (Online)

User Query ↓ Query Embedding ↓ Similarity Search ↓ Top-K Chunks ↓ Optional Reranking ↓ Context Construction ↓ LLM ↓ Answer
এই pipeline চলে প্রতিবার ব্যবহারকারী প্রশ্ন করলে, real-time-এ। Ingestion Pipeline-এ আগে থেকে তৈরি করা vector index ব্যবহার করে এখানে দ্রুত search করা হয় — পুরো document আবার প্রক্রিয়া করার দরকার হয় না।
মনে রাখার সহজ উপায়: Ingestion Pipeline = লাইব্রেরি সাজানো (একবার)। Query Pipeline = লাইব্রেরিতে বই খোঁজা (প্রতিবার)। লাইব্রেরি একবার সাজানো থাকলে, প্রতিবার বই খোঁজা অনেক দ্রুত হয়।

🧬 ৯. Embedding কী?

Embedding হলো এমন একটি numerical representation, যেখানে একটি text-এর semantic meaning একটি vector-এর মাধ্যমে প্রকাশ করা হয়। একটি embedding model কোনো text (শব্দ, বাক্য, বা অনুচ্ছেদ) ইনপুট নেয়, এবং একটি নির্দিষ্ট সংখ্যক dimension-এর একটি vector (সংখ্যার তালিকা) output দেয়।

কেন এটা দরকার?

নিচের দুটি বাক্য লক্ষ্য করুন:

"How can I improve my patience?" "What does Islam teach about patience?"

এই দুটি বাক্য একই শব্দ ব্যবহার করে না ("improve" বনাম "teach"), কিন্তু semantically (অর্থের দিক থেকে) সম্পর্কিত — দুটোই "patience" (ধৈর্য) সম্পর্কিত তথ্য খুঁজছে। একটি ভালো embedding model এই দুই বাক্যকে vector space-এ কাছাকাছি অবস্থানে রাখবে, কারণ তাদের অর্থ কাছাকাছি।

এখানেই traditional keyword search-এর সীমাবদ্ধতা প্রকাশ পায়। Keyword search শুধু exact শব্দ মিল খোঁজে। "improve patience" আর "teach about patience" — শব্দগতভাবে ভিন্ন হওয়ায়, শুধু keyword দিয়ে খুঁজলে সম্পর্কটি ধরা নাও পড়তে পারে। কিন্তু Embedding-ভিত্তিক semantic search এই সম্পর্ক ধরতে পারে, কারণ এটি শব্দ নয়, অর্থ তুলনা করে।
এই Episode-এ আমরা embedding model কীভাবে ভেতরে ভেতরে কাজ করে (neural network architecture, training objective) তা নিয়ে বিস্তারিত যাব না — এটি সিরিজের একটি পরবর্তী Episode-এ আলাদাভাবে গভীরভাবে আলোচনা করা হবে। এখানে শুধু এটুকু মনে রাখা দরকার: Embedding = text-কে এমন একটি vector-এ রূপান্তর করা, যেখানে অর্থগতভাবে কাছাকাছি text-গুলো vector space-এও কাছাকাছি থাকে।

📐 ১০. Vector ও Vector Search কী?

Embedding তৈরি হওয়ার পর, সেটি ব্যবহার করে search করার পুরো প্রক্রিয়াটি দেখা যাক:

Text ↓ Embedding Model ↓ Vector ↓ Vector Index ↓ Similarity Search
Embedding বনাম Vector — একটি সূক্ষ্ম কিন্তু গুরুত্বপূর্ণ পার্থক্য:

Embedding = একটি embedding model থেকে তৈরি হওয়া representation (একটি concept/process)
Vector = system-এর মধ্যে ব্যবহৃত হওয়া সেই numerical representation (সংখ্যার তালিকা)

প্রায়ক্ষেত্রে এই দুটো শব্দ একে অপরের বদলে ব্যবহার করা হয়, এবং বাস্তবে একটি embedding-ই একটি vector আকারে সংরক্ষিত হয় — কিন্তু concept হিসেবে এই পার্থক্যটি মাথায় রাখা ভালো, বিশেষ করে যখন "vector" শব্দটি embedding ছাড়া অন্য প্রসঙ্গেও (যেমন one-hot encoding) ব্যবহৃত হতে পারে।

গুরুত্বপূর্ণ পরিভাষা

টার্ম সহজ ব্যাখ্যা
Vector Space সব vector যেখানে অবস্থান করে, এমন একটি বহু-মাত্রিক (multi-dimensional) গাণিতিক space
Dimension প্রতিটি vector-এ কতগুলো সংখ্যা আছে (যেমন 384-dimensional মানে vector-এ ৩৮৪টি সংখ্যা)
Distance দুটি vector একে অপরের থেকে কতটা "দূরে" আছে তার পরিমাপ
Similarity দুটি vector কতটা "কাছাকাছি"/সম্পর্কিত তার পরিমাপ (Distance-এর বিপরীত ধারণা)
Top-K সবচেয়ে বেশি similar এমন K সংখ্যক ফলাফল নির্বাচন করা (যেমন Top-5)

Similarity পরিমাপ করার কয়েকটি common পদ্ধতি

পদ্ধতি সংক্ষিপ্ত ধারণা
Cosine Similarity দুটি vector-এর মধ্যবর্তী কোণ (angle) পরিমাপ করে — vector-এর দৈর্ঘ্য উপেক্ষা করে শুধু দিক (direction) তুলনা করে
Euclidean / L2 Distance দুটি vector-এর মধ্যে সরাসরি জ্যামিতিক দূরত্ব (straight-line distance) পরিমাপ করে
Inner Product / Dot Product দুটি vector-এর উপাদানগুলোর গুণফলের যোগফল — কিছু normalized embedding-এর ক্ষেত্রে cosine similarity-এর সমতুল্য আচরণ করতে পারে
এই তিনটি পদ্ধতি সব ক্ষেত্রে একে অপরের বদলে ব্যবহারযোগ্য নয়। কোনটি ব্যবহার করা হবে তা নির্ভর করে embedding model কীভাবে train হয়েছে এবং vector index কীভাবে configure করা হয়েছে তার উপর। এই বিষয়ে বিস্তারিত আলোচনা সিরিজের "Similarity Metrics" Episode-এ করা হবে।

📦 ১১. FAISS কী? (এবং FAISS বনাম Vector Database)

আমাদের practical Islamic RAG project-এ vector search-এর জন্য FAISS ব্যবহার করা হয়েছে। চলুন এটিকে স্পষ্টভাবে বুঝি।

FAISS

What? (এটা কী?)
FAISS (Facebook AI Similarity Search) হলো dense vector-এর উপর efficient similarity search করার জন্য একটি library।

Why? (কেন দরকার?)
হাজার থেকে মিলিয়ন সংখ্যক vector-এর মধ্যে দ্রুত nearest-neighbor খুঁজে বের করার জন্য।

How? (এটা কীভাবে কাজ করে?)
এটি vector-গুলোকে একটি নির্দিষ্ট গঠনে (index) সংগঠিত করে, এবং সেই index-এর মধ্যে nearest-neighbor search perform করে।

Where? (RAG-এর কোথায় বসে?)
Retrieval ধাপে — query vector-এর সাথে knowledge base-এর vector-গুলোর similarity মেলানোর জায়গায়।

এটা কোন সমস্যার সমাধান করে?
বহু সংখ্যক vector-এর মধ্যে efficient similarity search।

এটা কোন সমস্যার সমাধান করে না?
এটি স্বয়ংক্রিয়ভাবে একটি সম্পূর্ণ document-management বা vector-database প্ল্যাটফর্ম না।
গুরুত্বপূর্ণ: "FAISS একটি vector database" — এই বাক্যটি একটি সরলীকরণ, এবং এটি সম্পূর্ণ সঠিক নয়। এই পার্থক্যটি স্পষ্টভাবে বোঝা দরকার।
FAISS = similarity search library / indexing toolkit (শুধু vector index এবং search algorithm সরবরাহ করে) Vector Database = storage + indexing + metadata + filtering + persistence + API (product অনুযায়ী ভিন্ন হতে পারে — যেমন Qdrant, Chroma, Pinecone, অথবা pgvector-এর মতো PostgreSQL extension)

FAISS নিজে থেকে metadata filtering, multi-user access, built-in persistence layer, বা REST API সরবরাহ করে না (যদিও FAISS index নিজেই save/load করা যায়)। এই কারণে অনেক production system FAISS-কে একটি বড় infrastructure-এর একটি অংশ হিসেবে ব্যবহার করে, অথবা এর বদলে একটি সম্পূর্ণ vector database (যেমন Qdrant, Chroma, বা pgvector) ব্যবহার করে যেখানে এই সুবিধাগুলো built-in থাকে।

আমাদের project-এ FAISS কীভাবে ব্যবহৃত হয়েছে

Islamic_Knowleged_Assistant_RAG_Server repository-তে দুটি মূল artifact আছে:

faiss_index.bin — FAISS দিয়ে তৈরি করা vector index, যেখানে Quran ও Hadith-এর সব document-এর embedding সংরক্ষিত।

documents.npy — প্রতিটি vector-এর সাথে সংশ্লিষ্ট আসল document text (NumPy array আকারে সংরক্ষিত)। FAISS index শুধু vector ও তার position রাখে, তাই আসল text আলাদাভাবে এই ফাইলে maintain করা হয়েছে।

✂️ ১২. Chunking কী?

Chunking হলো একটি বড় document-কে ছোট ছোট, manageable অংশে ভাগ করার প্রক্রিয়া, যাতে প্রতিটি অংশ আলাদাভাবে embed ও retrieve করা যায়।

কেন পুরো document-কে একটি single vector-এ embed করা যায় না?

Large Document ↓ Chunking ↓ ┌──────┬──────┬──────┬──────┐ │Chunk1│Chunk2│Chunk3│Chunk4│ └──────┴──────┴──────┴──────┘ ↓ Embeddings

আমাদের Islamic RAG project-এ এই ধারণাটি স্বাভাবিকভাবেই প্রযোজ্য — প্রতিটি Quran verse বা Hadith entry ইতিমধ্যেই একটি স্বাভাবিক, ছোট, স্বয়ংসম্পূর্ণ একক (unit), যা chunk হিসেবে কাজ করে। এটি একধরনের "natural chunking" — dataset-এর গঠন নিজেই ইতিমধ্যে ছোট, অর্থবহ অংশে বিভক্ত।

Chunking-এর গুরুত্বপূর্ণ প্যারামিটার ও কৌশল

ধারণা সংক্ষিপ্ত ব্যাখ্যা
Chunk Size প্রতিটি chunk কত বড় হবে (token বা character সংখ্যায়)
Chunk Overlap পাশাপাশি chunk-গুলোর মধ্যে কিছু অংশ পুনরাবৃত্তি রাখা, যাতে বাক্যের মাঝখানে কেটে অর্থ না হারায়
Token-based Chunking নির্দিষ্ট সংখ্যক token অনুযায়ী ভাগ করা
Character-based Chunking নির্দিষ্ট সংখ্যক character অনুযায়ী ভাগ করা
Sentence-based Chunking সম্পূর্ণ বাক্য অনুযায়ী ভাগ করা, যাতে অর্থ ভেঙে না যায়
Paragraph-based Chunking অনুচ্ছেদ অনুযায়ী ভাগ করা
Recursive Chunking ধাপে ধাপে বড় থেকে ছোট বিভাজক (paragraph → sentence → word) ব্যবহার করে ভাগ করা
Semantic Chunking নির্দিষ্ট সংখ্যা অনুযায়ী না ভেঙে, অর্থের পরিবর্তন (topic shift) অনুযায়ী ভাগ করা
এই Episode-এ প্রতিটি কৌশলের বিস্তারিত বাস্তবায়ন আলোচনা করা হচ্ছে না — শুধু এটুকু বোঝা গুরুত্বপূর্ণ যে chunking একটি core RAG design decision, এবং ভুল chunking strategy retrieval quality-কে সরাসরি প্রভাবিত করে। সিরিজের "Chunking Strategies" Episode-এ আমরা প্রতিটি কৌশল বিস্তারিতভাবে তুলনা করব।

🔍 ১৩. Hybrid Search — সংক্ষিপ্ত পরিচিতি

Semantic search (embedding-ভিত্তিক) সবসময় সেরা সমাধান নয়। কিছু ক্ষেত্রে সাধারণ keyword search অনেক বেশি কার্যকর।

উদাহরণ ১: একজন ব্যবহারকারী সার্চ করল —
"ERR_CONNECTION_REFUSED"

এখানে keyword search অত্যন্ত কার্যকর, কারণ ব্যবহারকারী একটি exact error code খুঁজছে — semantic similarity এখানে তেমন গুরুত্বপূর্ণ না।

উদাহরণ ২: একজন ব্যবহারকারী প্রশ্ন করল —
"How can I become more patient?"

এখানে semantic search অনেক বেশি সহায়ক, কারণ knowledge base-এ হয়তো ঠিক এই শব্দগুলো নেই, কিন্তু অর্থগতভাবে সম্পর্কিত content আছে।
Keyword Search + Semantic Search ↓ Hybrid Search
Hybrid Search হলো keyword-based (lexical) search এবং embedding-based (semantic) search — উভয়ের ফলাফল একসাথে ব্যবহার করার একটি কৌশল, যাতে দুই ধরনের প্রশ্নের ক্ষেত্রেই ভালো ফলাফল পাওয়া যায়।
Production-grade RAG system প্রায়ই দুই ধরনের retrieval কৌশল একসাথে combine করে। কিন্তু এই বিষয়ের বিস্তারিত (যেমন BM25 algorithm, dense retrieval-এর সাথে score fusion, এবং Reciprocal Rank Fusion বা RRF) সিরিজের পরবর্তী "Advanced Retrieval" Phase-এ আলোচনা করা হবে। এই Episode-এ শুধু concept-টুকু পরিচয় করানো হলো।

🎯 ১৪. Reranking — সংক্ষিপ্ত পরিচিতি

Vector search সাধারণত দ্রুত কিন্তু আনুমানিক (approximate) ফলাফল দেয়। এই ফলাফলের মান আরও উন্নত করার জন্য একটি অতিরিক্ত ধাপ ব্যবহার করা যায়, যাকে বলে Reranking

Query ↓ Retrieve Top 50 ↓ Reranker ↓ Best 5 ↓ LLM
প্রথমে একটি দ্রুত, তুলনামূলক কম নিখুঁত retrieval ধাপ (যেমন FAISS দিয়ে Top-50 vector খোঁজা) চালানো হয়। তারপর একটি আলাদা, তুলনামূলক ধীর কিন্তু বেশি নিখুঁত reranker model সেই ৫০টি ফলাফলকে আবার মূল্যায়ন করে সবচেয়ে প্রাসঙ্গিক কয়েকটি (যেমন Top-5) বেছে নেয়, যেগুলো তখন LLM-কে দেওয়া হয়।
Retrieval এবং Reranking দুটি আলাদা ধাপ — Retrieval দ্রুত অনেক candidate খুঁজে বের করে, আর Reranking সেই candidate-গুলোর মধ্যে থেকে সবচেয়ে ভালোগুলো নিখুঁতভাবে বাছাই করে। এই Episode-এ আমরা Reranking বাস্তবায়ন করছি না — শুধু ধারণাটি পরিচয় করালাম, যাতে পরবর্তী Episode-এ যখন এটি নিয়ে বিস্তারিত আলোচনা হবে তখন প্রেক্ষাপট পরিষ্কার থাকে।

🆚 ১৫. RAG বনাম Fine-tuning

আরেকটি সাধারণ বিভ্রান্তি — RAG আর Fine-tuning কি একই জিনিস? না। এই দুটো ভিন্ন সমস্যার সমাধান করে।

RAG → Inference-এর সময় external knowledge সরবরাহ করে Fine-tuning → অতিরিক্ত training-এর মাধ্যমে model-এর behavior/parameter পরিবর্তন করে
বিষয় RAG Fine-tuning
কাজ করে কখন Inference (query) সময়ে Training সময়ে (আগে থেকে)
Model পরিবর্তন হয়? না, model অপরিবর্তিত থাকে হ্যাঁ, model-এর parameter আপডেট হয়
নতুন তথ্য যোগ করা Knowledge base আপডেট করলেই যথেষ্ট আবার training/fine-tuning প্রয়োজন
প্রধান ব্যবহার Factual knowledge সরবরাহ করা, source-ভিত্তিক উত্তর Style, tone, নির্দিষ্ট task-এ behavior পরিবর্তন করা
RAG এবং Fine-tuning পরস্পরবিরোধী নয় — বাস্তবে এগুলো একসাথেও ব্যবহার করা যায়। যেমন, একটি model-কে নির্দিষ্ট style-এ উত্তর দেওয়ার জন্য fine-tune করা যায়, এবং একই সাথে RAG দিয়ে তাকে সাম্প্রতিক বা domain-specific তথ্য সরবরাহ করা যায়।

🕌 ১৬. Case Study: আমাদের Islamic RAG Project

এখন পর্যন্ত আলোচিত সব ধারণা একটি বাস্তব, কাজ করা project-এর মাধ্যমে দেখা যাক — Islamic_Knowleged_Assistant_RAG_Server, একটি offline Islamic Knowledge RAG system।

Project-এর বর্তমান Architecture

Quran Dataset (৬,২৩৬+ verses) + Hadith Dataset (৩৫,০০০+ entries) ↓ Document Preparation ↓ SentenceTransformer ↓ Embeddings ↓ FAISS ↓ User Query ↓ Query Embedding ↓ Similarity Search ↓ Relevant Documents ↓ Context ↓ Mistral via Ollama ↓ Answer

রিপোজিটরির বর্ণনা অনুযায়ী, dataset-এ মোট প্রায় ৪১,০০০+ entry আছে (Quran + Hadith মিলিয়ে)।

প্রতিটি অংশ কীভাবে আমাদের আলোচিত concept-এর সাথে মেলে

Project-এর অংশ আমাদের আলোচিত concept
Quran + Hadith Dataset Knowledge Base — raw documents
Document Preparation Ingestion Pipeline-এর Parsing/Cleaning ধাপ; প্রতিটি verse/hadith স্বাভাবিকভাবেই একটি chunk
paraphrase-multilingual-MiniLM-L12-v2 (SentenceTransformer) Embedding Model
faiss_index.bin Vector Index (FAISS)
documents.npy প্রতিটি vector-এর সাথে যুক্ত আসল document text সংরক্ষণ
User Query → Query Embedding → Similarity Search Query Pipeline
Mistral (via Ollama) Generation ধাপের LLM — সম্পূর্ণভাবে local/offline চলে

কেন multilingual embedding model ব্যবহার করা হয়েছে?

paraphrase-multilingual-MiniLM-L12-v2 একটি multilingual embedding model, যার মানে এটি একাধিক ভাষার text-কে একই ধরনের vector space-এ map করতে পারে। Quran ও Hadith dataset-এ Arabic ও English উভয় ভাষার content থাকায়, একটি multilingual model ব্যবহার করার সুবিধা হলো — একজন ব্যবহারকারী English-এ প্রশ্ন করলেও, তার সাথে semantically সম্পর্কিত Arabic বা English content খুঁজে পাওয়া সম্ভব হয়, কারণ উভয় ভাষার embedding একই vector space-এ তুলনাযোগ্য।

স্পষ্টভাবে বলা দরকার — Project বর্তমানে কী করে না

সততার সাথে বলা গুরুত্বপূর্ণ: বর্তমান repository-র বর্ণনা অনুযায়ী এই project-এ বর্তমানে নিচের advanced feature-গুলো implement করা নেই —
Feature বর্তমান অবস্থা
Hybrid Search (keyword + semantic) বর্তমানে implement করা নেই — শুধু FAISS-ভিত্তিক semantic search ব্যবহৃত হয়
Reranking বর্তমানে implement করা নেই
BM25 / Reciprocal Rank Fusion (RRF) বর্তমানে implement করা নেই
Qdrant / pgvector / Chroma-এর মতো dedicated vector database বর্তমানে ব্যবহৃত হয়নি — FAISS index ফাইল (faiss_index.bin) সরাসরি ব্যবহার করা হয়
Semantic Chunking বর্তমানে প্রয়োজন হয়নি, কারণ dataset ইতিমধ্যে verse/hadith অনুযায়ী স্বাভাবিকভাবে বিভক্ত
এগুলো এই project-এর ভবিষ্যৎ উন্নতির সম্ভাব্য দিক (future improvement) হিসেবে বিবেচনা করা যেতে পারে, এবং সিরিজের পরবর্তী, advanced Episode-গুলোতে ঠিক এই feature-গুলোই আমরা ধাপে ধাপে যোগ করার চেষ্টা করব — যাতে এই basic architecture থেকে ধীরে ধীরে একটি production-grade RAG system-এ রূপান্তরিত করা যায়।

💻 ১৭. ছোট Code Walkthrough

এই Episode পুরো system বাস্তবায়ন করছে না — কিন্তু query pipeline-এর মূল ধারণাটি ছোট conceptual code দিয়ে দেখা যাক।

ধাপ ১: সংরক্ষিত FAISS index ও document লোড করা

import faiss import numpy as np # আগে থেকে তৈরি করা vector index লোড করা index = faiss.read_index("faiss_index.bin") # প্রতিটি vector-এর সাথে যুক্ত আসল document text লোড করা documents = np.load("documents.npy", allow_pickle=True)
faiss.read_index(...) Ingestion Pipeline-এ আগে থেকে তৈরি করা vector index টি memory-তে লোড করে। documents.npy ফাইলে সেই vector-গুলোর সাথে সংশ্লিষ্ট আসল text সংরক্ষিত — কারণ FAISS নিজে শুধু vector সংরক্ষণ করে, text নয়।

ধাপ ২: ব্যবহারকারীর প্রশ্নকে embedding-এ রূপান্তর করা

from sentence_transformers import SentenceTransformer model = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2") query_embedding = model.encode( ["What does the Quran say about patience?"] )
এখানে একই embedding model ব্যবহার করা হচ্ছে যা Ingestion Pipeline-এ document embed করার সময়ও ব্যবহৃত হয়েছিল — এটি গুরুত্বপূর্ণ, কারণ query ও document একই vector space-এ থাকতে হবে, নাহলে similarity তুলনা অর্থহীন হয়ে যাবে।

ধাপ ৩: Vector Search চালানো

distances, indices = index.search( query_embedding, k=5 )
index.search(query_embedding, k=5) query vector-এর সাথে সবচেয়ে similar Top-5 vector খুঁজে বের করে। এটি ফেরত দেয় — distances (প্রতিটি ফলাফলের distance/similarity স্কোর) এবং indices (সেই vector-গুলোর position, যা দিয়ে documents array থেকে আসল text বের করা যায়)।

ধাপ ৪: প্রাসঙ্গিক text বের করে Context তৈরি করা

relevant_chunks = [documents[i] for i in indices[0]] context = "\n".join(relevant_chunks)

ধাপ ৫: LLM-কে context সহ প্রশ্ন করা (conceptual)

prompt = f"""নিচের তথ্যের ভিত্তিতে প্রশ্নের উত্তর দাও: {context} প্রশ্ন: What does the Quran say about patience? """ # এই prompt-টি এরপর local Mistral model-কে # Ollama-এর মাধ্যমে পাঠানো হয়, উত্তর তৈরির জন্য
এই পাঁচটি ধাপই মূলত অংশ ৮-এ আলোচিত Query Pipeline-এর একটি সরলীকৃত বাস্তবায়ন। পরের Episode-গুলোতে আমরা প্রতিটি ধাপ আরও গভীরভাবে explore করব — ইনক্লুডিং কীভাবে Ingestion Pipeline চালিয়ে প্রথমে faiss_index.bindocuments.npy তৈরি করা হয়েছিল।

🚧 ১৮. সাধারণ ভুল ধারণা

ভুল ধারণা বাস্তবতা
"RAG মানে LLM-কে fine-tune করা" না। RAG-এ model-এর parameter পরিবর্তন হয় না — inference-এর সময় external context যোগ করা হয়
"RAG ব্যবহার করলে hallucination একদম শূন্য হয়ে যায়" না। RAG hallucination কমাতে সাহায্য করে, কিন্তু retrieval ও prompt quality-এর উপর নির্ভর করে; সম্পূর্ণ দূর করে না
"FAISS একটি vector database" সম্পূর্ণ সঠিক না। FAISS একটি similarity search library; একটি সম্পূর্ণ vector database-এ সাধারণত metadata, persistence, ও API-এর মতো অতিরিক্ত সুবিধা থাকে
"Embedding আর Vector সবসময় সম্পূর্ণ একই জিনিস" খুব কাছাকাছি ধারণা হলেও, Embedding একটি process/representation-এর ধারণা, আর Vector হলো system-এ ব্যবহৃত সেই সংখ্যাগত রূপ
"Semantic search সবসময় keyword search-এর চেয়ে ভালো" না, নির্দিষ্ট error code, ID, বা exact match-নির্ভর query-তে keyword search বেশি কার্যকর হতে পারে
"Retrieval আর Reranking একই ধাপ" না, এগুলো আলাদা ধাপ — Retrieval দ্রুত অনেক candidate আনে, Reranking সেগুলোর মধ্যে সেরা কয়েকটি বাছাই করে

🗺️ ১৯. সিরিজ Roadmap — সম্পূর্ণ Learning Path

এই Episode শুধু শুরু। পুরো সিরিজে আমরা ধাপে ধাপে fundamentals থেকে production-grade RAG পর্যন্ত যাব। সম্পূর্ণ পরিকল্পনা নিচে দেওয়া হলো:

Phase 1 — Fundamentals

  1. RAG কী? (এই Episode)
  2. LLM কীভাবে কাজ করে?
  3. Embedding কী? (গভীরভাবে)
  4. Vector কী?
  5. Vector Database কী?

Phase 2 — Retrieval

  1. Document Ingestion
  2. Chunking
  3. Chunking Strategies
  4. Semantic Search
  5. Metadata Filtering

Phase 3 — Vector Search

  1. FAISS
  2. FAISS Indexes
  3. Similarity Metrics
  4. Approximate Nearest Neighbor
  5. Vector DB Comparison

Phase 4 — Advanced Retrieval

  1. BM25
  2. Hybrid Search
  3. Score Fusion
  4. Reciprocal Rank Fusion (RRF)
  5. Reranking

Phase 5 — Generation

  1. Context Construction
  2. RAG Prompting
  3. Grounding
  4. Citation
  5. Hallucination Mitigation

Phase 6 — Production RAG

  1. Evaluation
  2. Recall@K
  3. Precision@K
  4. MRR
  5. NDCG
  6. Latency
  7. Caching
  8. Scaling
  9. Observability

Phase 7 — Advanced RAG

  1. Query Rewriting
  2. Multi-query Retrieval
  3. Parent-Child Retrieval
  4. HyDE
  5. Agentic RAG
  6. Multi-step Retrieval

Phase 8 — Practical Project

একটি সম্পূর্ণ RAG system একদম শূন্য থেকে তৈরি করা, এবং ধীরে ধীরে সেটাকে একটি production-oriented architecture-এ রূপান্তর করা — যেখানে আমাদের Islamic RAG project-কে reference হিসেবে ব্যবহার করে, Phase 4-7-এ আলোচিত feature-গুলো (Hybrid Search, Reranking, Evaluation ইত্যাদি) ধাপে ধাপে যোগ করা হবে।

এই roadmap নির্দেশক (guiding), কিন্তু rigid নয় — কিছু Episode একত্র হতে পারে বা প্রয়োজন অনুযায়ী ক্রম সামান্য পরিবর্তিত হতে পারে, যাতে প্রতিটি ধারণা যথাযথ গভীরতায় ব্যাখ্যা করা যায়।

২০. Conclusion

এই Episode-এ আমরা যা শিখলাম:

✓ কেন পুরো knowledge base সরাসরি LLM-কে পাঠানো যায় না, এবং কেন "Retrieval → Augment → Generate" এই সহজ ধারণা থেকে RAG-এর জন্ম
✓ LLM কী, এবং training, inference, parameters, tokens, context window-এর মতো মূল পরিভাষা
✓ Training Knowledge কখনো একটি private/dynamic database-এর বিকল্প নয়
✓ Hallucination কী, এবং কেন RAG এটি সম্পূর্ণ দূর করে না, শুধু কমাতে সাহায্য করে
✓ Traditional LLM usage এবং RAG-এর মধ্যে architecture-ভিত্তিক পার্থক্য
✓ সম্পূর্ণ RAG architecture — User থেকে Answer পর্যন্ত প্রতিটি বক্স
✓ Ingestion Pipeline (offline) ও Query Pipeline (online)-এর মধ্যে স্পষ্ট পার্থক্য
✓ Embedding, Vector, Vector Search, এবং Similarity metric-এর মূল ধারণা
✓ FAISS আসলে কী, এবং কেন এটিকে সরলীকৃতভাবে "vector database" বলা ঠিক না
✓ Chunking কেন প্রয়োজন এবং এর প্রধান কৌশলগুলোর সংক্ষিপ্ত পরিচিতি
✓ Hybrid Search ও Reranking-এর প্রাথমিক ধারণা
✓ RAG এবং Fine-tuning কীভাবে আলাদা এবং একসাথেও ব্যবহারযোগ্য
✓ আমাদের বাস্তব Islamic RAG project কীভাবে এই সব ধারণা প্রয়োগ করে — এবং সততার সাথে, এটি বর্তমানে কী কী করে না

এই Episode একটি শক্ত mental model তৈরি করেছে। পরবর্তী Episode-গুলোতে আমরা প্রতিটি ধারণা আরও গভীরে গিয়ে, ধাপে ধাপে কোড লিখে বাস্তবায়ন করব।

➡️ ২১. Next Episode

পরবর্তী Episode: "LLM কীভাবে কাজ করে?"

পরের পর্বে আমরা LLM-এর ভেতরের প্রক্রিয়া আরও গভীরভাবে দেখব — tokenization, next-token prediction, এবং কীভাবে prompt থেকে output তৈরি হয়, সেই ভিত্তি তৈরি করব — যা পরবর্তীতে Embedding ও RAG prompting বোঝার জন্য কাজে লাগবে।
⬅ পূর্ববর্তী Episode (এটাই প্রথম পর্ব) পরবর্তী Episode: LLM কীভাবে কাজ করে? ➡
© 2025 Sheikh Thanbir Alam. All Rights Reserved. thanbirtamim.github.io
এই লেখা মূল লেখকের সম্পত্তি — লিখিত অনুমতি ছাড়া কপি করে অন্য কোনো ওয়েবসাইট, ব্লগ, বই বা প্ল্যাটফর্মে প্রকাশ/বিতরণ করা কঠোরভাবে নিষিদ্ধ। Content may not be copied or republished without permission.