惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
Vercel News
Vercel News
C
Check Point Blog
G
Google Developers Blog
博客园 - 司徒正美
量子位
Engineering at Meta
Engineering at Meta
S
SegmentFault 最新的问题
Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
A
About on SuperTechFans
美团技术团队
D
DataBreaches.Net
Stack Overflow Blog
Stack Overflow Blog
Jina AI
Jina AI
Y
Y Combinator Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Apple Machine Learning Research
Apple Machine Learning Research
J
Java Code Geeks
MongoDB | Blog
MongoDB | Blog
人人都是产品经理
人人都是产品经理
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The Cloudflare Blog
U
Unit 42

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
I Built 'Chat With Your Docs' From Scratch — Supabase + p...
Devanshu Biswas · 2026-06-14 · via DEV Community

Devanshu Biswas

"Chat with your PDF / your notes / your docs" is everywhere. Today we build it from scratch and you'll see it's just three moves: retrieve, then generate — with one prompt trick that stops the hallucinations.

This is Day 46 of TechFromZero. Yesterday (Day 45) we built the retrieval half with pgvector. Today we add the answer half and host it on Supabase.

RAG in one line

Find the relevant chunks of your documents, paste them into the prompt, and tell the model to answer using only those.

That's Retrieval-Augmented Generation. The "augmented" part is just stuffing real context into the prompt so the model isn't guessing from memory.

1. Storage: Supabase is Postgres, so pgvector is one click

Supabase is hosted Postgres with an auto-generated API. Because it's just Postgres, vector search needs no separate database:

create extension if not exists vector;

create table documents (
  id        bigserial primary key,
  content   text,
  embedding vector(384)
);

-- one RPC the app calls to get the closest chunks
create function match_documents(query_embedding vector(384), match_count int)
returns table (id bigint, content text, similarity float)
language sql stable as $$
  select id, content, 1 - (embedding <=> query_embedding) as similarity
  from documents order by embedding <=> query_embedding limit match_count;
$$;

2. Ingest: chunk → embed → store

Split your docs into paragraph-sized chunks, embed each with a free local model (all-MiniLM-L6-v2 via Transformers.js — no key, nothing leaves your machine), and insert the row + vector:

const embedding = await embed(chunk);     // 384 numbers
await supabase.from("documents").insert({ content: chunk, embedding });

Chunk size matters: too big buries the answer in noise, too small loses meaning. A few hundred characters is a good start.

3. Retrieve + Generate (the payoff)

Embed the question with the same model, ask Supabase for the closest chunks, then hand them to the LLM:

const query_embedding = await embed(question);
const { data: chunks } = await supabase.rpc("match_documents", { query_embedding, match_count: 4 });

const prompt = `Answer using ONLY the context below.
If the answer isn't there, say "I don't know based on the documents."

Context:
${chunks.map(c => "- " + c.content).join("\n")}

Question: ${question}`;

const answer = (await gemini.generateContent(prompt)).response.text();

The line that kills hallucinations

"Answer using ONLY the context. If it isn't there, say I don't know."

Without it, the model blends its own (possibly wrong) memory back in. With it, the model becomes a librarian that quotes your documents instead of a stranger guessing. Return the chunks alongside the answer so users can verify.

Why this stack

  • Supabase — managed Postgres + pgvector, free tier, no separate vector DB.
  • Transformers.js embeddings — free, local, private; ingest costs nothing.
  • Gemini free tier — only the final answer makes an API call.

Get this and you've built the core of every "AI that knows your data" product.

Repo: https://github.com/dev48v/supabase-rag-from-zero

This was Day 46 of TechFromZero. A new technology every day, built from scratch.