DEV Community

Sunny Dagar
Sunny Dagar

Posted on

RAG Without a Vector Database: My Production Assistant Runs on MariaDB and 10 Lines of Cosine Similarity

Everyone will tell you that building a RAG (Retrieval-Augmented Generation) assistant means signing up for Pinecone, Weaviate, or spinning up pgvector. I want to show you the counter-example I run in production: the AI assistant on my robotics platform, roboturfs.ca, answers customer questions every day with no vector database at all—just MariaDB, Gemini embeddings, and a cosine-similarity function that fits in ten lines of PHP.

This isn't a toy. It retrieves knowledge, quotes live inventory and prices, captures leads, and books appointments. Here's how it works, why I built it this way, and honestly when you should not copy me.

What RAG actually requires (less than you think)

Strip away the hype and RAG needs exactly four things:

  1. Chunks of your content (knowledge-base entries, docs, FAQs)
  2. An embedding per chunk—a list of numbers that captures its meaning
  3. A way to find the nearest chunks by meaning when a question arrives
  4. A prompt that pastes those chunks in and tells the model to answer only from them

Notice what's missing: nothing in that list says "dedicated vector database." A vector DB is a scaling optimization, not a requirement of the pattern.

My setup

  • Embeddings: Google's gemini-embedding at 256 dimensions. One API call per chunk.
  • Storage: each chunk lives in a plain MariaDB table (kb_chunks (id, title, content, embedding)) with the embedding cached as JSON in a column.
  • Lazy embedding: chunks are embedded on first use, then cached forever. Add a new knowledge chunk to the table today, the assistant knows it today—no reindexing pipeline, no deploy.
  • Retrieval: brute-force cosine similarity over every chunk, in PHP, at request time. Top 4 chunks win.
  • Corpus size: a few hundred chunks.

The entire "vector search engine"

This is the actual production code:


php
function cosine(array $a, array $b): float {$dot = $na =$nb = 0.0;
    $n = min(count($a), count($b));
    for ($i = 0; $i <$n; $i++) {$dot += $a[$i] * $b[$i];
        $na +=$a[$i] *$a[$i];$nb += $b[$i] * $b[$i];
    }
    return ($na && $nb) ?$dot / (sqrt($na) * sqrt($nb)) : 0.0;
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)