<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: TAGBA G-Josaphat E.</title>
    <description>The latest articles on DEV Community by TAGBA G-Josaphat E. (@josaphatstar).</description>
    <link>https://dev.to/josaphatstar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2701018%2F040c3ca7-e6a8-47cf-9cd0-ac10e0cd6691.jpg</url>
      <title>DEV Community: TAGBA G-Josaphat E.</title>
      <link>https://dev.to/josaphatstar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/josaphatstar"/>
    <language>en</language>
    <item>
      <title>I Built a Local RAG Assistant with Ollama, ChromaDB and LangChain. Here's What I Learned</title>
      <dc:creator>TAGBA G-Josaphat E.</dc:creator>
      <pubDate>Sat, 25 Jul 2026 14:36:54 +0000</pubDate>
      <link>https://dev.to/josaphatstar/i-built-a-local-rag-assistant-with-ollama-chromadb-and-langchain-heres-what-i-learned-5a2e</link>
      <guid>https://dev.to/josaphatstar/i-built-a-local-rag-assistant-with-ollama-chromadb-and-langchain-heres-what-i-learned-5a2e</guid>
      <description>&lt;p&gt;During my internship at a software services company, I noticed a recurring problem: technicians spent hours searching through hundreds of pages of PDF manuals to answer client questions. The company deploys a suite of management tools accounting, HR, logistics mainly to public institutions managing projects funded by international donors.&lt;/p&gt;

&lt;p&gt;I kept thinking: this is exactly the kind of problem LLMs were made for. So for my Master's project in AI &amp;amp; Big Data, I built an intelligent assistant to handle it.&lt;/p&gt;

&lt;p&gt;The constraint that shaped every technical decision: &lt;strong&gt;no data could leave the local infrastructure&lt;/strong&gt;. These institutions handle sensitive financial data it cannot be sent to OpenAI, Anthropic, or any cloud provider.&lt;/p&gt;

&lt;p&gt;This forced me into the world of fully local LLMs. Here's what I built, what broke, and what I learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;The company had accumulated massive technical documentation PDF manuals, configuration guides, FAQ files but no efficient way to query it. When a technician faced an issue with the accounting module or the HR module, they searched manually. Slow, inconsistent, and dependent on individual expertise.&lt;/p&gt;

&lt;p&gt;Classic LLMs can't help here: they don't know the private internal documentation. And without grounding in official docs, they hallucinate procedures dangerous when dealing with accounting operations for donor-funded projects.&lt;/p&gt;

&lt;p&gt;The solution: &lt;strong&gt;RAG (Retrieval-Augmented Generation)&lt;/strong&gt; make the LLM answer &lt;em&gt;only&lt;/em&gt; from the official documentation, injected at query time.&lt;/p&gt;




&lt;h2&gt;
  
  
  What RAG Actually Is
&lt;/h2&gt;

&lt;p&gt;Before the code, the concept in one sentence: instead of asking the LLM to "know" everything, you retrieve the relevant passages from your documents and inject them into the prompt as context.&lt;/p&gt;

&lt;p&gt;The pipeline has two distinct phases:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 1 : Ingestion (done once)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PDF documents
    ↓
Chunking (split into 300-character blocks)
    ↓
Embedding (convert each block to a vector)
    ↓
ChromaDB (store all vectors)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Phase 2 : Query (at each question)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User question
    ↓
Embed the question (same model)
    ↓
ChromaDB similarity search → top 3 chunks
    ↓
Inject chunks + question into LLM prompt
    ↓
Llama 3 generates a grounded answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight: the LLM never "knows" your documents. It reads them fresh at each query, from the context you provide. No fine-tuning needed. No retraining when docs are updated.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture: 4 Docker Services
&lt;/h2&gt;

&lt;p&gt;Everything runs locally via Docker Compose. Four services, each with a clear role:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ollama&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Runs Llama 3 locally&lt;/td&gt;
&lt;td&gt;11434&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ChromaDB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vector database&lt;/td&gt;
&lt;td&gt;8001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FastAPI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;RAG pipeline + REST API&lt;/td&gt;
&lt;td&gt;8000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Streamlit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;User interface&lt;/td&gt;
&lt;td&gt;8501&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# docker-compose.yml (simplified)&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ollama&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama/ollama:latest&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;11434:11434"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./ollama_models:/root/.ollama"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;OLLAMA_KEEP_ALIVE=24h&lt;/span&gt;

  &lt;span class="na"&gt;chromadb&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chromadb/chroma:latest&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8001:8000"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./chroma_db:/chroma/chroma"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="na"&gt;python-api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./src&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ollama&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;chromadb&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;OLLAMA_BASE_URL=http://ollama:11434&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CHROMA_HOST=chromadb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CHROMA_PORT=8000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 1 : Ingesting the Documentation
&lt;/h2&gt;

&lt;p&gt;I ingested 10 documents accounting references (SYSCOHADA, SYCEBNL), a general accounting code, and internal user manuals. That's &lt;strong&gt;2,111 pages&lt;/strong&gt; split into &lt;strong&gt;9,669 chunks&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# src/ingestion.py
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.document_loaders&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PyPDFLoader&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_text_splitters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_chroma&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.embeddings&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HuggingFaceEmbeddings&lt;/span&gt;

&lt;span class="n"&gt;DATA_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/app/data/documents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;COLLECTION_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;documentation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_documents&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DATA_DIR&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PyPDFLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DATA_DIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="c1"&gt;# Tag each chunk with its source document
&lt;/span&gt;                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;module&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skipped &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Don't crash on encrypted PDFs
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;store_embeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HuggingFaceEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all-MiniLM-L6-v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;model_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;device&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Explicit HTTP connection — not localhost, the Docker service name
&lt;/span&gt;    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chromadb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLLECTION_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Done — &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; vectors stored&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things worth noting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I tag each chunk with its source document name as metadata this allows the LLM to cite its source in the answer&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;try/except&lt;/code&gt; is not optional one encrypted PDF (it happened) would have crashed the entire ingestion without it. Install &lt;code&gt;cryptography&lt;/code&gt; if you hit an AES error: &lt;code&gt;pip install cryptography&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 2 : Building the RAG Chain
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# src/rag_chain.py
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.embeddings&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HuggingFaceEmbeddings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.llms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Ollama&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_chroma&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.runnables&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_rag_chain&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Must be the same model used during ingestion
&lt;/span&gt;    &lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HuggingFaceEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all-MiniLM-L6-v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chromadb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;vectorstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Chroma&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;documentation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;embedding_function&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Retrieve top 3 most relevant chunks
&lt;/span&gt;    &lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;search_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;similarity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;search_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Ollama&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://ollama:11434&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llama3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;num_predict&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt;   &lt;span class="c1"&gt;# Cap response length — critical on CPU
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;You are a technical support assistant.
Answer ONLY from the provided context. Cite your source.
If the answer is not in the context, say so clearly.

Context: {context}
Question: {question}
Answer:&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;format_docs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[Source: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;module&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;?&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;
        &lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="c1"&gt;# The full pipeline in 4 steps
&lt;/span&gt;    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;context&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;format_docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;RunnablePassthrough&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The chain is a pipeline: &lt;code&gt;retriever → prompt → llm → parser&lt;/code&gt;. LangChain's &lt;code&gt;|&lt;/code&gt; operator makes this clean and readable. Each step passes its output to the next.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 : API and Interface
&lt;/h2&gt;

&lt;p&gt;FastAPI exposes the chain as a REST endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# src/main.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rag_chain&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_rag_chain&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Local RAG Assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_rag_chain&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QueryRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;QueryRequest&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Streamlit makes it usable in a browser in 10 lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# src/app.py
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;streamlit&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Technical Support Assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Your question:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spinner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Searching documentation... (1-2 min on CPU)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://python-api:8000/query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What Broke (and How I Fixed It)
&lt;/h2&gt;

&lt;p&gt;This is the part nobody writes about. Three real problems I hit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 1 : ChromaDB v2 silently ignoring my data
&lt;/h3&gt;

&lt;p&gt;I was connecting with the old &lt;code&gt;client_settings&lt;/code&gt; syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# WRONG silently stores data locally instead of sending to the server
&lt;/span&gt;&lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;client_settings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Settings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chroma_server_host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chromadb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ingestion ran without errors, showed 9669 chunks stored but ChromaDB had 0 vectors. Querying returned nothing.&lt;/p&gt;

&lt;p&gt;The fix explicit &lt;code&gt;HttpClient&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# CORRECT explicit HTTP connection to the ChromaDB Docker service
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chromadb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also: the v1 heartbeat endpoint (&lt;code&gt;/api/v1/heartbeat&lt;/code&gt;) is deprecated. Use &lt;code&gt;/api/v2/heartbeat&lt;/code&gt; to check if ChromaDB is alive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 2 : LangChain moved its modules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Broke silently after a LangChain update
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;           &lt;span class="c1"&gt;# ❌ ModuleNotFoundError
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.schema.runnable&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;  &lt;span class="c1"&gt;# ❌ ModuleNotFoundError
&lt;/span&gt;
&lt;span class="c1"&gt;# Everything stable lives in langchain_core now
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;      &lt;span class="c1"&gt;# ✅
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.runnables&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;   &lt;span class="c1"&gt;# ✅
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LangChain has been refactoring aggressively across versions. If you hit &lt;code&gt;ModuleNotFoundError&lt;/code&gt;, check &lt;code&gt;langchain_core&lt;/code&gt; first it's the stable base layer they're committing to not break.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 3 : Llama 3 timing out on CPU
&lt;/h3&gt;

&lt;p&gt;Llama 3 (8B parameters) on CPU generates roughly 2-5 tokens per second. A 200-word answer takes 2+ minutes. My 120-second timeout was too short.&lt;/p&gt;

&lt;p&gt;Three things helped significantly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dropping &lt;code&gt;k&lt;/code&gt; from 5 to 3 chunks shorter prompt = faster time-to-first-token&lt;/li&gt;
&lt;li&gt;Adding &lt;code&gt;num_predict=250&lt;/code&gt; to cap response length without it, the model generates forever&lt;/li&gt;
&lt;li&gt;Allocating more RAM to Docker via &lt;code&gt;.wslconfig&lt;/code&gt; on Windows to avoid swap&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;After setup, the assistant correctly answers questions grounded in the official documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;"How to close monthly payroll?"&lt;/em&gt; → Step-by-step procedure from the HR module manual&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"How to create an account in the chart of accounts?"&lt;/em&gt; → Exact navigation path, source cited&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"What does SYSCOHADA class 4 cover?"&lt;/em&gt; → Accurate definition from the accounting reference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And critically when the answer isn't in the documentation, it says so explicitly instead of hallucinating. That was the whole point.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;On RAG:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The embedding model used during ingestion must be &lt;strong&gt;identical&lt;/strong&gt; to the one used at query time. A different model produces incompatible vector spaces your similarity search returns garbage without any error message.&lt;/p&gt;

&lt;p&gt;Chunk size matters more than expected. 500 characters worked less well than 300 for technical documents shorter chunks produce more precise retrieval.&lt;/p&gt;

&lt;p&gt;Metadata on chunks is essential for source citation. Tag every chunk with its document name at ingestion time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On local LLMs:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Running on CPU is slow but viable for non-real-time use cases like internal support tools.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;num_predict&lt;/code&gt; is your most important parameter for performance. Without it, the model generates until it decides to stop sometimes never.&lt;/p&gt;

&lt;p&gt;Docker container networking does not use &lt;code&gt;localhost&lt;/code&gt;. Use the service name defined in &lt;code&gt;docker-compose.yml&lt;/code&gt; (e.g., &lt;code&gt;chromadb&lt;/code&gt;, &lt;code&gt;ollama&lt;/code&gt;) as the hostname when connecting between containers.&lt;/p&gt;




&lt;p&gt;This project is available on my github : &lt;a href="https://github.com/josaphatstar/Assistant-Intelligent-RAG" rel="noopener noreferrer"&gt;https://github.com/josaphatstar/Assistant-Intelligent-RAG&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;This RAG pipeline handles straightforward questions well. But it has a core limitation: &lt;strong&gt;it always does the same thing&lt;/strong&gt; regardless of the question type. Whether you ask a procedural question or report a system crash, it searches the docs and answers. No reasoning about what strategy fits best.&lt;/p&gt;

&lt;p&gt;In the next article, I'll show how I evolved this into an &lt;strong&gt;Agentic AI architecture&lt;/strong&gt; with LangGraph where the system first &lt;em&gt;decides&lt;/em&gt; which agent to call (documentation search, error diagnosis, or human escalation ticket), then acts accordingly.&lt;/p&gt;




&lt;p&gt;I'm a Master's student in AI &amp;amp; Big Data, and this project came out of a real internship constraint no cloud, no API keys, just local infrastructure and open-source tools. I'm curious: have you built a local RAG pipeline under similar constraints? What stack did you use, and what broke first? Drop it in the comments I'd genuinely like to compare notes.&lt;/p&gt;

</description>
      <category>rag</category>
      <category>langchain</category>
      <category>python</category>
      <category>ollama</category>
    </item>
    <item>
      <title>The Skill Level Of Young Developers Is Dropping. And Barely Anyone Wants To Admit It.</title>
      <dc:creator>TAGBA G-Josaphat E.</dc:creator>
      <pubDate>Thu, 09 Jul 2026 20:39:32 +0000</pubDate>
      <link>https://dev.to/josaphatstar/the-skill-level-of-young-developers-is-dropping-and-barely-anyone-wants-to-admit-it-1ff</link>
      <guid>https://dev.to/josaphatstar/the-skill-level-of-young-developers-is-dropping-and-barely-anyone-wants-to-admit-it-1ff</guid>
      <description>&lt;p&gt;Yesterday, during a class on advanced machine learning models, my professor said something that stuck with me.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"The skill level of young developers is declining year after year."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Not because they're less intelligent. Not because the curriculum is worse. But because they no longer take the time to think things through by themselves before handing their tasks off to AI.&lt;/p&gt;

&lt;p&gt;He added something even more concrete: &lt;strong&gt;he sees this decline firsthand in the new interns he mentors.&lt;/strong&gt; It's not an abstract trend for him it's something he watches happen in real time, intern after intern.&lt;/p&gt;

&lt;p&gt;At first, it sounded like a slightly jaded professor's remark, the kind of comment every generation hears ("kids these days don't know how to do anything anymore"). But the more I think about it, the more I believe he's right, and that the problem runs deeper than we'd like to admit.&lt;/p&gt;




&lt;h2&gt;
  
  
  We're no longer learning through struggle
&lt;/h2&gt;

&lt;p&gt;There's something essential about learning to code that we're losing: &lt;strong&gt;the struggle itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spending two hours stuck on a dumb bug. Reading the same stack trace over and over. Searching, testing, failing, trying again. It's frustrating, sure. But that exact process is what builds real competence. It's by hitting the wall that you understand &lt;em&gt;why&lt;/em&gt; a solution works, not just &lt;em&gt;that&lt;/em&gt; it works.&lt;/p&gt;

&lt;p&gt;Today, a lot of young developers never hit that wall anymore. They copy an error, paste it into an AI chat, grab a solution, and move on. The code works. But the understanding never actually happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem isn't the tool, it's the missing effort
&lt;/h2&gt;

&lt;p&gt;I'm not saying AI is bad for learning to code that would be absurd, and a bit hypocritical since I use it myself every single day. The problem isn't the tool. The problem is using it to &lt;em&gt;avoid&lt;/em&gt; effort instead of using it to &lt;em&gt;support&lt;/em&gt; effort.&lt;/p&gt;

&lt;p&gt;There's a huge difference between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using AI to understand something &lt;strong&gt;after&lt;/strong&gt; you've tried to figure it out yourself, and&lt;/li&gt;
&lt;li&gt;Using AI to &lt;strong&gt;avoid&lt;/strong&gt; trying to figure it out yourself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first approach is a learning accelerator. The second is technical debt you take out against yourself and you'll pay it back later, with interest.&lt;/p&gt;




&lt;h2&gt;
  
  
  In 10-15 years: a shortage of real skill
&lt;/h2&gt;

&lt;p&gt;Here's where I want to go with this, and it's the part that worries me the most.&lt;/p&gt;

&lt;p&gt;If this trend continues, the average skill level of developers will keep dropping. Not dramatically or overnight, but slowly, generation after generation. More and more people will know how to "make code work," but fewer and fewer will actually understand what they're writing, be able to debug a complex problem without assistance, or design a solid architecture from scratch.&lt;/p&gt;

&lt;p&gt;Meanwhile, AI itself will keep improving, taking up more space, automating more tasks. That creates a scissor effect: more people relying entirely on AI, fewer people capable of supervising it, correcting it, or solving the problems it can't solve on its own.&lt;/p&gt;

&lt;p&gt;The result: in 10 or 15 years, the people who kept real technical depth — who kept understanding the fundamentals instead of systematically outsourcing their thinking will be &lt;strong&gt;extremely rare&lt;/strong&gt;. And a rare skill, in a market that will always need it, comes at a very high price.&lt;/p&gt;




&lt;h2&gt;
  
  
  The two categories of developers
&lt;/h2&gt;

&lt;p&gt;I think we're heading toward a split:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A large mass&lt;/strong&gt; who know how to use AI but depend on it completely interchangeable, easily replaced.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A small minority&lt;/strong&gt; who genuinely understand what they're doing, capable of stepping in wherever AI fails.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That second group will end up grabbing pretty much every interesting opportunity and the salaries that come with them.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this means for us, right now
&lt;/h2&gt;

&lt;p&gt;If this reasoning holds up, the real question isn't "should we use AI or not." The question is: &lt;strong&gt;are we using it to learn faster, or to stop learning altogether?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I think the best long-term strategy for any developer starting out today is to keep imposing difficulty on themselves on purpose. Solve problems without AI from time to time. Understand the "why" before asking for the "how." Treat AI like a demanding mentor, not a permanent shortcut.&lt;/p&gt;

&lt;p&gt;Because in a few years, "knowing how to use AI" won't be what sets anyone apart. Everyone will know how to do that. What will matter is: &lt;strong&gt;who still has real technical skill behind it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And those people will be few. Which is exactly what will make them valuable.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Do you notice this trend around you, in your classes, or with people you mentor? Curious to hear your take in the comments.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is part of a series where I share my honest thoughts on AI, learning, and building in tech.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow along on &lt;a href="https://www.facebook.com/profile.php?id=61585926839187" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>AI Is Killing the SaaS Model. And I Think That's a Good Thing.</title>
      <dc:creator>TAGBA G-Josaphat E.</dc:creator>
      <pubDate>Sat, 27 Jun 2026 10:36:02 +0000</pubDate>
      <link>https://dev.to/josaphatstar/ai-is-killing-the-saas-model-and-i-think-thats-a-good-thing-4cna</link>
      <guid>https://dev.to/josaphatstar/ai-is-killing-the-saas-model-and-i-think-thats-a-good-thing-4cna</guid>
      <description>&lt;p&gt;I'll be honest with you.&lt;/p&gt;

&lt;p&gt;The last time I considered paying for a SaaS product, I caught myself thinking: &lt;em&gt;"Wait. Could I just build this myself?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And the answer, increasingly, is &lt;strong&gt;yes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That moment changed something in how I see the software industry.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI democratized building. Nobody fully processed what that means yet.
&lt;/h2&gt;

&lt;p&gt;A few years ago, building a working web app required real technical depth. Months of learning. A team. Infrastructure knowledge. It was a high barrier and SaaS products existed precisely because most people couldn't build their own tools.&lt;/p&gt;

&lt;p&gt;That barrier is collapsing.&lt;/p&gt;

&lt;p&gt;With AI, a developer even a junior one can now conceive, design, and ship a functional application in days. Not months. A solo student in their bedroom can build what used to require a funded startup.&lt;/p&gt;

&lt;p&gt;And here's the logical consequence nobody talks about enough: &lt;strong&gt;if anyone can build software, why would they pay someone else for it?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  I already think this way. And I don't think I'm alone.
&lt;/h2&gt;

&lt;p&gt;Before subscribing to any tool now, I ask myself three questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I actually need all the features this SaaS offers, or just 20% of them?&lt;/li&gt;
&lt;li&gt;Could I build a lightweight version that does exactly what I need?&lt;/li&gt;
&lt;li&gt;Would maintaining it be worth the subscription cost?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More and more often, the answer points toward building my own version.&lt;/p&gt;

&lt;p&gt;Not because I'm cheap. But because AI makes it genuinely &lt;strong&gt;faster and easier&lt;/strong&gt; to build a custom solution than to adapt my workflow to someone else's product.&lt;/p&gt;

&lt;p&gt;A personal project management tool. A custom dashboard. A note taking app with exactly the features I want. A budget tracker built around my actual habits.&lt;/p&gt;

&lt;p&gt;Why pay $12/month for a tool that does 80% of what I need when I can build 100% of what I need in a weekend?&lt;/p&gt;




&lt;h2&gt;
  
  
  The SaaS products that will suffer
&lt;/h2&gt;

&lt;p&gt;Not all SaaS will die. But I think a specific category is in serious trouble: &lt;strong&gt;the simple, single-purpose tools.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The ones that do one thing. Solve one problem. The ones where the value proposition is essentially: &lt;em&gt;"We built this so you don't have to."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That value proposition just got a lot weaker.&lt;/p&gt;

&lt;p&gt;If your product's entire moat is "we wrote the code and you didn't have to" AI just erased your moat.&lt;/p&gt;

&lt;p&gt;Think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple form builders&lt;/li&gt;
&lt;li&gt;Basic invoice generators&lt;/li&gt;
&lt;li&gt;Lightweight project trackers&lt;/li&gt;
&lt;li&gt;Note-taking apps with no unique angle&lt;/li&gt;
&lt;li&gt;Simple landing page builders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every single one of these is now buildable by a motivated developer with AI assistance in a weekend.&lt;/p&gt;




&lt;h2&gt;
  
  
  The SaaS products that will survive
&lt;/h2&gt;

&lt;p&gt;The ones that survive will have something AI-assisted solo development can't easily replicate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Network effects&lt;/strong&gt; value that comes from other users being on the platform&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data moats&lt;/strong&gt; insights and intelligence that come from aggregating millions of users' data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep integrations&lt;/strong&gt; years of ecosystem connections that would take months to rebuild&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance and trust&lt;/strong&gt; regulated industries where "I built it myself" isn't good enough&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale infrastructure&lt;/strong&gt; the kind of backend complexity that goes far beyond a weekend project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notion, Stripe, Figma, Linear, these aren't threatened by someone building their own version. They offer something fundamentally hard to replicate alone.&lt;/p&gt;

&lt;p&gt;The $9/month form builder with no unique angle? That's a different story.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this means for developers building SaaS today
&lt;/h2&gt;

&lt;p&gt;If you're building a SaaS product right now, I think this is the most important question you need to answer honestly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Could a motivated developer with AI assistance replicate your core value in a weekend?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the answer is yes you have a problem. Not an immediate one. But a growing one.&lt;/p&gt;

&lt;p&gt;The market for "we built this so you don't have to" is shrinking. The market for "we built something you genuinely couldn't build yourself" is still very much alive.&lt;/p&gt;




&lt;h2&gt;
  
  
  My honest take
&lt;/h2&gt;

&lt;p&gt;I think we're entering a world where software splits into two categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Personal, custom tools&lt;/strong&gt; built by individuals for themselves, free, perfectly tailored, AI-assisted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform-scale products&lt;/strong&gt; with network effects, data, compliance, and infrastructure that individuals can't replicate&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The middle ground the simple paid SaaS with no unique moat is going to get squeezed from both sides.&lt;/p&gt;

&lt;p&gt;And honestly? I think that's good for users. We've been paying subscription fees for tools that were always a little too generic, a little too bloated, a little too expensive for what they actually delivered.&lt;/p&gt;

&lt;p&gt;AI is giving us a way out.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What do you think are you starting to build your own tools instead of paying for SaaS? Or do you think paid products will always have an edge that self-built tools can't match?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is part of a series where I share my honest thoughts on AI, learning, and building in tech.&lt;br&gt;
*Follow along on &lt;a href="https://www.facebook.com/profile.php?id=61585926839187" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>saas</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Is AI Making Us More Vulnerable? The Growing Threat of Cyberattacks in the AI Era</title>
      <dc:creator>TAGBA G-Josaphat E.</dc:creator>
      <pubDate>Tue, 16 Jun 2026 18:55:50 +0000</pubDate>
      <link>https://dev.to/josaphatstar/is-ai-making-us-more-vulnerable-the-growing-threat-of-cyberattacks-in-the-ai-era-3m90</link>
      <guid>https://dev.to/josaphatstar/is-ai-making-us-more-vulnerable-the-growing-threat-of-cyberattacks-in-the-ai-era-3m90</guid>
      <description>&lt;p&gt;Something feels different about security incidents lately.&lt;/p&gt;

&lt;p&gt;Breaches, leaks, account takeovers, phishing campaigns they're not new. But their &lt;strong&gt;frequency, sophistication, and scale&lt;/strong&gt; seem to be growing at a pace that feels genuinely alarming.&lt;/p&gt;

&lt;p&gt;Instagram accounts hacked overnight. Corporate systems compromised in hours. Phishing emails that sound disturbingly human.&lt;/p&gt;

&lt;p&gt;As someone studying AI &amp;amp; Big Data, I can't help but ask: &lt;strong&gt;is AI responsible for this? And if so, how?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I think the honest answer is: &lt;strong&gt;yes but in two very different ways.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The two faces of AI in cybersecurity
&lt;/h2&gt;

&lt;p&gt;When we talk about AI and cyberattacks, most people imagine one scenario: hackers using AI to attack systems faster and smarter.&lt;/p&gt;

&lt;p&gt;That's real. But it's only half the picture.&lt;/p&gt;

&lt;p&gt;The other half is something we talk about far less: &lt;strong&gt;the vulnerabilities that come from integrating AI into systems in the first place.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are two very different problems. And conflating them leads to the wrong solutions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 1: AI is expanding the attack surface
&lt;/h2&gt;

&lt;p&gt;Every time a platform integrates an AI feature, they're adding something new to their infrastructure. And new infrastructure means new potential vulnerabilities.&lt;/p&gt;

&lt;p&gt;AI systems require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Massive data pipelines&lt;/strong&gt; more data flowing through more systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APIs connecting multiple services&lt;/strong&gt; more endpoints that can be exploited&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-party models and tools&lt;/strong&gt; more external dependencies, more trust relationships&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time processing&lt;/strong&gt; less time to detect anomalies before damage is done&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many organizations are integrating AI features faster than their security teams can audit them. And the consequences are already visible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In June 2026&lt;/strong&gt;, hackers reportedly manipulated AI-powered support systems to gain unauthorized access to Instagram accounts. The attack didn't target traditional software vulnerabilities it targeted the &lt;strong&gt;AI system itself&lt;/strong&gt;, exploiting the automated account recovery flow that Meta had built with AI.&lt;/p&gt;

&lt;p&gt;This is the new reality: attackers are no longer just targeting your code. They're targeting your AI pipelines, your automated flows, your trust relationships.&lt;/p&gt;

&lt;p&gt;We've also seen entirely new categories of AI-specific attacks emerge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prompt injection&lt;/strong&gt; tricking AI systems into ignoring their safety rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model poisoning&lt;/strong&gt; corrupting training data to manipulate AI behavior&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API abuse&lt;/strong&gt; exploiting poorly secured AI endpoints to extract data or bypass authentication&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Problem 2: Your supply chain is now a weapon
&lt;/h2&gt;

&lt;p&gt;If you're a JavaScript developer, this one should concern you directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On May 11, 2026, between 19:20 and 19:26 UTC just six minutes&lt;/strong&gt; an attacker published 84 malicious versions across 42 &lt;code&gt;@tanstack/*&lt;/code&gt; npm packages. If you've built anything with React or modern JS tooling, you've almost certainly used TanStack. &lt;code&gt;@tanstack/react-router&lt;/code&gt; alone has over &lt;strong&gt;12 million weekly downloads&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The attack was elegant and terrifying. The attacker forked a TanStack repository, submitted a malicious commit, and triggered GitHub Actions to automatically build and publish the malware poisoning the CI/CD cache in the process. No npm tokens were stolen. The pipeline itself became the weapon.&lt;/p&gt;

&lt;p&gt;The malicious packages could silently exfiltrate AWS credentials, GitHub tokens, SSH keys, and &lt;code&gt;.npmrc&lt;/code&gt; contents &lt;strong&gt;automatically, on every developer machine that ran &lt;code&gt;npm install&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The blast radius extended far beyond TanStack. Grafana Labs, OpenAI, and Vercel were all impacted through downstream dependencies. Other compromised packages included tools from Mistral AI, Bitwarden, and Aqua Security.&lt;/p&gt;

&lt;p&gt;This wasn't an isolated incident either it was the &lt;strong&gt;fourth wave&lt;/strong&gt; of an ongoing campaign by a threat group called TeamPCP, using a self-replicating worm dubbed "Mini Shai-Hulud."&lt;/p&gt;

&lt;p&gt;The lesson? &lt;strong&gt;Every &lt;code&gt;npm install&lt;/code&gt; is a trust decision.&lt;/strong&gt; And most of us make hundreds of them without thinking.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 3: Hackers are using AI to attack smarter
&lt;/h2&gt;

&lt;p&gt;On the other side of the equation, the people attacking these systems are also using AI and it's fundamentally changing what attacks look like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phishing used to be easy to spot.&lt;/strong&gt; Broken English, obvious templates, suspicious links. Most people learned to recognize them.&lt;/p&gt;

&lt;p&gt;Now? AI generates phishing emails that are grammatically perfect, contextually relevant, and deeply personalized. It can scrape your LinkedIn, your GitHub, your public social profiles and craft a message that sounds like it came from your actual manager.&lt;/p&gt;

&lt;p&gt;Microsoft tracked a phishing platform called &lt;strong&gt;Tycoon2FA&lt;/strong&gt; that generated tens of millions of phishing emails per month and was linked to nearly &lt;strong&gt;100,000 compromised organizations&lt;/strong&gt;. At its peak, it accounted for roughly &lt;strong&gt;62% of all phishing attempts&lt;/strong&gt; Microsoft was blocking monthly. It didn't just steal passwords it intercepted MFA tokens in real time, defeating two-factor authentication entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nation-states are in this too.&lt;/strong&gt; Microsoft and OpenAI confirmed that threat actors aligned with China, Iran, North Korea, and Russia are actively using large language models to enhance their offensive operations reconnaissance, scripting, social engineering at scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voice cloning, deepfake video, AI-generated text&lt;/strong&gt; all now available to attackers at low cost. What used to require an expert team can be done today with the right prompts and a modest budget.&lt;/p&gt;




&lt;h2&gt;
  
  
  So which is it AI in systems, or AI as a weapon?
&lt;/h2&gt;

&lt;p&gt;Both. And they compound each other.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Organizations are rushing to integrate AI features to stay competitive, often outpacing their security practices. At the same time, attackers are rapidly adopting AI to improve their techniques. The result is a widening gap between attack capability and defense readiness.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's not that AI is inherently dangerous. It's that &lt;strong&gt;speed of adoption without security rigor&lt;/strong&gt; creates windows of vulnerability that sophisticated attackers are very good at exploiting.&lt;/p&gt;

&lt;p&gt;Sam Altman himself acknowledged the possibility of a "world-shaking cyberattack" in 2026 as AI capabilities accelerate. That's not fear-mongering it's a signal that even the people building these systems know we're in uncharted territory.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this means for you as a developer
&lt;/h2&gt;

&lt;p&gt;A few concrete things worth thinking about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Audit your dependencies&lt;/strong&gt; the TanStack incident proves that even massively popular, well-maintained packages can be compromised&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Harden your CI/CD pipelines&lt;/strong&gt; GitHub Actions cache poisoning is a documented, repeatable attack class&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat AI integrations like any third-party dependency&lt;/strong&gt; understand their failure modes, limit their permissions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be skeptical of any input that reaches an AI model&lt;/strong&gt; prompt injection is real and underestimated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Educate your users&lt;/strong&gt; the human layer is still the most exploited vector, and AI is making social engineering much harder to detect&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The question I keep coming back to
&lt;/h2&gt;

&lt;p&gt;We're in a moment where AI is being embedded into everything build pipelines, support systems, authentication flows faster than our collective ability to understand the risks.&lt;/p&gt;

&lt;p&gt;The attacks we're seeing aren't theoretical anymore. They hit tools we use every single day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So here's what I want to know: as a developer, how are you thinking about security in your own projects? Has the TanStack incident changed how you approach your dependencies?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Drop your take below especially if you've been directly affected by a supply chain attack.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is part of a series where I share my honest thoughts on AI, learning, and building in tech *&lt;br&gt;
*Follow along on &lt;a href="https://www.facebook.com/profile.php?id=61585926839187" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Learning to Code in the AI Era Feels Broken. And Nobody Talks About It.</title>
      <dc:creator>TAGBA G-Josaphat E.</dc:creator>
      <pubDate>Wed, 10 Jun 2026 20:51:13 +0000</pubDate>
      <link>https://dev.to/josaphatstar/learning-to-code-in-the-ai-era-feels-broken-and-nobody-talks-about-it-1911</link>
      <guid>https://dev.to/josaphatstar/learning-to-code-in-the-ai-era-feels-broken-and-nobody-talks-about-it-1911</guid>
      <description>&lt;p&gt;Let me be honest about something uncomfortable.&lt;/p&gt;

&lt;p&gt;When you're learning to code today really learning, from scratch, fighting with syntax errors and logic bugs and CSS that refuses to behave there's a voice in the back of your head that won't shut up.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"AI could do this in 3 seconds."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That voice is brutal. And I think it's making learning harder than it's ever been.&lt;/p&gt;




&lt;h2&gt;
  
  
  When I started, AI wasn't there to do it for me
&lt;/h2&gt;

&lt;p&gt;I started web development a few years ago. JavaScript was confusing. CSS felt like a random guessing game. I spent entire evenings debugging a function that turned out to have a missing semicolon.&lt;/p&gt;

&lt;p&gt;But here's the thing: there was no shortcut. I &lt;em&gt;had&lt;/em&gt; to figure it out. The struggle wasn't optional it was the path.&lt;/p&gt;

&lt;p&gt;Every bug I fixed alone left a mark. Every concept I finally understood after hours of confusion became part of how I think as a developer.&lt;/p&gt;

&lt;p&gt;Now I look at someone just starting out in 2024-2025 and I wonder: &lt;strong&gt;what is their path?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The new frustration nobody prepares you for
&lt;/h2&gt;

&lt;p&gt;Imagine spending three days trying to understand how async/await works in JavaScript.&lt;/p&gt;

&lt;p&gt;You watch tutorials. You read docs. You write broken code, fix it, break it again. You're exhausted.&lt;/p&gt;

&lt;p&gt;Then a friend casually says: &lt;em&gt;"Just ask ChatGPT, it'll write the whole thing for you."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And it does. Perfectly. In 4 seconds.&lt;/p&gt;

&lt;p&gt;That feeling I don't have a perfect word for it. It's somewhere between frustration, discouragement, and a quiet existential question: &lt;strong&gt;why am I even doing this the hard way?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For someone just starting out, that feeling can be enough to make them quit. Or worse to never really start learning at all.&lt;/p&gt;




&lt;h2&gt;
  
  
  The gap between using and understanding
&lt;/h2&gt;

&lt;p&gt;Here's what worries me most about the current moment.&lt;/p&gt;

&lt;p&gt;There's a growing gap between two types of people in tech:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Those who can &lt;strong&gt;use&lt;/strong&gt; tools to build things&lt;/li&gt;
&lt;li&gt;Those who &lt;strong&gt;understand&lt;/strong&gt; what's happening under the hood&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI is making the first group explode in size. Anyone can ship a working app today with minimal technical knowledge. That's genuinely amazing.&lt;/p&gt;

&lt;p&gt;But the second group the people who truly understand systems, who can debug when things break in unexpected ways, who can make real architectural decisions that group is built through struggle. Through learning the hard way.&lt;/p&gt;

&lt;p&gt;And right now, we're making the hard way feel pointless.&lt;/p&gt;




&lt;h2&gt;
  
  
  The basics still matter. Maybe more than ever.
&lt;/h2&gt;

&lt;p&gt;I learned HTML before I touched any framework. I wrote vanilla JavaScript before I used Vue or React. I understood what a loop actually does before I let anyone human or AI write one for me.&lt;/p&gt;

&lt;p&gt;That foundation is why I can look at AI-generated code and know if it's good, bad, or dangerous. It's why I can debug when things break. It's why I can have opinions about architecture instead of just accepting whatever the AI gives me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you skip the basics, you don't become a developer. You become dependent on a tool you don't understand.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And tools break. Tools change. Tools have limits you can't see if you don't know what's underneath.&lt;/p&gt;




&lt;h2&gt;
  
  
  So. Vibe coding.
&lt;/h2&gt;

&lt;p&gt;If you haven't heard the term: vibe coding is the idea of building software almost entirely through AI prompts, with minimal traditional coding. You describe what you want, the AI builds it, you iterate.&lt;/p&gt;

&lt;p&gt;Some people think it's the future of development. Some think it's a dangerous shortcut. Most of us are somewhere in the middle, figuring it out.&lt;/p&gt;

&lt;p&gt;I genuinely don't have a definitive answer. But I have a question I keep coming back to:&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If a new developer today learns entirely through vibe coding never really wrestling with the fundamentals what kind of developer are they in 5 years?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Are they more creative and productive because they offloaded the boring parts?&lt;/p&gt;

&lt;p&gt;Or are they fragile, because they built on a foundation they never actually learned?&lt;/p&gt;

&lt;p&gt;I don't know. But I think how we answer that question will define what "being a developer" means in the next decade.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What do you think? Should beginners learn the basics the hard way before touching AI? Or is vibe coding a legitimate new path into tech? Drop your take below I really want to know.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is part of a series where I share my honest thoughts on learning, AI, and building a career in tech.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Follow along on &lt;a href="https://www.facebook.com/profile.php?id=61585926839187" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Hidden Problem With Learning Through AI</title>
      <dc:creator>TAGBA G-Josaphat E.</dc:creator>
      <pubDate>Wed, 03 Jun 2026 19:44:06 +0000</pubDate>
      <link>https://dev.to/josaphatstar/the-hidden-problem-with-learning-through-ai-2ki8</link>
      <guid>https://dev.to/josaphatstar/the-hidden-problem-with-learning-through-ai-2ki8</guid>
      <description>&lt;p&gt;AI is an incredible learning tool. I said it in my &lt;a href="https://dev.to/josaphatstar/im-a-masters-student-in-ai-big-data-and-ai-just-gave-me-my-freedom-back-j9d"&gt;previous article&lt;/a&gt;, and I still believe it.&lt;/p&gt;

&lt;p&gt;But after spending months learning new web frameworks and technologies with AI as my main companion, I noticed something uncomfortable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I was moving fast. But was I really understanding?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The old way was painful and powerful
&lt;/h2&gt;

&lt;p&gt;Before AI, learning a new technology meant suffering.&lt;/p&gt;

&lt;p&gt;You'd hit a bug. You'd search for hours. Read Stack Overflow threads, YouTube videos. Try things that didn't work. Get frustrated. Sleep on it. Come back the next day and finally &lt;em&gt;click&lt;/em&gt;. It works.&lt;/p&gt;

&lt;p&gt;That process was slow. Sometimes humiliating. Often exhausting.&lt;/p&gt;

&lt;p&gt;But here's what I didn't realize at the time: &lt;strong&gt;that struggle was doing something to my brain.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every hour spent searching, failing, and retrying was building a deep, almost physical understanding of the concept. When I finally found the solution, I &lt;em&gt;owned&lt;/em&gt; it. I knew not just the answer, but every wrong path around it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Now I just ask. And get an answer. Instantly.
&lt;/h2&gt;

&lt;p&gt;With AI, that whole painful loop collapses into a single message.&lt;/p&gt;

&lt;p&gt;Bug? Ask AI. Confusing concept? Ask AI. Don't know the right syntax? Ask AI.&lt;/p&gt;

&lt;p&gt;The answer comes in seconds. Clean. Well-explained. Usually correct.&lt;/p&gt;

&lt;p&gt;And I move on.&lt;/p&gt;

&lt;p&gt;The problem is: &lt;strong&gt;moving on is not the same as understanding.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I actually noticed
&lt;/h2&gt;

&lt;p&gt;Learning Vue, Nuxt, and other web technologies with AI, I realized something: &lt;strong&gt;I needed to build far more projects than before to reach the same depth of understanding.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without AI, one difficult project could teach me something deeply because I had wrestled with every problem alone.&lt;/p&gt;

&lt;p&gt;With AI, I could finish that same project twice as fast, but the understanding was shallower. I had to build three or four more projects to reach the same level of genuine comprehension.&lt;/p&gt;

&lt;p&gt;The friction wasn't just wasted time. &lt;strong&gt;The friction was the learning.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  This doesn't mean AI is bad for learning
&lt;/h2&gt;

&lt;p&gt;I'm not saying we should go back to suffering alone for hours.&lt;/p&gt;

&lt;p&gt;What I'm saying is: &lt;strong&gt;we need to be intentional.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A few things that help me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Try first, ask second.&lt;/strong&gt; Before asking AI, I give myself at least 15-20 minutes to struggle alone. The struggle primes my brain to actually absorb the answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask AI to explain, not just fix.&lt;/strong&gt; Instead of "fix this bug", I ask "why is this happening and what does it teach me about how this framework works?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build more, copy less.&lt;/strong&gt; More small projects from scratch. Less copy-pasting AI-generated code without understanding it.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The bottom line
&lt;/h2&gt;

&lt;p&gt;AI accelerates learning. But depth still comes from doing really doing and from the discomfort of not knowing yet.&lt;/p&gt;

&lt;p&gt;The goal isn't to avoid AI. It's to use it without losing the struggle that makes knowledge stick.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you felt this too? Are you learning faster but sometimes feeling like things don't fully sink in? Let's talk in the comments.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Follow my journey on &lt;a href="https://www.facebook.com/profile.php?id=61585926839187" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt; I share thoughts on tech, learning, and building in the open.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>learning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I'm a Master's Student in AI &amp; Big Data. And AI Just Gave Me My Freedom Back.</title>
      <dc:creator>TAGBA G-Josaphat E.</dc:creator>
      <pubDate>Tue, 26 May 2026 16:37:13 +0000</pubDate>
      <link>https://dev.to/josaphatstar/im-a-masters-student-in-ai-big-data-and-ai-just-gave-me-my-freedom-back-j9d</link>
      <guid>https://dev.to/josaphatstar/im-a-masters-student-in-ai-big-data-and-ai-just-gave-me-my-freedom-back-j9d</guid>
      <description>&lt;p&gt;I'm currently preparing my Master's degree in AI &amp;amp; Big Data.&lt;/p&gt;

&lt;p&gt;You'd think that means I spend my days confidently building neural networks, designing data pipelines, and shipping ML models. And in a way, yes — that's the curriculum.&lt;/p&gt;

&lt;p&gt;But here's the thing no one really talks about in tech education: &lt;strong&gt;we learned a lot of things, and almost none of them deeply enough.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The paradox of a broad curriculum
&lt;/h2&gt;

&lt;p&gt;In my program, we covered a bit of everything. Machine learning. Big Data architecture. Statistics. Cloud infrastructure. Web development. Databases. Computer vision. NLP.&lt;/p&gt;

&lt;p&gt;Every few weeks, a new topic. Every few weeks, just enough to understand the surface before moving on.&lt;/p&gt;

&lt;p&gt;I don't blame my professors or my school. That's just the nature of a two-year program trying to give you a panoramic view of a field that's enormous.&lt;/p&gt;

&lt;p&gt;But it left me with a strange feeling: &lt;strong&gt;I knew &lt;em&gt;about&lt;/em&gt; a lot of things, but I couldn't really &lt;em&gt;do&lt;/em&gt; most of them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And as graduation gets closer, the pressure grows: pick a lane. Choose a specialty. Decide who you are professionally.&lt;/p&gt;

&lt;p&gt;Web developer? Data engineer? ML engineer? Backend dev? DevOps?&lt;/p&gt;

&lt;p&gt;I had to choose — because that's how the job market works.&lt;/p&gt;




&lt;h2&gt;
  
  
  The cost of choosing
&lt;/h2&gt;

&lt;p&gt;Here's what hurt the most about that choice: &lt;strong&gt;curiosity doesn't disappear when you pick a lane.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I chose to focus on web development alongside my studies — Vue/Nuxt, JavaScript, TypeScript, CSS. I love it. But I've always been drawn to everything else too.&lt;/p&gt;

&lt;p&gt;I'd look at a computer vision project and think: &lt;em&gt;"I want to build something like this."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I'd see a cool data pipeline and think: &lt;em&gt;"I want to understand how that really works."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I'd read about systems programming, DevOps, mobile development, and feel that familiar pull.&lt;/p&gt;

&lt;p&gt;But exploring those domains felt expensive. Not in money — in &lt;strong&gt;time and frustration&lt;/strong&gt;. The entry cost for any new technical field is high: new syntax, new mental models, new tooling, new vocabulary. You spend weeks just getting comfortable before you can do anything interesting.&lt;/p&gt;

&lt;p&gt;And with a Master's thesis, coursework, and personal projects already fighting for my attention, that entry cost was almost always too high.&lt;/p&gt;

&lt;p&gt;So I held back. I watched from the edges.&lt;/p&gt;




&lt;h2&gt;
  
  
  Then AI changed the equation
&lt;/h2&gt;

&lt;p&gt;When I started using AI as a learning companion — not just to generate code, but to actually &lt;em&gt;explore&lt;/em&gt; — something shifted.&lt;/p&gt;

&lt;p&gt;The entry cost dropped dramatically.&lt;/p&gt;

&lt;p&gt;Now when I'm curious about something new, I don't have to start from zero alone. I have a thinking partner that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explains new concepts &lt;strong&gt;by connecting them to things I already know&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Helps me read and understand code from domains I'm not fluent in&lt;/li&gt;
&lt;li&gt;Answers the "dumb" questions I'd be embarrassed to ask anyone else&lt;/li&gt;
&lt;li&gt;Turns a confusing error message into an actual learning moment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want to understand how a Kafka pipeline works? I can explore it in a real conversation, mapped to my existing mental models — not by reading a dense 40-page documentation for two weeks.&lt;/p&gt;

&lt;p&gt;Curious about how a specific ML architecture actually processes data? I can dig into it interactively, ask follow-up questions, build a mental picture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The translation layer that used to take weeks now takes a conversation.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  This is not about shortcuts
&lt;/h2&gt;

&lt;p&gt;I want to be honest here, because I know how this sounds.&lt;/p&gt;

&lt;p&gt;This is not about having AI do everything for me. It's not about faking expertise I don't have.&lt;/p&gt;

&lt;p&gt;It's about &lt;strong&gt;removing the fear and friction of being a beginner in something new.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I still struggle. I still hit walls. I still have to put in real work to actually understand things. But now I can get to the interesting part — the part where concepts click, where I can build something small, where curiosity turns into real knowledge — without burning weeks just fighting the setup.&lt;/p&gt;

&lt;p&gt;That changes everything about how willing I am to explore.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I actually believe now
&lt;/h2&gt;

&lt;p&gt;For a long time, I thought choosing one specialty was the only responsible path. The market rewards experts, right? Go deep. Become &lt;em&gt;the&lt;/em&gt; AI person, or &lt;em&gt;the&lt;/em&gt; frontend person, or &lt;em&gt;the&lt;/em&gt; data person.&lt;/p&gt;

&lt;p&gt;But I've started to think that framing was always a bit off.&lt;/p&gt;

&lt;p&gt;The most impactful people in tech I look up to aren't people who know one thing incredibly well. They're people with &lt;strong&gt;wide peripheral vision&lt;/strong&gt; — who understand enough about different domains to connect ideas, ask better questions, and see things that pure specialists miss.&lt;/p&gt;

&lt;p&gt;AI didn't make me a generalist overnight. But it gave me permission to &lt;strong&gt;be curious without guilt&lt;/strong&gt;, and the tools to turn that curiosity into something real.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where I am now
&lt;/h2&gt;

&lt;p&gt;I'm still a Master's student in AI &amp;amp; Big Data. Still building in Vue/Nuxt. Still figuring out what my career will look like.&lt;/p&gt;

&lt;p&gt;But I no longer feel like I have to wall myself off from everything that isn't my specialty.&lt;/p&gt;

&lt;p&gt;I explore data engineering because it helps me understand the full picture of what I'm studying.&lt;/p&gt;

&lt;p&gt;I write frontend code because building things that people can see and touch keeps me grounded.&lt;/p&gt;

&lt;p&gt;I poke at ML projects not because I'll be an ML researcher, but because understanding them makes me better at everything else.&lt;/p&gt;

&lt;p&gt;Am I an expert in all of these? Absolutely not.&lt;/p&gt;

&lt;p&gt;But am I afraid of any of them? Not anymore.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Are you also a student or early-career dev who feels pressure to specialize? How do you handle the tension between depth and curiosity? I'd love to hear your experience in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>student</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
