The Goal

By the end of this blueprint you'll have a live app that does two things. You paste some text (or a PDF, or a URL), and it becomes searchable knowledge. Then you ask a question in plain English and get back an answer that's grounded in what you uploaded — with a numbered list of the exact sources it stood on:

"What does the onboarding doc say about the trial period?"

"The trial lasts 14 days and converts automatically unless cancelled [1]. Card details are required up front [2]."

Sources: [1] onboarding.pdf · [2] pricing-faq.md

No hallucinated answers, no "I read the whole internet" hand-waving. The model only ever sees the handful of chunks a similarity search pulled back, and it's told to say "I don't know" when the answer isn't in them.

RAG is two phases, always

Retrieval-Augmented Generation sounds like one thing but it's really two, and keeping them separate is the whole mental model:

  • Write phase (ingest). A document comes in → split it into overlapping chunks → turn each chunk into an embedding (a vector of numbers that captures its meaning) → store the chunk + its vector in Postgres.
  • Read phase (query). A question comes in → embed the question into the same vector space → find the nearest chunks by vector similarity → hand those chunks to the model and ask it to answer only from them.

The magic isn't the model — it's that "find me text that means the same thing as this question" becomes a fast math operation (nearest vectors) once everything is an embedding.

Why "agentic" RAG

Classic RAG is a fixed pipeline: always retrieve, always stuff the results into one prompt, always answer. Agentic RAG reframes retrieval as a tool the model's loop can decide to call — search when it needs to, search again with a better query, or skip it entirely. This build implements the retrieval + grounding core that any agentic version sits on top of: the query function embeds a question, calls a match_documents retrieval tool, and grounds the answer in what came back. Wire that same retrieval step into an agent's tool loop and you've got the agentic version — the retrieval and grounding machinery is identical, which is exactly what we're building here.

The three moving parts

  1. Next.js upload page (Vercel) — one client component. Paste text, drop a URL, or pick a PDF; then an ask box. It holds no secrets.
  2. Supabase: chunk, embed, store — the ingest Edge Function does the write phase.
  3. Supabase: question, retrieve, ground — the query Edge Function does the read phase and returns the answer with sources.

How the pieces fit together

Notice that Supabase is doing four jobs in this build: it's the Postgres database, the pgvector vector store, the Edge Functions runtime — which also runs the embedding model (gte-small) in-process, so your text never leaves Supabase to get vectorized — and the RLS fence that locks the table. One account, four roles, and the only external call in the whole build is Gemini writing the final answer. That's why it fits in ten minutes.

The two-keys rule

This is the one security idea to internalize before you write any code:

  • The anon key is public. It ships in browser JavaScript across the entire Supabase ecosystem — that's fine, it's designed for it. It's the only key the front-end ever sees.
  • The service-role key and the Gemini key are secrets. They live only inside the Edge Functions, set as Supabase secrets, and never leave the server. (Embeddings need no key at all — gte-small runs inside Supabase, so the Gemini key is the only model key in the whole build.)

So: the browser never talks to Gemini. Every model call happens server-side, inside a function. Put a Gemini key in client JavaScript and someone will scrape it out of your bundle and run up a five-figure bill on your account overnight. The functions are the wall between the public browser and the expensive keys.

How this differs from the other two RAG blueprints

Brain Drip has two other RAG builds; this one is a deliberate third point on the map:

BlueprintStackShape
Build a RAG PipelinePlain PythonLocal script, learn the mechanics
RAG on Cloud SQL + pgvectorGCP (Cloud SQL)Managed Postgres on Google Cloud
This oneNext.js + Supabase + GeminiDeployed web app, agentic framing

If the Python one taught you what RAG is, this one is ship a real one: a public web app, server-side keys, and the retrieval-as-a-tool framing that scales up to an agent.

What you'll need before Step 2

Step 2 builds the data model: one table, one index, one retrieval function.