An interactive, educational web application for learning and comparing different Retrieval-Augmented Generation (RAG) architectures. Built with Next.js 15, TypeScript, and Supabase.
RAG Playground is a hands-on learning platform that helps you understand how different RAG architectures work by:
- Comparing 5 RAG architectures side-by-side in real-time
- Streaming execution timelines showing each step as it happens
- Interactive controls to tune parameters and see their effects
- Educational content explaining the theory behind each approach
Perfect for developers, researchers, and anyone learning about RAG systems!
- Standard RAG - Baseline vector similarity search
- Advanced RAG - Query expansion with multi-query retrieval and reranking
- Hybrid RAG - Combines semantic (vector) and keyword (full-text) search using RRF
- Agentic RAG - Autonomous agent with planning, self-evaluation, and iteration
- GraphRAG - Entity-relationship extraction with knowledge graph traversal
Watch each RAG mode execute step-by-step in real-time:
- See embeddings generated
- Track similarity searches
- Monitor LLM calls
- View performance metrics
- Understand the complete flow
- Run two RAG modes side-by-side with the same query
- Compare speed, quality, and approach
- Adjust parameters (threshold, max tokens, model)
- View detailed sources and execution steps
- Dynamic embedding models - Choose from 3 OpenAI models
- Adjustable chunk size/overlap - Optimize for your use case
- Similarity threshold control - Fine-tune retrieval precision
- Token output limits - Control response length
- Model selection - Currently supports GPT-4o-mini
- Dark mode support
- Responsive design (mobile to desktop)
- Smart logging (no spam for large files)
- Type-safe TypeScript throughout
- Modular, maintainable codebase
- Optional LangSmith integration - Trace & debug RAG queries (not embeddings)
- Server-Sent Events (SSE) for real-time progress updates
- Node.js 18+ (20+ recommended)
- pnpm 8+ or npm 9+
- Supabase account (free tier works!)
- OpenAI API key with access to GPT-4o models
git clone https://github.com/yourusername/rag-playground.git
cd rag-playgroundUsing pnpm (recommended):
pnpm installOr using npm:
npm install-
Create a new project at supabase.com
-
Go to Settings β API and copy:
Project URLservice_rolekey (notanonkey!)
-
Run the database setup in the Supabase SQL Editor:
Go to your Supabase project β SQL Editor β New Query
Copy the contents of supabase/migrations/000_complete_setup.sql and paste it into the editor, then click Run.
This single migration creates:
- β pgvector extension
- β
documentsanddocument_chunkstables - β Vector similarity indexes
- β
match_document_chunks()function (for Standard/Advanced/Agentic/GraphRAG) - β
hybrid_search()function (for Hybrid RAG) - β Row Level Security policies
π View the complete SQL (click to expand)
-- Enable pgvector extension
CREATE EXTENSION IF NOT EXISTS vector;
-- Create documents table
CREATE TABLE IF NOT EXISTS documents (
id UUID PRIMARY KEY,
filename TEXT NOT NULL,
content TEXT NOT NULL,
file_type TEXT,
uploaded_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
metadata JSONB DEFAULT '{}'::jsonb
);
-- Create document_chunks table with vector embeddings
CREATE TABLE IF NOT EXISTS document_chunks (
id UUID PRIMARY KEY,
document_id UUID REFERENCES documents(id) ON DELETE CASCADE,
content TEXT NOT NULL,
embedding vector(1536),
chunk_index INTEGER NOT NULL,
total_chunks INTEGER NOT NULL,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create indexes
CREATE INDEX IF NOT EXISTS document_chunks_embedding_idx
ON document_chunks USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
CREATE INDEX IF NOT EXISTS document_chunks_document_id_idx
ON document_chunks(document_id);
-- Create similarity search function
CREATE OR REPLACE FUNCTION match_document_chunks(
query_embedding vector(1536),
match_threshold FLOAT DEFAULT 0.5,
match_count INT DEFAULT 5
)
RETURNS TABLE (id UUID, document_id UUID, content TEXT, similarity FLOAT, metadata JSONB)
LANGUAGE plpgsql AS $$
BEGIN
RETURN QUERY
SELECT dc.id, dc.document_id, dc.content,
1 - (dc.embedding <=> query_embedding) AS similarity, dc.metadata
FROM document_chunks dc
WHERE 1 - (dc.embedding <=> query_embedding) > match_threshold
ORDER BY dc.embedding <=> query_embedding
LIMIT match_count;
END;
$$;
-- Create hybrid search function (full SQL in file)
CREATE OR REPLACE FUNCTION hybrid_search(...) RETURNS TABLE (...) LANGUAGE sql AS $$ ... $$;
-- Enable RLS and create policies
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
ALTER TABLE document_chunks ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all operations on documents" ON documents FOR ALL USING (true);
CREATE POLICY "Allow all operations on document_chunks" ON document_chunks FOR ALL USING (true);
-- Grant permissions
GRANT EXECUTE ON FUNCTION match_document_chunks TO authenticated, anon, service_role;
GRANT EXECUTE ON FUNCTION hybrid_search TO authenticated, anon, service_role;π‘ Troubleshooting: If you get any errors, make sure you're using the
service_rolekey in your.env.local(not theanonkey).
Create a .env.local file in the root directory:
# Supabase
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
# OpenAI
OPENAI_API_KEY=your_openai_api_key
# Optional: LangSmith (for tracing & debugging)
# LANGCHAIN_TRACING_V2=true
# LANGCHAIN_API_KEY=your_langsmith_api_key
# LANGCHAIN_PROJECT=rag-playgroundservice_role key for SUPABASE_SERVICE_ROLE_KEY, not the anon key!
π‘ Optional: LangSmith provides tracing and observability for debugging RAG operations. The app works perfectly fine without it. Free tier: 5,000 traces/month.
Using pnpm:
pnpm devOr using npm:
npm run devOpen http://localhost:3000 in your browser.
- Click the Documents tab in the sidebar
- Select embedding model (text-embedding-3-small recommended)
- Adjust chunk size/overlap if needed (Advanced Settings)
- See estimated cost before uploading
- Drag & drop files or click to upload
- Watch real-time progress: Text extraction β Chunking β Embedding generation
- Supported formats:
.txt,.md,.pdf,.docx
New Features:
- π Live Progress Tracking - See exactly what's happening during upload
- π° Cost Estimation - Know the embedding cost before you upload
- π PDF Support - Powered by LangChain's WebPDFLoader
- π Smart Error Handling - Helpful messages for encrypted PDFs and other issues
π‘ Quick Start: A sample document is included at
public/Sample_RAG_Paper.mdβ a comprehensive paper on RAG architectures perfect for testing!
- Select Left Mode and Right Mode from the comparison panel
- Adjust Threshold (0-100%) - higher = more strict matching
- Adjust Max Tokens (100-2000) - control response length
- Select Model (currently gpt-4o-mini)
- Enter your question
- Click Run Left, Run Right, or Run Both
- Each mode shows a real-time Execution Timeline
- Expand to see detailed metrics for each step
- Learn how different RAG approaches work under the hood
- Click the Docs tab in the sidebar
- Read Overview for detailed architecture explanations
- Understand when to use each RAG mode
- Learn about trade-offs between speed, quality, and complexity
rag-playground/
βββ app/
β βββ api/
β β βββ documents/ # Document upload & management
β β βββ rag/
β β βββ modes/ # Non-streaming RAG implementations
β β β βββ standard.ts
β β β βββ advanced.ts
β β β βββ hybrid.ts
β β βββ streaming/ # Streaming RAG implementations
β β β βββ standard-stream.ts
β β β βββ advanced-stream.ts
β β β βββ hybrid-stream.ts
β β β βββ agentic-stream.ts
β β β βββ graph-stream.ts
β β βββ query/ # Main query endpoint
β βββ page.tsx # Main app component
βββ components/
β βββ comparison-mode.tsx # Side-by-side comparison UI
β βββ execution-timeline.tsx # Real-time step visualization
β βββ file-upload.tsx # Document upload component
β βββ learn-content.tsx # Educational content
β βββ rag-response-display.tsx # Response renderer
βββ lib/
β βββ openai.ts # OpenAI client config
β βββ supabase.ts # Supabase client config
β βββ logger.ts # Structured logging utility
βββ types/
βββ rag.ts # TypeScript type definitions
- Generate query embedding (1536 dimensions)
- Vector similarity search in Supabase
- Retrieve top-K chunks above threshold
- Generate answer with LLM
- Query expansion (generate 2 alternative phrasings)
- Multi-query retrieval (3 parallel searches)
- Deduplicate and rerank by similarity
- Generate answer with enhanced context
- Generate query embedding
- Parallel execution:
- Semantic search (vector similarity)
- Keyword search (full-text)
- Merge results using Reciprocal Rank Fusion (RRF)
- Generate answer with hybrid context
- Autonomous Planning - Analyze query complexity, choose strategy
- Adaptive Retrieval - Execute chosen strategy (semantic or expansion)
- Self-Evaluation - Assess quality, re-retrieve if needed
- Answer Generation - Generate response with optimized context
- Entity Extraction - Identify 2-4 key entities from query
- Multi-Entity Search - Independent searches per entity
- Relationship Discovery - Find connections between entities
- Graph-Aware Answer - Generate response with relationship context
| RAG Mode | Best For | Speed | Quality |
|---|---|---|---|
| Standard | Simple Q&A, speed-critical | β‘β‘β‘ | ββ |
| Advanced | Better recall, diverse phrasings | β‘β‘ | βββ |
| Hybrid | Exact terms + semantic meaning | β‘β‘β‘ | βββ |
| Agentic | Complex reasoning, adaptive | β‘ | ββββ |
| GraphRAG | Relationship questions | β‘ | ββββ |
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Please ensure:
- Code follows TypeScript best practices
- All linting passes (
pnpm lint) - Components are properly typed
- New features include appropriate logging
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Next.js and TypeScript
- Vector database powered by Supabase with pgvector
- LLM integration via OpenAI and LangChain
- UI components from shadcn/ui
- Icons by Lucide
Questions? Feedback? Open an issue or reach out!
Made with β€οΈ for the RAG community
β If you find this project helpful, please star it on GitHub!