{"slug": "how-to-build-a-rag-system-from-scratch-in-python-chunk-embed-retrieve-cite-https", "title": "How to build a RAG system from scratch in Python (chunk embed retrieve cite)( https://ai.studybydoing.in)", "summary": "A developer has published a from-scratch Python walkthrough for building a retrieval-augmented generation (RAG) system, covering chunking, embeddings, a minimal vector store, hybrid retrieval, re-ranking, and cited generation without relying on framework one-liners. The build uses sentence-transformers for embeddings and a NumPy-based vector store that normalizes vectors so cosine similarity reduces to a dot product. The author argues chunking is the highest-leverage design decision and presents the full lesson as part of a free course on building RAG, agents, and evaluation by hand.", "body_md": "Most \"RAG tutorials\" hand you a framework and a `.from_documents()` one-liner, and you never actually see what happens inside. So I built one **by hand** — chunking, embeddings, a tiny\n\n  vector store, hybrid retrieval, re-ranking, and cited generation — to understand each moving part. Here's the mental model and the two pieces that matter most.\n\n## What RAG actually is\n\nAn LLM only knows what was in its training data. **RAG (Retrieval-Augmented Generation)** lets it answer questions about *your* private/current documents by retrieving relevant snippets at\n\n  query time and putting them in the prompt. The model then answers from that supplied context — facts, not guesses.\n\nThe pipeline has two timelines:\n\nIn one line: **RAG = look things up first, then answer from what you found.** The offline row is a librarian shelving books; the online row is you asking a question and getting the right\n\n  pages handed to you before you write your reply.\n\n## The highest-leverage decision: chunking\n\nModels retrieve **chunks, not whole documents** — so how you split matters more than almost anything else:\n\n``` python\n  import re\n\n  def chunk_text(text, source, target_words=120, overlap=25):\n      \"\"\"Split on paragraphs, then pack into ~target_words chunks with overlap.\"\"\"\n      paras = [p.strip() for p in re.split(r\"\\n\\s*\\n\", text) if p.strip()]\n      chunks, buf = [], []\n      for p in paras:\n          buf.append(p)\n          if sum(len(x.split()) for x in buf) >= target_words:\n              chunks.append(\" \".join(buf))\n              buf = buf[-1:]  # carry last para as overlap\n      if buf:\n          chunks.append(\" \".join(buf))\n      return [{\"text\": c, \"source\": source, \"id\": f\"{source}#{i}\"} for i, c in enumerate(chunks)]\n```\n\nThe rules that survived the labs:\n\n## Embeddings + a vector store in ~15 lines\n\nAn embedding turns text into a vector where **similar meanings sit close together**. Store each chunk's vector; at query time, embed the question and find the nearest chunks by cosine\n\n  similarity.\n\n``` python\n  import numpy as np\n  from sentence_transformers import SentenceTransformer  # swap for any provider\n\n  _model = SentenceTransformer(\"all-MiniLM-L6-v2\")\n\n  def embed(texts):\n      # normalize -> cosine similarity collapses into a plain dot product\n      return np.asarray(_model.encode(texts, normalize_embeddings=True))\n\n  class VectorStore:\n      def add(self, chunks):\n          self.chunks = chunks\n          self.vecs = embed([c[\"text\"] for c in chunks])   # (N chunks x d)\n\n      def search(self, query, k=4):\n          q = embed([query])[0]\n          sims = self.vecs @ q                             # similarity to every chunk, one step\n          top = np.argsort(-sims)[:k]\n          return [(self.chunks[i], float(sims[i])) for i in top]\n```\n\nTwo things clicked for me here:\n\n`embed()` is the one place text becomes numbers\n## Then: hybrid retrieval, re-ranking, and *citations*\n\nThe last labs add the parts that separate a demo from something usable:\n\n## The mental model to keep\n\nIf you want to *run* each stage yourself (the lesson has an in-browser Python terminal, no setup) the full build is here 👉 **[Build a RAG System From\n  Scratch](https://ai.studybydoing.in/ch03-rag)**. It's part of a free course that builds RAG, agents, eval, and production LLM systems by hand:\n\n**[ai.studybydoing.in](https://ai.studybydoing.in)**.", "url": "https://wpnews.pro/news/how-to-build-a-rag-system-from-scratch-in-python-chunk-embed-retrieve-cite-https", "canonical_source": "https://dev.to/krish0549/how-to-build-a-rag-system-from-scratch-in-python-chunk-embed-retrieve-cite-fa4", "published_at": "2026-09-18 03:21:53+00:00", "updated_at": "2026-09-18 03:52:57.251388+00:00", "lang": "en", "topics": ["large-language-models", "ai-tools", "developer-tools", "natural-language-processing", "ai-agents"], "entities": ["Python", "sentence-transformers", "NumPy", "all-MiniLM-L6-v2", "ai.studybydoing.in"], "alternates": {"html": "https://wpnews.pro/news/how-to-build-a-rag-system-from-scratch-in-python-chunk-embed-retrieve-cite-https", "markdown": "https://wpnews.pro/news/how-to-build-a-rag-system-from-scratch-in-python-chunk-embed-retrieve-cite-https.md", "text": "https://wpnews.pro/news/how-to-build-a-rag-system-from-scratch-in-python-chunk-embed-retrieve-cite-https.txt", "jsonld": "https://wpnews.pro/news/how-to-build-a-rag-system-from-scratch-in-python-chunk-embed-retrieve-cite-https.jsonld"}}