Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DocRAG — Document Question-Answering with AI

DocRAG is a full-stack web application that lets you upload PDF or plain-text documents and ask natural-language questions about their content. It uses a Retrieval-Augmented Generation (RAG) pipeline powered by Google Gemini to find relevant passages and generate accurate, context-grounded answers.


Purpose

The goal of DocRAG is to give users a simple, private way to "chat" with their own documents. Instead of manually searching through long files, you upload them once and ask questions in plain English. The AI answers based only on what is in your documents — it will explicitly say when it cannot find relevant information rather than hallucinating.


Features

  • Upload multiple PDF and TXT files at once
  • Automatic text extraction and chunking
  • Semantic similarity search over your documents
  • AI-generated answers grounded exclusively in your uploaded content
  • Session-based isolation — each browser session has its own document store
  • No cloud storage — documents live in server memory for the duration of the session

Tech Stack

Layer Technology
Framework SvelteKit (Svelte 5)
Styling Tailwind CSS v4
AI / LLM Google Gemini 2.5 Pro (gemini-2.5-pro)
Embeddings Google Gemini Embedding (gemini-embedding-001)
RAG orchestration LangGraph
LLM abstractions LangChain.js
PDF parsing pdf-parse
Build tool Vite

How It Works

1. Document Upload (POST /api/upload)

  1. The browser sends one or more files as multipart/form-data.
  2. The server assigns a UUID session ID and stores it in an HTTP-only cookie (24-hour lifetime).
  3. Each file is read into a buffer:
    • PDF files are parsed with pdf-parse to extract plain text.
    • TXT files are decoded as UTF-8 directly.
  4. The text is split into overlapping chunks using RecursiveCharacterTextSplitter (chunk size 1 000 characters, overlap 200 characters).
  5. Every chunk is embedded with the Gemini Embedding model and stored in the session's in-memory vector store.
  6. The response returns each file name and how many chunks were produced.

2. In-Memory Vector Store (src/lib/server/session.ts)

A lightweight SimpleVectorStore class holds (embedding, document) pairs in a plain array. When a query arrives, it embeds the query string and ranks every stored chunk by cosine similarity, returning the top-k results. There is no external database — the store lives in Node.js module memory and is keyed by session ID.

3. RAG Query Pipeline (POST /api/chat)

  1. The browser sends the user's question as JSON.
  2. The server looks up the session cookie and verifies a document store exists for it.
  3. runRAG is called, which builds a two-node LangGraph state machine:
START → retrieve → generate → END
  • retrieve — embeds the question and fetches the top-5 most relevant document chunks from the vector store.
  • generate — passes those chunks as context to Gemini 2.5 Pro with a system prompt that instructs the model to answer only from the provided context.
  1. The final answer string is returned to the browser.

4. Frontend (src/routes/+page.svelte)

The single-page UI has two panels:

  • Documents panel (left sidebar) — a drag-and-drop / click file picker that shows selected files with their sizes, a list of already-loaded files with chunk counts, and an upload button.
  • Chat panel (main area) — a scrollable message thread plus a text input. Pressing Enter (or clicking Send) posts the question. The assistant's reply is appended when the request resolves.

Project Structure

src/
├── app.css                  # Global styles and CSS variables
├── app.html                 # HTML shell
├── lib/
│   └── server/
│       ├── rag.ts           # LangGraph RAG pipeline
│       └── session.ts       # In-memory vector store + session management
└── routes/
    ├── +layout.svelte       # Root layout
    ├── +page.svelte         # Main UI (upload + chat)
    └── api/
        ├── chat/
        │   └── +server.ts   # POST /api/chat
        └── upload/
            └── +server.ts   # POST /api/upload

Getting Started

Prerequisites

Setup

# Install dependencies
npm install

# Create an environment file
echo "GOOGLE_API_KEY=your_api_key_here" > .env

Development

npm run dev

Open http://localhost:5173 in your browser.

Production Build

npm run build
npm run preview

Environment Variables

Variable Description
GOOGLE_API_KEY Google Generative AI API key used for both embeddings and chat generation

Limitations

  • In-memory only — the vector store is reset on every server restart. Documents must be re-uploaded after a restart.
  • Session expiry — the session cookie expires after 24 hours.
  • No persistence — there is no database; all document data is held in RAM.
  • Single server — the in-memory store is not shared across multiple server instances.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages