Skip to content
Product

Every piece of a RAG app, already built.

Ingestion, embeddings, vector search, streaming chat and demo protection — wired together as readable Next.js code you own.

Web Scraping

Web Scraping Engine

Turn any URL into searchable knowledge in seconds.

FastRAG's scraping pipeline fetches any public URL and strips it down to pure signal — no nav menus, no cookie banners, no boilerplate. It intelligently targets semantic content zones like <main> and <article> before falling back to the full page body.

The extracted text is chunked with LangChain's RecursiveCharacterTextSplitter and stored in Pinecone under an isolated namespace, ready for retrieval. The whole pipeline runs serverlessly on Vercel with zero ESM conflicts.

  • Fully compatible with Vercel serverless — zero ESM issues
  • Targets semantic content zones before falling back to body
  • Strips nav, footers, scripts, and boilerplate automatically
  • Configurable chunk size (1000 characters) and overlap (200 characters)
  • 15-second timeout, 5MB size cap and graceful error handling
  • SSRF-safe: only public web addresses, redirects re-validated
pages/api/ingest-url.js
// pages/api/ingest-url.jsasync function scrapeUrl(url) {  // → fetch → parse → strip boilerplate  // → target <main> / <article> first  // → chunk with RecursiveCharacterTextSplitter  // → upsert to Pinecone namespace}
PDF Ingestion

PDF Ingestion Pipeline

Drag, drop, and start chatting with any document.

The PDF pipeline accepts multipart form uploads up to 20MB. Files are parsed for full text extraction, chunked, embedded, and stored in Pinecone — every chunk tagged with its source filename so the chat interface can cite exactly which document an answer came from.

Temp files are deleted from disk immediately after processing. Ingestion statistics (chunks created, characters processed) are returned to the frontend so users get immediate confirmation of what was indexed.

  • Multipart upload — no base64 encoding overhead
  • Full text extraction from any standard PDF
  • Per-chunk source metadata for accurate citations
  • Temp files cleaned up immediately after processing
  • Returns chunk count and character stats on completion
pages/api/ingest-pdf.js
// pages/api/ingest-pdf.jsexport default async function handler(req, res) {  // → parse multipart upload (up to 20MB)  // → extract text from PDF buffer  // → chunk → embed in batch → upsert  // → return { chunksIngested, totalCharacters }}
Voyage AI Embeddings

Voyage AI Embeddings

Anthropic's recommended embeddings — 200M free tokens to start.

FastRAG uses Voyage AI's voyage-3.5 model — the embeddings provider officially recommended by Anthropic. The first 200 million tokens are free, covering roughly 400,000 document pages before you pay anything.

Separate embedding instances are used for documents and queries, optimising the vector space for asymmetric retrieval — the pattern where short questions retrieve long passages. LangChain handles batch splitting automatically.

  • voyage-3.5 — Anthropic's recommended embedding model
  • 200M free tokens — ~400,000 document pages at no cost
  • Separate document vs. query embedders for asymmetric retrieval
  • LangChain handles batch splitting automatically
  • Singleton instances prevent cold-start overhead per request
lib/embeddings.js
// lib/embeddings.js// Separate instances for document ingestion// and query retrieval — optimised vector space// for asymmetric search (short query → long doc) export const embedBatch = (texts) => { ... }export const embedQuery = (query) => { ... }
Streaming

Real-Time Claude Streaming

Answers appear word by word, grounded in your documents.

FastRAG streams responses using claude-haiku-4-5 — Anthropic's fastest Claude model — chosen for demo latency: first token arrives in under a second even on cold starts.

The first SSE event carries source citations and a usage payload before any answer text, so the UI renders source cards and updates the usage meter without a separate API call. If no chunks score above the relevance threshold, Claude says so — graceful degradation over confident fabrication.

  • claude-haiku-4-5 — fastest Claude model, sub-second TTFT
  • First SSE event carries sources + usage in one payload
  • Retrieved context injected into system prompt via <context> tags
  • 0.3 cosine similarity threshold filters irrelevant chunks
  • Usage meter stays in sync without a separate status call
lib/claude.js
// lib/claude.js// → anthropic.messages.stream() with RAG system prompt// → first event: sources + usage metadata// → token deltas streamed as SSE// → final event: done flag + token usage stats
Demo Rate Limiting

IP-Based Demo Rate Limiting

Let visitors experience the product — without burning your API budget.

FastRAG ships with a production-ready IP-based rate limiter built for public demo pages. Each visitor gets 5 chat messages and 3 ingestions per 24-hour window before being nudged toward sign-up.

Limits are tracked per visitor IP in Upstash Redis with a 24-hour TTL, so counters reset on their own. The API returns structured 429 responses with a resetAt timestamp so the UI can show an exact countdown. Usage meters, amber warnings at 70%, and a full upgrade CTA wall are all included.

  • 5 chat messages + 3 ingestions per visitor per 24h
  • Upstash Redis counters with an automatic 24h TTL reset
  • Correct x-forwarded-for parsing for Vercel's proxy chain
  • 429 responses include resetAt timestamp for countdown UI
  • Live usage meters with amber warnings and upgrade CTA wall
lib/demo-limits.js
// lib/demo-limits.jsexport async function incrementUsage(ip, field) {  // → atomic Lua INCR in Upstash Redis (24h TTL)  // → window resets automatically on expiry  // → throw { limitReached, resetAt } if over limit  // → otherwise return { used, limit, resetAt }}
Namespace Isolation

Pinecone Namespace Isolation

Multi-tenant vector storage with zero cross-contamination.

Every ingestion and retrieval operation is scoped to a Pinecone namespace. In the demo, each visitor session gets its own namespace. In production, swap it for a userId or orgId — each tenant's documents stay completely isolated within a single Pinecone index, with no schema migration or provisioning step.

The namespace flows as a single string through the entire pipeline: ingest API → vector store → chat retrieval. One index, unlimited tenants, zero extra cost.

  • One Pinecone index, unlimited namespaces — no added cost
  • Namespaces auto-created on first document upsert
  • Zero cross-contamination between tenants by design
  • Namespace flows through ingest → store → retrieval uniformly
  • Swap the demo session id for a userId/orgId for instant multi-tenancy
lib/vector-store.js
// lib/vector-store.js// upsertVectors(vectors, namespace)// → index.namespace(namespace).upsert(vectors) // querySimilar(embedding, topK, namespace)// → index.namespace(namespace).query(...)// → each tenant's vectors are fully isolated

See it working on your own documents

The live demo runs the real pipeline — upload a PDF or paste a URL and ask a question.

Pay once · MIT license · Lifetime updates