<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[RAG - Retrieval Augmented Generation]]></title><description><![CDATA[RAG - Retrieval Augmented Generation]]></description><link>https://rag-retrieval-augmented-generation.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 01 Sep 2026 17:48:09 GMT</lastBuildDate><atom:link href="https://rag-retrieval-augmented-generation.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[🤖📚 RAG: Because Even Your LLM Needs Cheat Sheets]]></title><description><![CDATA[Imagine you're ChatGPT. A user uploads a 100-page PDF on Quantum Mechanics and then asks,

"Explain quantum entanglement in simple terms."

Now, you could do one of two things:

Try to remember everything from the PDF like a tired college student bef...]]></description><link>https://rag-retrieval-augmented-generation.hashnode.dev/rag-because-even-your-llm-needs-cheat-sheets</link><guid isPermaLink="true">https://rag-retrieval-augmented-generation.hashnode.dev/rag-because-even-your-llm-needs-cheat-sheets</guid><category><![CDATA[AI]]></category><category><![CDATA[llm]]></category><category><![CDATA[RAG ]]></category><category><![CDATA[chatgpt]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Arpit Mohankar]]></dc:creator><pubDate>Sat, 07 Jun 2025 04:03:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1749241703087/dc6fcdc1-f940-4e2c-bcb4-b219d9bde794.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imagine you're ChatGPT. A user uploads a <strong>100-page PDF on Quantum Mechanics</strong> and then asks,</p>
<blockquote>
<p>"Explain quantum entanglement in simple terms."</p>
</blockquote>
<p>Now, you could do one of two things:</p>
<ol>
<li><p><strong>Try to remember</strong> everything from the PDF like a tired college student before an exam.</p>
</li>
<li><p><strong>Look up</strong> the relevant part from the PDF first (like a smart kid with notes), and <strong>then</strong> answer.</p>
</li>
</ol>
<p>Guess what makes the second method possible?<br />🎉 <strong>RAG - Retrieval Augmented Generation</strong> 🎉</p>
<p>Let’s break this whole RAG thing down using a funny analogy, explain the techy bits (like chunking and vectorization), and walk you through a Streamlit app that lets you <em>chat with a PDF</em> like it’s your emotionally unavailable ex.</p>
<h2 id="heading-but-first-what-is-rag">🧠 But first, what <em>is</em> RAG?</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749241412212/00275214-f44b-46ec-b858-be6fbdcfaad9.jpeg" alt class="image--center mx-auto" /></p>
<p>RAG = Retrieval + Generation.<br />It's like combining Google Search + ChatGPT.</p>
<blockquote>
<p><strong>Retrieval</strong> → Fetch relevant context from a source (like a PDF or database).<br /><strong>Generation</strong> → Use that context to generate a response with an LLM.</p>
</blockquote>
<p>Think of it like:</p>
<blockquote>
<p><strong>LLMs without RAG</strong> = Trying to answer questions while blindfolded.<br /><strong>LLMs with RAG</strong> = Wearing glasses + having Google open in another tab.</p>
</blockquote>
<h2 id="heading-why-rag-whats-the-problem">🧩 Why RAG? What's the problem?</h2>
<p>Big LLMs like GPT are trained on lots of data… <strong>but</strong> they:</p>
<ul>
<li><p>Don’t know your specific document.</p>
</li>
<li><p>Hallucinate answers when clueless (like that overconfident guy in your group project).</p>
</li>
<li><p>Can’t "remember" long PDFs or websites out of the box.</p>
</li>
</ul>
<p>💡 <strong>RAG solves this by feeding the LLM bite-sized, relevant info from your data.</strong></p>
<h2 id="heading-lets-break-down-the-rag-system-using-your-code">🔧 Let’s break down the RAG System (using your code)</h2>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">The Folder Structure</div>
</div>

<pre><code class="lang-python">/.
├── main.py              <span class="hljs-comment"># The main app</span>
├── requirements.txt     <span class="hljs-comment"># All the stuff you need to install</span>
├── pyproject.toml       <span class="hljs-comment"># Project metadata</span>
├── .python-version      <span class="hljs-comment"># Python version (3.11)</span>
├── .venv/               <span class="hljs-comment"># Virtual environment (ignore this mess)</span>
└── README.md            <span class="hljs-comment"># You’re reading it!</span>
</code></pre>
<p>Here’s what your PDF chatbot is doing:</p>
<p><strong>🗂️ Step 1: Load your PDF</strong></p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> streamlit <span class="hljs-keyword">as</span> st
<span class="hljs-keyword">from</span> PyPDF2 <span class="hljs-keyword">import</span> PdfReader
<span class="hljs-keyword">import</span> tempfile

<span class="hljs-comment"># Upload the PDF</span>
uploaded_file = st.file_uploader(<span class="hljs-string">"Upload your PDF"</span>, type=<span class="hljs-string">"pdf"</span>)

<span class="hljs-keyword">if</span> uploaded_file:
    <span class="hljs-keyword">with</span> tempfile.NamedTemporaryFile(delete=<span class="hljs-literal">False</span>, suffix=<span class="hljs-string">".pdf"</span>) <span class="hljs-keyword">as</span> tmp:
        tmp.write(uploaded_file.read())
        path = tmp.name
</code></pre>
<p>🎒 You pack your textbook (PDF). We’re gonna dissect this bad boy.</p>
<p><strong>✂️ Step 2: Chunk it like Netflix episodes</strong></p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> langchain_community.document_loaders <span class="hljs-keyword">import</span> PyPDFLoader
<span class="hljs-keyword">from</span> langchain_text_splitters <span class="hljs-keyword">import</span> RecursiveCharacterTextSplitter

<span class="hljs-comment"># Load PDF as documents</span>
loader = PyPDFLoader(path)
docs = loader.load()

<span class="hljs-comment"># Chunk the documents</span>
splitter = RecursiveCharacterTextSplitter(chunk_size=<span class="hljs-number">1000</span>, chunk_overlap=<span class="hljs-number">400</span>)
chunks = splitter.split_documents(docs)
</code></pre>
<p>👀 <strong>Chunking</strong> means splitting big documents into manageable pieces (like binge-watching episodes instead of watching a 12-hour movie).</p>
<ul>
<li><p><strong>chunk_size</strong> = Length of each piece (in characters).</p>
</li>
<li><p><strong>chunk_overlap</strong> = A little overlap so context isn’t lost.</p>
</li>
</ul>
<p>🧠 This helps later when the LLM is searching for info.</p>
<p><strong>🧬 Step 3: Vectorization — Turn Text into Math</strong></p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> langchain_openai <span class="hljs-keyword">import</span> OpenAIEmbeddings
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv

load_dotenv()
openai_api_key = os.getenv(<span class="hljs-string">"openai_api_key"</span>)

<span class="hljs-comment"># Create embeddings for chunks</span>
embedding = OpenAIEmbeddings(openai_api_key=openai_api_key)
</code></pre>
<p>📦 Each chunk is turned into a <strong>vector</strong> — a fancy mathematical way to say <em>“this is the vibe of the chunk.”</em></p>
<p>Think of it like giving each paragraph its own <strong>vibe-check playlist</strong>.<br />Now when you ask a question, the system’s like:</p>
<blockquote>
<p>“Yo, which chunk has the same vibe as this question?” 🎧</p>
</blockquote>
<p>It’s Spotify’s “Recommended for You” — but for knowledge.</p>
<p><strong>🏦 Step 4: Store in Vector DB (Qdrant in this case)</strong></p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> langchain_community.vectorstores <span class="hljs-keyword">import</span> Qdrant
<span class="hljs-keyword">from</span> qdrant_client <span class="hljs-keyword">import</span> QdrantClient

qdrant_url = <span class="hljs-string">"https://your-qdrant-url:6333"</span>
qdrant_api_key = os.getenv(<span class="hljs-string">"qdrant_api_key"</span>)
collection_name = <span class="hljs-string">"pdf_chunks"</span>

<span class="hljs-comment"># Delete old collection if needed</span>
client = QdrantClient(url=qdrant_url, api_key=qdrant_api_key)
client.delete_collection(collection_name=collection_name)

<span class="hljs-comment"># Store vectors</span>
qdrant_store = Qdrant.from_documents(
    documents=chunks,
    embedding=embedding,
    url=qdrant_url,
    api_key=qdrant_api_key,
    collection_name=collection_name
)

<span class="hljs-comment"># Save store in session</span>
st.session_state.qdrant_store = qdrant_store
</code></pre>
<p>🧠 Think of <strong>Qdrant</strong> as a memory palace — it remembers each chunk’s meaning (vector) and can quickly find the best matches when asked.  </p>
<p><strong>🔍 Step 5: Ask a question → Retrieve relevant chunks</strong></p>
<pre><code class="lang-python"><span class="hljs-comment"># Input from user</span>
user_query = st.text_input(<span class="hljs-string">"Ask your question about the PDF"</span>)

<span class="hljs-keyword">if</span> user_query:
    <span class="hljs-comment"># Retrieve similar chunks</span>
    results = st.session_state.qdrant_store.similarity_search(user_query, k=<span class="hljs-number">3</span>)
    context = <span class="hljs-string">"\n\n"</span>.join([doc.page_content <span class="hljs-keyword">for</span> doc <span class="hljs-keyword">in</span> results])
</code></pre>
<p>🕵️‍♂️ This is where your assistant goes:</p>
<blockquote>
<p>“Hmm… out of 100 chunks, these 3 smell like they contain the answer.”</p>
</blockquote>
<h3 id="heading-step-6-feed-chunks-question-to-openai">✨ Step 6: Feed chunks + question to OpenAI</h3>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> openai <span class="hljs-keyword">import</span> OpenAI

client = OpenAI(api_key=openai_api_key)

<span class="hljs-comment"># Craft the prompt</span>
prompt = <span class="hljs-string">f"""
Use this context to answer the question:
\"\"\"<span class="hljs-subst">{context}</span>\"\"\"

Question: <span class="hljs-subst">{user_query}</span>
"""</span>

<span class="hljs-comment"># Call OpenAI's GPT model</span>
response = client.chat.completions.create(
    model=<span class="hljs-string">"gpt-3.5-turbo"</span>,
    messages=[
        {<span class="hljs-string">"role"</span>: <span class="hljs-string">"system"</span>, <span class="hljs-string">"content"</span>: <span class="hljs-string">"You are a helpful assistant."</span>},
        {<span class="hljs-string">"role"</span>: <span class="hljs-string">"user"</span>, <span class="hljs-string">"content"</span>: prompt}
    ]
)

<span class="hljs-comment"># Display answer</span>
answer = response.choices[<span class="hljs-number">0</span>].message.content.strip()
st.markdown(<span class="hljs-string">"### 📘 Answer:"</span>)
st.markdown(answer)
</code></pre>
<p>Now the LLM (GPT-3.5) has everything it needs:</p>
<ul>
<li><p>A specific question</p>
</li>
<li><p>Just the right background info<br />  …without being overwhelmed.</p>
</li>
</ul>
<p>Result? 👇<br />✅ Less hallucination<br />✅ More factual answers<br />✅ Like a nerd who studied only <em>important</em> topics</p>
<h2 id="heading-tldr-rag-is-your-llms-memory-booster">✅ TL;DR – RAG is your LLM’s Memory Booster</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Steps</td><td>What it Does</td></tr>
</thead>
<tbody>
<tr>
<td>Chunking</td><td>Breaks docs into smaller, manageable parts</td></tr>
<tr>
<td>Embedding</td><td>Turns text into mathematical vectors</td></tr>
<tr>
<td>Vector Store</td><td>Saves + searches chunks based on meaning</td></tr>
<tr>
<td>Retrieval</td><td>Picks the most relevant chunks for a query</td></tr>
<tr>
<td>Generation</td><td>Uses those chunks to give a smart answer</td></tr>
</tbody>
</table>
</div><h2 id="heading-final-words-from-your-pdf-therapist">🔚 Final Words from your PDF Therapist</h2>
<p>With this RAG setup, your chatbot isn’t just guessing anymore.<br />It’s <strong>researching</strong> like a top-tier student and <strong>explaining</strong> like your favorite YouTuber.</p>
<blockquote>
<p>Your PDFs finally get to talk. Just hope they don’t roast your notes.</p>
</blockquote>
<h3 id="heading-try-it-yourself">🚀 Try It Yourself</h3>
<p><strong>📂 GitHub Repository</strong><br />Want to check out the full code or run it locally?<br /><a target="_blank" href="https://github.com/Arpit-mohankar/RAG">👉 View on GitHub</a></p>
<p><strong>🌐 Live Streamlit Demo</strong><br />Don’t want to set it up? No worries — try it live in your browser!<br /><a target="_blank" href="https://rag-with-pdf.streamlit.app/">👉 Chat with your PDF – Live Demo</a></p>
]]></content:encoded></item></channel></rss>