How vinayak258/ncert-doubt-solver works
1. What this repo is
- This is a split RAG system for NCERT textbook Q&A with three main runtime concerns: document ingestion/indexing, answer generation, and a student-facing UI.
- The architecture is intentionally service-oriented: frontend, backend RAG service, and offline data-prep pipelines are separated.
2. Primary request path
- A user asks a question in the Next.js frontend.
- The frontend sends the query over HTTP to the FastAPI backend.
- The backend retrieves relevant textbook chunks from FAISS and then calls Google Gemini to generate the final answer grounded in that retrieved context.
3. Frontend boundary
- The production UI lives in frontend/ and uses Next.js 14 App Router, React, and Tailwind.
- Its job is presentation and API orchestration only; it does not contain retrieval or generation logic.
- The local Python ui/ directory appears to be an auxiliary UI entry point, but the main documented user-facing app is the Next.js frontend.
4. Backend API boundary
- The API layer is in api/ with main.py, routes/query.py, and schemas.py.
- This layer defines request/response contracts and exposes the query endpoint(s) consumed by the frontend.
- It acts as the HTTP boundary around the RAG pipeline rather than embedding business logic itself.
5. RAG core
- The reusable RAG implementation is in rag/: pipeline.py, generator.py, and llm_config.py.
- This is where retrieval results are turned into prompts and passed to the LLM.
- The prompt templates live under prompts/, which means prompt formatting is treated as a first-class, versioned part of the architecture.
6. Retrieval subsystem
- Semantic search uses Sentence-Transformers embeddings and FAISS vector storage.
- The vector index and metadata are persisted as local artifacts, not in an external database.
- vector_store/ contains the index/retriever abstraction used by the RAG pipeline.
7. Ingestion and indexing pipeline
- The offline pipeline is in ingestion/, with PDF-to-text conversion, OCR, cleaning, and chunking.
- embeddings/ builds embeddings and constructs the FAISS index from the cleaned chunks.
- This is a build-time data pipeline: raw PDFs → cleaned text/chunks → embeddings → FAISS index + metadata.
8. Data artifacts and persistence
- The canonical input corpus is stored under rag_service/data/raw_books/ as NCERT PDFs.
- Preprocessed chunks are stored in rag_service/data/cleaned_text/chunks.json.
- The retrieval store is persisted in rag_service/data/vector_store/faiss.index and metadata.pkl.
- There is no separate relational or document database in the architecture.
9. Standalone deployable backend package
- rag_service/ is a self-contained deployable version of the backend, with its own app.py, requirements.txt, Dockerfile, and an internal src/ tree mirroring the root-level RAG modules.
- This is an important packaging boundary: the repo keeps shared logic at the root, but the production/deployment image uses the rag_service layout.
- The README’s hosted backend and Render deployment refer to this packaged service.
10. Operational flow and tooling
- scripts/run_ingestion.py, scripts/run_rag.py, and scripts/run_retrieval.py orchestrate offline ingestion, manual RAG runs, and retrieval evaluation.
- evaluation/retrieval_test.py is for checking retrieval quality rather than end-user serving.
- Docker Compose supports local multi-service startup, while k8s/ contains Kubernetes manifests for the same service split.
- GitHub Actions CI is present in .github/workflows/ci.yml, and deployment metadata exists in render.yaml.
11. External dependencies that shape the architecture
- The main external service is Google Gemini, used only at generation time.
- The backend is tuned for constrained memory, so model loading is described as lazy-loaded and the embedding model is intentionally lightweight.
- This explains why the system prefers local artifacts plus on-demand inference rather than heavier always-on infrastructure.
12. How to draw the architecture
- Put the Next.js frontend at the edge.
- Behind it, place a FastAPI query service wrapping the RAG pipeline.
- Connect that pipeline to two internal data subsystems: the FAISS vector store for retrieval and Gemini for generation.
- Add a separate offline lane from NCERT PDFs → ingestion/cleaning/chunking → embeddings/index build → persisted FAISS artifacts.
- Show rag_service/ as the production packaging of the backend and data artifacts, not as a separate business capability.
Main entry points: pipeline.py RAG pipeline · query.py Query route · generator.py Generator · text_cleaner.py Clean chunks
Components 20
Frontend
Student-facing Next.js UI layer.
- Next.js app · Production student-facing interface for asking questions and showing answers.
frontend/src/app - UI shell · App Router shell and shared presentation structure.
frontend/src/app/layout.tsx - Chat page · Main interactive page that drives question submission.
frontend/src/app/page.tsx
Backend
HTTP API and RAG serving layer.
- API app · Backend application entrypoint for serving the query API.
api/main.py - Query route · Endpoint handling question requests from the frontend.
api/routes/query.py - Contracts · Request and response shapes for the API boundary.
api/schemas.py - RAG pipeline · Coordinates retrieval, prompt assembly, and answer generation.
rag/pipeline.py - Generator · Builds prompts and turns retrieved context into final answers.
rag/generator.py - LLM config · Google Gemini and runtime settings for answer generation.
rag/llm_config.py - Retriever · Semantic search over indexed textbook chunks.
vector_store/retriever.py - Prompts · System, user, and query templates used by the RAG pipeline.
prompts/rag_query_template.txt
Offline pipeline
Ingestion, embedding, and retrieval build steps.
- PDF extract · Converts NCERT PDFs into text and OCR output.
ingestion/pdf_to_text.py - Clean chunks · Normalizes and chunks extracted textbook text.
ingestion/text_cleaner.py - Index build · Creates embeddings and writes the FAISS artifacts.
embeddings/build_index.py
Packaging
Deployable backend bundle and runtime artifacts.
- FAISS store · Local FAISS index and metadata used for retrieval.
rag_service/data/vector_store/faiss.index - NCERT PDFs · Canonical textbook source material for the RAG system.
rag_service/data/raw_books - Chunk corpus · Persisted cleaned text chunks used to build and inspect the index.
rag_service/data/cleaned_text/chunks.json - Backend bundle · Standalone production packaging of the backend, RAG modules, and data artifacts.
rag_service
Operations
Scripts and deployment automation.
- Run scripts · Orchestrates ingestion, manual RAG runs, and retrieval checks.
scripts/run_rag.py - Deploy config · Docker Compose, Kubernetes, Render, and CI configuration for the split service setup.
docker-compose.yml
Connections 21
- Chat page → Query route: HTTP query · User questions are sent from the frontend to the backend API.
- UI shell → Next.js app: composes · Shared UI shell supports the app routes.
- API app → Query route: mounts · FastAPI application exposes the query route.
- Query route → Contracts: validates · API payloads are checked against request and response schemas.
- Query route → RAG pipeline: invokes · Route hands the request to the RAG orchestrator.
- RAG pipeline → Retriever: retrieves · Pipeline fetches relevant textbook chunks for grounding.
- RAG pipeline → Generator: generates · Pipeline passes retrieved context into answer generation.
- Generator → LLM config: loads · Generator uses model configuration for Gemini inference.
- Generator → Prompts: formats · Prompt assets shape the final LLM prompt.
- Retriever → FAISS store: reads · Retriever queries the persisted FAISS artifacts.
- PDF extract → Clean chunks: feeds · Extracted text flows into cleaning and chunking.
- Clean chunks → Chunk corpus: writes · Processed chunks are persisted for index construction and inspection.
- Chunk corpus → Index build: input · Chunk corpus is embedded and indexed offline.
- NCERT PDFs → PDF extract: source · NCERT PDFs are the raw ingestion input.
- Index build → FAISS store: builds · Embedding pipeline produces the FAISS index and metadata.
- Backend bundle → RAG pipeline: packages · Deployable backend bundle contains the shared RAG code.
- Backend bundle → FAISS store: ships · Production package includes persisted retrieval artifacts.
- Run scripts → Clean chunks: runs · Scripts orchestrate offline preprocessing and indexing workflows.
- Run scripts → RAG pipeline: tests · Scripts support manual RAG execution and retrieval checks.
- Deploy config → API app: deploys · Operational configs deploy the backend service.
- Deploy config → Next.js app: deploys · Operational configs also deploy the frontend.