FocusFlow Assistant
fix: pre-download embedding model during Docker build to avoid DNS failures on HF Spaces
3c23e28 | # FocusFlow Architecture - Explained | |
| **Imagine this:** You have a pile of PDF textbooks. You want to: | |
| 1. Upload them to an app | |
| 2. Have the app create a study plan automatically | |
| 3. Ask questions and get answers with exact page citations | |
| 4. Take auto-generated quizzes | |
| 5. Track your progress | |
| **That's FocusFlow!** | |
| --- | |
| ## π― The Big Picture (What We're Building) | |
| ``` | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β WHAT THE USER SEES β | |
| β β | |
| β π± Web Interface (Streamlit) β | |
| β ββ Upload PDFs β | |
| β ββ Generate study plan β | |
| β ββ Ask questions β | |
| β ββ Take quizzes β | |
| β ββ View progress β | |
| β β | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| βοΈ | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β WHAT HAPPENS BEHIND β | |
| β β | |
| β π€ AI Brain (LLM) - Understands and generates text β | |
| β π Search Engine (ChromaDB) - Finds relevant content β | |
| β πΎ Database (Supabase/SQLite) - Saves your progress β | |
| β π API Server (FastAPI) - Connects everything β | |
| β β | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ``` | |
| --- | |
| ## π Chapter 1: The Technology Stack (What We Use & Why) | |
| ### **1.1 Frontend (What You See)** | |
| #### **Streamlit** π¨ | |
| - **What it is:** A Python library that turns scripts into web apps | |
| - **Why we use it:** | |
| - No HTML/CSS/JavaScript knowledge needed | |
| - Write everything in Python | |
| - Built-in widgets (buttons, sliders, file uploaders) | |
| - Perfect for AI/ML apps | |
| - **Alternative we could use:** React.js | |
| - **Why we didn't:** Too complicated - requires learning JavaScript, webpack, npm, etc. | |
| - **Streamlit advantage:** 5 lines of Python = a full interface | |
| **Example:** | |
| ```python | |
| # Streamlit - Easy! | |
| import streamlit as st | |
| uploaded_file = st.file_uploader("Upload PDF") | |
| if st.button("Generate Plan"): | |
| st.write("Plan created!") | |
| # React - Complex! (Need JavaScript, JSX, state management) | |
| // Would need 50+ lines of code | |
| ``` | |
| --- | |
| ### **1.2 Backend (The Brain)** | |
| #### **FastAPI** π | |
| - **What it is:** A modern Python web framework for building APIs | |
| - **Why we use it:** | |
| - Super fast (async support) | |
| - Auto-generates API documentation | |
| - Type checking built-in | |
| - Easy to learn | |
| - **Alternative we could use:** Flask | |
| - **Why FastAPI is better:** Automatic validation, async support, faster | |
| **What's an API?** Think of it like a waiter in a restaurant: | |
| - Frontend (you) asks for something β API (waiter) β Backend (kitchen) makes it β API brings it back | |
| **Example:** | |
| ```python | |
| @app.post("/upload") # This is an "endpoint" - a URL the frontend can call | |
| def upload_pdf(file: UploadFile): | |
| # Process PDF | |
| return {"status": "success"} | |
| ``` | |
| When frontend calls `http://localhost:8000/upload`, this function runs! | |
| --- | |
| ### **1.3 The AI Brain (LLM - Large Language Model)** | |
| We use **TWO different AI models** depending on where you run the app: | |
| #### **For Local (Your Computer): Ollama + llama3.2** | |
| - **What it is:** Ollama runs AI models on your computer (offline) | |
| - **Model used:** llama3.2:1b (1 billion parameters - "small" but smart) | |
| - **Why we use it:** | |
| - β Completely private (no data sent to internet) | |
| - β Free forever | |
| - β Works offline | |
| - β Requires powerful computer (8GB+ RAM) | |
| #### **For Cloud (HuggingFace Spaces): HuggingFace API + Llama-3-8B** | |
| - **What it is:** HuggingFace runs the AI on their servers | |
| - **Model used:** Meta-Llama-3-8B-Instruct (8 billion parameters - smarter) | |
| - **Why we use it:** | |
| - β No setup needed | |
| - β Faster (runs on powerful cloud servers) | |
| - β Bigger, smarter model | |
| - β Requires internet | |
| - β Data goes to cloud | |
| **What does the AI do?** | |
| 1. **Generate study plans** from your PDFs | |
| 2. **Answer questions** based on PDF content | |
| 3. **Create quizzes** with multiple-choice questions | |
| **Example conversation with AI:** | |
| ``` | |
| User PDF: "Photosynthesis converts light into energy..." | |
| User Question: "What is photosynthesis?" | |
| AI Answer: "Photosynthesis is the process where plants convert | |
| light into chemical energy. [Source: biology.pdf, page 42]" | |
| ``` | |
| --- | |
| ### **1.4 The Memory System (Databases)** | |
| We use **MULTIPLE** databases for different types of data: | |
| #### **ChromaDB** π (Vector Database) | |
| - **What it stores:** PDF text chunks + their "meaning" (embeddings) | |
| - **Why we need it:** For semantic search | |
| **What's semantic search?** | |
| - **Keyword search:** Looks for exact words | |
| - Search "car" β finds "car" but NOT "vehicle" or "automobile" | |
| - **Semantic search:** Understands meaning | |
| - Search "car" β finds "car", "vehicle", "automobile", "sedan" | |
| **How it works:** | |
| ``` | |
| 1. Upload PDF: "The mitochondria is the powerhouse of the cell" | |
| β | |
| 2. Convert to "embedding" (a bunch of numbers representing meaning) | |
| [0.234, -0.456, 0.123, 0.789, ...] (384 numbers!) | |
| β | |
| 3. Store in ChromaDB with original text | |
| β | |
| 4. User asks: "What produces energy in cells?" | |
| β | |
| 5. Convert question to embedding | |
| [0.245, -0.401, 0.134, 0.756, ...] | |
| β | |
| 6. ChromaDB finds chunks with SIMILAR numbers (similar meaning) | |
| β | |
| 7. Returns: "The mitochondria is the powerhouse..." β | |
| ``` | |
| **Why ChromaDB instead of regular database?** | |
| - Regular database: Can only search exact text | |
| - ChromaDB: Searches by **meaning** (perfect for AI!) | |
| --- | |
| #### **Supabase PostgreSQL** πΎ (Main Database - Cloud) | |
| - **What it stores:** Your study plans, quiz scores, progress | |
| - **Why we use it:** | |
| - β Free cloud database (no setup) | |
| - β Data persists forever | |
| - β Multi-user support | |
| - β Real-time updates | |
| **Alternative:** MongoDB, MySQL, Firebase | |
| - **Why Supabase:** Easier than AWS, more features than SQLite, free tier generous | |
| **Example data structure:** | |
| ```json | |
| { | |
| "student_id": "student_abc123", | |
| "profile_data": { | |
| "study_plan": { | |
| "topics": [ | |
| {"day": 1, "title": "Intro to Python", "status": "completed"}, | |
| {"day": 2, "title": "Functions", "status": "unlocked"} | |
| ] | |
| }, | |
| "quiz_history": [ | |
| {"topic": "Intro to Python", "score": 8, "total": 10} | |
| ], | |
| "mastery_tracker": { | |
| "Python": 80.0, | |
| "Math": 65.0 | |
| } | |
| } | |
| } | |
| ``` | |
| --- | |
| #### **SQLite** π (Local Database) | |
| - **What it stores:** Sources (uploaded PDFs), schedules | |
| - **Why we use it:** | |
| - β No setup (just a file) | |
| - β Built into Python | |
| - β Perfect for small data | |
| **Alternative:** PostgreSQL, MySQL | |
| - **Why SQLite:** Simpler for local usage, zero configuration | |
| --- | |
| ### **1.5 The Connector (LangChain)** | |
| #### **LangChain** π | |
| - **What it is:** A toolkit for building AI apps | |
| - **Why we use it:** | |
| - Connects AI models with data sources | |
| - Built-in RAG (Retrieval-Augmented Generation) patterns | |
| - Handles chunking, embeddings, prompts | |
| **Without LangChain (hard):** | |
| ```python | |
| # You'd have to write 200+ lines: | |
| 1. Load PDF manually | |
| 2. Split into chunks manually | |
| 3. Generate embeddings manually | |
| 4. Store in vector DB manually | |
| 5. Query and rank results manually | |
| 6. Format prompt manually | |
| 7. Call LLM manually | |
| 8. Parse response manually | |
| ``` | |
| **With LangChain (easy):** | |
| ```python | |
| from langchain.document_loaders import PyPDFLoader | |
| from langchain.vectorstores import Chroma | |
| from langchain.chains import RetrievalQA | |
| # Just 5 lines! | |
| loader = PyPDFLoader("textbook.pdf") | |
| docs = loader.load_and_split() | |
| vectorstore = Chroma.from_documents(docs, embeddings) | |
| qa_chain = RetrievalQA.from_chain_type(llm, vectorstore) | |
| answer = qa_chain.run("What is photosynthesis?") | |
| ``` | |
| --- | |
| ## ποΈ Chapter 2: System Architecture (How It All Connects) | |
| ### **2.1 The Full Stack** | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β USER'S BROWSER β | |
| β β | |
| β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β Streamlit Frontend (Port 8501) β β | |
| β β - Material Design UI β β | |
| β β - Calendar widget β β | |
| β β - Chat interface β β | |
| β β - Quiz display β β | |
| β ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β | |
| β β HTTP Requests (API calls) β | |
| βββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββ | |
| β | |
| β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β FastAPI Backend (Port 8000) β | |
| β β | |
| β βββββββββββββββββββββ ββββββββββββββββββββββββββββββββ β | |
| β β API Endpoints β β Student Profile Manager β β | |
| β β /upload β β - load_profile() β β | |
| β β /query β β - save_profile() β β | |
| β β /generate_plan β β - update_progress() β β | |
| β β /generate_quiz β ββββββββββββββββββββββββββββββββ β | |
| β βββββββββββββββββββββ β | |
| β β | |
| β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β RAG Engine (rag_engine.py) β β | |
| β β - ingest_document() - Process PDFs β β | |
| β β - query_knowledge_base() - Answer questions β β | |
| β β - generate_lesson() - Create lessons β β | |
| β β - generate_quiz() - Make quizzes β β | |
| β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β | |
| βββββββ¬βββββββββββββββββ¬βββββββββββββββββ¬ββββββββββββββββββββββ | |
| β β β | |
| β β β | |
| ββββββββββββ βββββββββββββββ ββββββββββββββββββ | |
| β ChromaDB β β LLM (AI) β β Supabase β | |
| β β β β β PostgreSQL β | |
| β Store β β Ollama or β β β | |
| β PDF β β HuggingFace β β Store study β | |
| β chunks β β β β plans/progress β | |
| β β β Generate β β β | |
| β Search β β answers β β Multi-user β | |
| β similar β β β β support β | |
| β content β β β β β | |
| ββββββββββββ βββββββββββββββ ββββββββββββββββββ | |
| ``` | |
| --- | |
| ### **2.2 Data Flow (What Happens When You Do Something)** | |
| #### **π Flow 1: Uploading a PDF** | |
| ``` | |
| 1. USER: Clicks "Upload PDF" button in Streamlit | |
| β | |
| 2. FRONTEND: File sent to FastAPI backend | |
| POST http://localhost:8000/upload | |
| β | |
| 3. BACKEND: Receives PDF file | |
| - Saves temporarily to /tmp/ | |
| β | |
| 4. RAG ENGINE: Processes PDF | |
| - PyPDFLoader extracts text from PDF | |
| - RecursiveCharacterTextSplitter splits into chunks | |
| (1000 characters each, 200 overlap) | |
| Example: | |
| PDF: "Chapter 1: Python is a programming language..." | |
| (5000 characters) | |
| β | |
| Chunks: | |
| 1. "Chapter 1: Python is a programming..." | |
| 2. "language. Python was created by..." | |
| 3. "by Guido van Rossum. It is used..." | |
| 4. "used for web development, AI..." | |
| 5. "AI, data science and more..." | |
| β | |
| 5. EMBEDDINGS: Convert each chunk to numbers | |
| Chunk 1 β [0.234, -0.456, 0.789, ...] (384 numbers) | |
| Chunk 2 β [0.123, -0.234, 0.567, ...] | |
| ... | |
| β | |
| 6. CHROMADB: Store chunks + embeddings | |
| { | |
| text: "Chapter 1: Python is...", | |
| embedding: [0.234, -0.456, ...], | |
| metadata: {source: "python.pdf", page: 1} | |
| } | |
| β | |
| 7. SQLITE: Save source info | |
| INSERT INTO sources (filename, type, is_active) | |
| VALUES ('python.pdf', 'pdf', true) | |
| β | |
| 8. RESPONSE: Tell frontend "Success!" | |
| β | |
| 9. FRONTEND: Shows PDF in "Sources" list β | |
| ``` | |
| --- | |
| #### **π Flow 2: Asking a Question** | |
| ``` | |
| 1. USER: Types "What is Python?" in chat | |
| β | |
| 2. FRONTEND: Sends to backend | |
| POST /query {"question": "What is Python?"} | |
| β | |
| 3. BACKEND: RAG Engine processes | |
| β | |
| 4. EMBEDDINGS: Convert question to numbers | |
| "What is Python?" β [0.245, -0.401, 0.756, ...] | |
| β | |
| 5. CHROMADB: Similarity search | |
| - Compares question embedding with all stored embeddings | |
| - Finds top 4 most similar chunks | |
| Math (simplified): | |
| Question: [0.245, -0.401, 0.756] | |
| Chunk 1: [0.234, -0.456, 0.789] β Similarity: 0.95 β | |
| Chunk 2: [0.123, -0.234, 0.567] β Similarity: 0.87 | |
| Chunk 3: [0.891, -0.123, 0.234] β Similarity: 0.45 | |
| ... | |
| Returns top 4: Chunk 1, 2, 8, 15 | |
| β | |
| 6. CONTEXT: Build context from chunks | |
| Context = """ | |
| Chunk 1: Python is a programming language... | |
| Chunk 2: Python was created by Guido van Rossum... | |
| Chunk 8: Python is used for web development... | |
| Chunk 15: Python syntax is simple and readable... | |
| """ | |
| β | |
| 7. PROMPT: Create prompt for AI | |
| """ | |
| Context from documents: | |
| {context} | |
| Question: What is Python? | |
| Answer based on the context above. | |
| Include citations. | |
| """ | |
| β | |
| 8. LLM: Generate answer | |
| Ollama/HuggingFace processes prompt | |
| β | |
| 9. RESPONSE: AI returns answer | |
| "Python is a programming language created by Guido | |
| van Rossum. It's used for web development, AI, and | |
| data science. Python syntax is simple and readable. | |
| [Source: python.pdf, page 1]" | |
| β | |
| 10. FRONTEND: Display answer with citations β | |
| ``` | |
| --- | |
| #### **π Flow 3: Generating a Study Plan** | |
| ``` | |
| 1. USER: Types "Make a 5-day plan" in calendar | |
| β | |
| 2. FRONTEND: Sends request | |
| POST /generate_plan {"request_text": "Make a 5-day plan"} | |
| β | |
| 3. BACKEND: RAG Engine works | |
| β | |
| 4. CHROMADB: Get ALL document chunks | |
| - Queries vector DB for broad context | |
| - Gets 50+ chunks | |
| β | |
| 5. SUMMARIZE: Build content summary | |
| Content = "Documents contain: Python basics, functions, | |
| loops, data structures, OOP..." | |
| β | |
| 6. PROMPT: Ask AI to create plan | |
| """ | |
| Content available: {content summary} | |
| Create a 5-day study plan in JSON format: | |
| [ | |
| {"day": 1, "topic": "...", "subject": "..."}, | |
| {"day": 2, "topic": "...", "subject": "..."}, | |
| ... | |
| ] | |
| """ | |
| β | |
| 7. LLM: Generate plan | |
| Returns JSON: | |
| [ | |
| {"day": 1, "topic": "Python Basics", "subject": "Python"}, | |
| {"day": 2, "topic": "Functions", "subject": "Python"}, | |
| {"day": 3, "topic": "Loops", "subject": "Python"}, | |
| {"day": 4, "topic": "Data Structures", "subject": "Python"}, | |
| {"day": 5, "topic": "OOP Concepts", "subject": "Python"} | |
| ] | |
| β | |
| 8. VALIDATE: Check and fix plan | |
| - Ensure all days present | |
| - Set day 1 topics as "unlocked" | |
| - Other days as "locked" | |
| - Add IDs, status fields | |
| β | |
| 9. SAVE: Store in database | |
| Supabase (cloud) or JSON file (local) | |
| profile_data.study_plan = { | |
| plan_id: "plan_20260110_123456", | |
| topics: [...] | |
| } | |
| β | |
| 10. FRONTEND: Update calendar + show plan β | |
| ``` | |
| --- | |
| #### **π Flow 4: Taking a Quiz** | |
| ``` | |
| 1. USER: Clicks "Start Learning" β Views lesson β Clicks "Take Quiz" | |
| β | |
| 2. FRONTEND: Request quiz | |
| POST /generate_quiz {"topic": "Python Basics"} | |
| β | |
| 3. CHROMADB: Search for topic content | |
| - Finds 6 most relevant chunks about "Python Basics" | |
| β | |
| 4. PROMPT: Ask AI for quiz questions | |
| """ | |
| Context: {6 chunks about Python Basics} | |
| Create 3 multiple-choice questions in JSON: | |
| [ | |
| { | |
| "question": "What is Python?", | |
| "options": ["A) A snake", "B) A language", "C) A tool", "D) A framework"], | |
| "correct": "B" | |
| }, | |
| ... | |
| ] | |
| """ | |
| β | |
| 5. LLM: Generate quiz | |
| Returns 3 questions with answers | |
| β | |
| 6. FRONTEND: Display quiz | |
| - Shows questions with radio buttons | |
| - User selects answers | |
| - Clicks Submit | |
| β | |
| 7. SCORE: Calculate results | |
| - Compares user answers with correct answers | |
| - Score = 2/3 = 66.7% | |
| β | |
| 8. SAVE: Record quiz result | |
| POST /student/quiz_complete | |
| Saves to profile: | |
| quiz_history: [ | |
| { | |
| topic: "Python Basics", | |
| score: 2, | |
| total: 3, | |
| percentage: 66.7, | |
| timestamp: "2026-01-10T20:30:00" | |
| } | |
| ] | |
| β | |
| 9. UPDATE MASTERY: Adjust skill level | |
| Old mastery: 70.0 | |
| Quiz score: 66.7 | |
| New mastery = 0.7 * 70.0 + 0.3 * 66.7 = 69.0 | |
| (Exponential weighted average) | |
| β | |
| 10. UNLOCK: Check if should unlock next topic | |
| If score β₯ 70% β Mark topic complete + unlock next | |
| If score < 70% β Keep same topic unlocked | |
| β | |
| 11. FRONTEND: Show results + update progress β | |
| ``` | |
| --- | |
| ## π¨ Chapter 3: Why These Specific Choices? | |
| ### **3.1 Why Streamlit + FastAPI (Not MERN/Django/etc.)?** | |
| **Alternatives:** | |
| - **MERN Stack** (MongoDB, Express, React, Node.js) | |
| - **Django** (Python full-stack framework) | |
| - **Flask** + React | |
| **Why our stack is better for AI apps:** | |
| | Feature | Our Stack | MERN | Django | | |
| |---------|-----------|------|--------| | |
| | **Language** | 100% Python | JavaScript + Python hassle | Python | | |
| | **AI/ML Support** | β Native | β Need Python backend anyway | β OK | | |
| | **Speed to build UI** | β Very fast | β Slow (component hell) | β οΈ Medium | | |
| | **Learning curve** | β Easy | β Hard (JS, React, etc.) | β οΈ Medium | | |
| | **AI integrations** | β Perfect | β Limited | β οΈ OK | | |
| **Real example:** The entire Streamlit UI is ~1500 lines. Same in React would be 5000+ lines! | |
| --- | |
| ### **3.2 Why ChromaDB (Not PostgreSQL for everything)?** | |
| **Question:** Why not just store PDF text in regular database? | |
| **Answer:** Semantic search is IMPOSSIBLE in regular databases! | |
| **Example:** | |
| **Regular Database (PostgreSQL with LIKE):** | |
| ```sql | |
| -- User asks: "How do cells produce energy?" | |
| SELECT * FROM documents | |
| WHERE text LIKE '%produce energy%'; | |
| -- β Misses: "mitochondria", "ATP synthesis", "cellular respiration" | |
| -- Only finds exact phrase "produce energy" | |
| ``` | |
| **Vector Database (ChromaDB):** | |
| ```python | |
| # User asks: "How do cells produce energy?" | |
| results = chroma.similarity_search("How do cells produce energy?", k=4) | |
| # β Finds: | |
| # - "The mitochondria is the powerhouse..." | |
| # - "ATP is synthesized through..." | |
| # - "Cellular respiration converts glucose..." | |
| # - "Energy production in eukaryotic cells..." | |
| # All related by MEANING, not exact words! | |
| ``` | |
| **Why this matters:** | |
| - Students don't ask questions using exact textbook phrases | |
| - Need AI to understand context and meaning | |
| - Vector search makes RAG possible | |
| --- | |
| ### **3.3 Why Supabase (Not AWS/Firebase/Own server)?** | |
| **Alternatives:** | |
| - **AWS RDS** - Complex, expensive | |
| - **Firebase** - Good but limited free tier | |
| - **Own server** - Too much work | |
| **Why Supabase:** | |
| ``` | |
| AWS RDS: | |
| - β Complex setup (VPC, security groups, IAM) | |
| - β Expensive ($30+/month minimum) | |
| - β Overkill for our need | |
| Firebase: | |
| - β οΈ Good but NoSQL (we want SQL) | |
| - β οΈ Expensive for storage | |
| - β Easy to use | |
| Supabase: | |
| - β PostgreSQL (powerful SQL) | |
| - β 500MB free forever | |
| - β Built-in authentication (future use) | |
| - β Real-time subscriptions | |
| - β 2 clicks to set up | |
| ``` | |
| --- | |
| ### **3.4 Why Two LLM Modes (Ollama + HuggingFace)?** | |
| **The Problem:** | |
| - **Cloud-only apps** β No privacy (data goes to OpenAI, Google, etc.) | |
| - **Local-only apps** β Hard to demo (need Ollama installed) | |
| **Our Solution:** Support both! | |
| ```python | |
| # backend/config.py | |
| def get_llm(): | |
| provider = os.getenv("LLM_PROVIDER") # "ollama" or "huggingface" | |
| if provider == "ollama": | |
| return Ollama(model="llama3.2:1b") # Local | |
| else: | |
| return HuggingFaceEndpoint(model="meta-llama/Llama-3-8B") # Cloud | |
| ``` | |
| **Benefits:** | |
| - **For users:** Choose privacy (local) vs convenience (cloud) | |
| - **For demos:** Just share HuggingFace link | |
| - **For students:** Learn locally without API costs | |
| --- | |
| ## π§ Chapter 4: How Components Talk (The Communication Layer) | |
| ### **4.1 Frontend β Backend Communication** | |
| **Technology:** HTTP REST API | |
| **What's REST?** | |
| - **RE**presentational **S**tate **T**ransfer | |
| - Fancy way of saying: "Send data using URLs" | |
| **Example:** | |
| ``` | |
| Frontend wants to upload PDF: | |
| 1. Package file as HTTP POST request | |
| 2. Send to: http://localhost:8000/upload | |
| 3. Backend receives, processes, returns JSON | |
| 4. Frontend shows success message | |
| ``` | |
| **Why not WebSockets?** | |
| - REST is simpler | |
| - Most operations don't need real-time | |
| - WebSockets = overkill for this app | |
| --- | |
| ### **4.2 Backend β LLM Communication** | |
| **For Ollama (Local):** | |
| ```python | |
| # Direct connection to local server | |
| from langchain.llms import Ollama | |
| llm = Ollama(base_url="http://localhost:11434") | |
| response = llm.invoke("What is Python?") | |
| ``` | |
| **For HuggingFace (Cloud):** | |
| ```python | |
| # API call to HF servers | |
| from langchain_huggingface import ChatHuggingFace | |
| llm = ChatHuggingFace( | |
| huggingfacehub_api_token="hf_xxx", | |
| model="meta-llama/Llama-3-8B-Instruct" | |
| ) | |
| response = llm.invoke("What is Python?") | |
| ``` | |
| **Why ChatHuggingFace wrapper?** | |
| - Llama-3 is a "chat model" (conversational) | |
| - Needs special message formatting | |
| - Wrapper handles format conversion automatically | |
| --- | |
| ### **4.3 Multi-User System (How Each User Gets Their Own Data)** | |
| **The Challenge:** On cloud (HF Spaces), multiple people use the app simultaneously. How to keep data separate? | |
| **Solution:** Session-based student IDs | |
| ``` | |
| User A opens app β Gets student_id = "student_abc123" | |
| User B opens app β Gets student_id = "student_xyz789" | |
| When User A saves plan: | |
| POST /student/save_plan | |
| Header: X-Student-Id: student_abc123 | |
| Backend: | |
| - Loads profile for "student_abc123" | |
| - Saves to Supabase with this ID | |
| When User B saves plan: | |
| POST /student/save_plan | |
| Header: X-Student-Id: student_xyz789 | |
| Backend: | |
| - Loads profile for "student_xyz789" | |
| - Completely separate data! | |
| ``` | |
| **Database structure:** | |
| ``` | |
| student_profiles table: | |
| βββββββββββββββ¬βββββββββββββββββββββββ | |
| β student_id β profile_data β | |
| βββββββββββββββΌβββββββββββββββββββββββ€ | |
| β abc123 β {study_plan: {...}} β | |
| β xyz789 β {study_plan: {...}} β | |
| β def456 β {study_plan: {...}} β | |
| βββββββββββββββ΄βββββββββββββββββββββββ | |
| Each row = one user's data! | |
| ``` | |
| --- | |
| ## π Chapter 5: Deployment (Getting It Online) | |
| ### **5.1 Local Deployment (Run on Your Computer)** | |
| **What happens:** | |
| ``` | |
| Your Computer: | |
| ββββββββββββββββββββββββββββββββββ | |
| β Terminal 1: β | |
| β $ ollama serve β β Starts AI server | |
| β Listening on :11434... β | |
| ββββββββββββββββββββββββββββββββββ | |
| ββββββββββββββββββββββββββββββββββ | |
| β Terminal 2: β | |
| β $ uvicorn backend.main:app β β Starts API server | |
| β Running on :8000... β | |
| ββββββββββββββββββββββββββββββββββ | |
| ββββββββββββββββββββββββββββββββββ | |
| β Terminal 3: β | |
| β $ streamlit run app.py β β Starts web interface | |
| β Running on :8501... β | |
| ββββββββββββββββββββββββββββββββββ | |
| Your browser: | |
| Go to http://localhost:8501 β | |
| ``` | |
| **File locations:** | |
| - PDFs chunks: `./chroma_db/` (permanent) | |
| - Study plans: `~/.focusflow/student_profile.json` (permanent) | |
| - Sources DB: `data/focusflow.db` (permanent) | |
| --- | |
| ### **5.2 Cloud Deployment (HuggingFace Spaces)** | |
| **What happens:** | |
| ``` | |
| HuggingFace Server: | |
| ββββββββββββββββββββββββββββββββββββββββββββ | |
| β Docker Container β | |
| β β | |
| β 1. Reads Dockerfile β | |
| β 2. Installs Python 3.10 β | |
| β 3. Installs all requirements.txt β | |
| β 4. Copies our code β | |
| β 5. Runs /app/start.sh: β | |
| β β | |
| β #!/bin/bash β | |
| β # Start backend β | |
| β uvicorn backend.main:app & β | |
| β β | |
| β # Wait for backend health check β | |
| β curl http://localhost:8000/health β | |
| β β | |
| β # Start frontend β | |
| β streamlit run app.py β | |
| β β | |
| β 6. Exposes port 8501 to internet β | |
| β β | |
| β URL: https://huggingface.co/spaces/ β | |
| β SivaRohith69/focusflow β | |
| ββββββββββββββββββββββββββββββββββββββββββββ | |
| ``` | |
| **Environment variables (secrets in HF Spaces settings):** | |
| ```bash | |
| LLM_PROVIDER=huggingface # Use HF API, not Ollama | |
| USE_SUPABASE=true # Use cloud DB, not local | |
| HUGGINGFACE_API_TOKEN=hf_xxx # For LLM access | |
| SUPABASE_URL=https://xxx.supabase.co | |
| SUPABASE_KEY=xxx | |
| ``` | |
| **File locations:** | |
| - PDFs chunks: `/app/chroma_db/` (β ephemeral - deleted on restart!) | |
| - Study plans: Supabase (β permanent) | |
| - Sources DB: `/app/data/focusflow.db` (β ephemeral) | |
| --- | |
| ## π§ Chapter 6: The RAG System (How AI Answers Questions) | |
| **RAG = Retrieval-Augmented Generation** | |
| **Simple explanation:** | |
| - **Without RAG:** AI only knows what it learned during training (outdated, generic) | |
| - **With RAG:** AI reads your PDFs first, then answers (accurate, specific) | |
| ### **6.1 The Three Steps** | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β STEP 1: RETRIEVAL (Find relevant info) β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| User asks: "What is mitochondria?" | |
| β | |
| Convert to embedding: [0.234, -0.567, ...] | |
| β | |
| Search ChromaDB for similar chunks | |
| β | |
| Returns: | |
| 1. "The mitochondria is the powerhouse..." (similarity: 0.95) | |
| 2. "Mitochondria have two membranes..." (similarity: 0.88) | |
| 3. "ATP synthesis occurs in mitochondria..." (similarity: 0.85) | |
| 4. "Cellular respiration in mitochondria..." (similarity: 0.82) | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β STEP 2: AUGMENTATION (Add context) β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Build prompt: | |
| """ | |
| Context from documents: | |
| 1. The mitochondria is the powerhouse... | |
| 2. Mitochondria have two membranes... | |
| 3. ATP synthesis occurs in mitochondria... | |
| 4. Cellular respiration in mitochondria... | |
| Question: What is mitochondria? | |
| Answer the question using ONLY the context above. | |
| Include citations to source. | |
| """ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β STEP 3: GENERATION (AI creates answer) β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Send prompt to LLM (Ollama or HuggingFace) | |
| β | |
| LLM generates answer: | |
| "The mitochondria is the powerhouse of the cell, | |
| responsible for ATP synthesis through cellular | |
| respiration. It has two membranes that facilitate | |
| energy production. [Source: biology.pdf, page 42]" | |
| ``` | |
| --- | |
| ### **6.2 Why RAG is Powerful** | |
| **Traditional AI (ChatGPT without RAG):** | |
| ``` | |
| You: What did the textbook say about photosynthesis? | |
| AI: I don't have access to your specific textbook. But generally, | |
| photosynthesis is... [generic answer] | |
| ``` | |
| **Our RAG System:** | |
| ``` | |
| You: What did the textbook say about photosynthesis? | |
| AI: According to your textbook (biology.pdf, page 67), | |
| "Photosynthesis converts light energy into chemical | |
| energy through the reaction: 6CO2 + 6H2O + light β | |
| C6H12O6 + 6O2. This process occurs in chloroplasts..." | |
| [Exact quote from YOUR PDF!] | |
| ``` | |
| **The magic:** RAG makes AI "read" your documents before answering! | |
| --- | |
| ## π Chapter 7: The Frontend Architecture (What You See) | |
| ### **7.1 The Three-Column Layout** | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β FocusFlow β | |
| βββββββββββββ¬βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββ€ | |
| β CONTROL β INTELLIGENT WORKSPACE β CALENDAR & PLAN β | |
| β CENTER β β β | |
| β β β β | |
| β βββββββββ β Welcome Screen / Lesson / β π Calendar Widget β | |
| β β Timer β β Chat / Quiz β β | |
| β β 25:00 β β β π Study Plan β | |
| β β START β β β - Day 1 β | |
| β βββββββββ β β - Day 2 β | |
| β β β - Day 3 β | |
| β Sources β β β | |
| β β pdf1 β β Today's Topics β | |
| β β pdf2 β β βΆ Topic 1 (Start) β | |
| β β β π Topic 2 β | |
| β + Upload β β β | |
| β β β π Analytics β | |
| βββββββββββββ΄βββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββ | |
| ^ ^ ^ | |
| | | | | |
| 150px Flexible 300px | |
| (rest of space) | |
| ``` | |
| **Why this layout?** | |
| - **Left:** Quick access to timer, sources (always visible) | |
| - **Center:** Main focus area (largest space) | |
| - **Right:** Plan overview, quick navigation | |
| **Implemented with:** | |
| ```python | |
| col1, col2, col3 = st.columns([0.15, 0.55, 0.3]) | |
| with col1: | |
| st.header("Control Center") | |
| # Timer, sources, etc. | |
| with col2: | |
| st.header("Workspace") | |
| # Lessons, chat, quiz | |
| with col3: | |
| st.header("Calendar") | |
| # Calendar, plan, analytics | |
| ``` | |
| --- | |
| ### **7.2 Material Design Principles** | |
| **What we use:** | |
| - **Elevation shadows** - Cards float above background | |
| - **Color system** - Primary (blue), accent (purple), surface | |
| - **Typography** - Inter font, hierarchical sizes | |
| - **Animations** - Smooth transitions (150ms) | |
| **Example CSS:** | |
| ```css | |
| /* Material Design Card */ | |
| .material-card { | |
| background: white; | |
| border-radius: 8px; | |
| padding: 16px; | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* Elevation-2 */ | |
| transition: box-shadow 150ms ease; | |
| } | |
| .material-card:hover { | |
| box-shadow: 0 4px 8px rgba(0,0,0,0.15); /* Elevation-3 */ | |
| } | |
| ``` | |
| **Why Material Design?** | |
| - **Professional look** - Looks like Google apps | |
| - **Proven UX patterns** - Users already know how to use it | |
| - **Accessibility** - Good color contrast, clear hierarchy | |
| --- | |
| ## π Chapter 8: Data Privacy & Security | |
| ### **8.1 What Data We Collect** | |
| **Local Mode:** | |
| - β Everything stays on your computer | |
| - β ZERO data sent to internet | |
| - Your PDFs never uploaded anywhere | |
| **Cloud Mode:** | |
| | Data Type | Stored Where | Private? | | |
| |-----------|-------------|----------| | |
| | PDF content | ChromaDB (ephemeral) | Yes - deleted on restart | | |
| | Study plans | Supabase | β οΈ In cloud database | | |
| | Quiz scores | Supabase | β οΈ In cloud database | | |
| | Your questions/answers | Not stored | Yes - processed in-memory | | |
| | PDFs themselves | Not stored | Yes - only processed, not saved | | |
| ### **8.2 How We Protect Your Data** | |
| ``` | |
| 1. Session Isolation | |
| - Each browser tab = unique student_id | |
| - User A cannot see User B's data | |
| - Database enforces separation | |
| 2. No PDF Storage | |
| - PDFs processed in-memory | |
| - Chunks stored, but not original file | |
| - Even we can't recover your original PDF | |
| 3. HTTPS | |
| - HuggingFace Spaces uses HTTPS | |
| - Data encrypted in transit | |
| 4. Environment Variables | |
| - API keys stored as secrets | |
| - Not in code (can't be leaked) | |
| 5. Local-First Option | |
| - Paranoid about privacy? Use local mode! | |
| - 100% offline, no cloud needed | |
| ``` | |
| --- | |
| ## π― Chapter 9: Unique Features (What Makes This Special) | |
| ### **9.1 Hybrid Architecture** | |
| **What it means:** Same codebase works both offline AND online | |
| **How:** | |
| ```python | |
| # Single config switch changes entire behavior | |
| if os.getenv("LLM_PROVIDER") == "ollama": | |
| # Local mode: Use Ollama | |
| llm = Ollama(model="llama3.2:1b") | |
| embeddings = OllamaEmbeddings(model="nomic-embed-text") | |
| storage = JSONFileStorage() # Save to local file | |
| else: | |
| # Cloud mode: Use HuggingFace | |
| llm = HuggingFaceEndpoint(model="Llama-3-8B") | |
| embeddings = HuggingFaceEmbeddings(model="all-MiniLM-L6-v2") | |
| storage = SupabaseStorage() # Save to cloud DB | |
| ``` | |
| **Why this is rare:** | |
| - Most apps are cloud-only (no privacy) OR local-only (hard to demo) | |
| - We get best of both worlds! | |
| --- | |
| ### **9.2 Auto Study Plan Generation** | |
| **Traditional study apps:** | |
| ``` | |
| User manually creates plan: | |
| - Day 1: Topic A | |
| - Day 2: Topic B | |
| - Day 3: Topic C | |
| (Takes 20 minutes of manual work!) | |
| ``` | |
| **FocusFlow:** | |
| ``` | |
| User: "Make a 7-day plan" | |
| AI: *reads all PDFs* | |
| AI: *creates structured plan based on content* | |
| Generated plan: | |
| - Day 1: Python Basics (from intro chapter) | |
| - Day 2: Variables & Data Types (from ch 2-3) | |
| - Day 3: Control Flow (from ch 4) | |
| ... | |
| (Done in 10 seconds!) | |
| ``` | |
| **How:** | |
| 1. ChromaDB retrieves all chunk summaries | |
| 2. LLM analyzes content | |
| 3. Creates logical progression | |
| 4. Assigns topics to days | |
| 5. Sets prerequisites (unlocking order) | |
| --- | |
| ### **9.3 Exact Source Citations** | |
| **Traditional chatbots:** | |
| ``` | |
| User: What is photosynthesis? | |
| Bot: Photosynthesis is the process where plants convert | |
| light into energy. | |
| User: Where did you get this info? | |
| Bot: Β―\_(γ)_/Β― (can't tell you) | |
| ``` | |
| **FocusFlow:** | |
| ``` | |
| User: What is photosynthesis? | |
| Bot: Photosynthesis is the process where plants convert | |
| light into energy through the reaction 6CO2 + 6H2O | |
| + light β C6H12O6 + 6O2. | |
| [Source: biology.pdf, page 67] | |
| [Source: textbook.pdf, page 142] | |
| User: *can verify by opening those exact pages!* | |
| ``` | |
| **How we do it:** | |
| - Every chunk stored with metadata | |
| - When answering, append source info | |
| - Links are clickable (future: open PDF to exact page) | |
| --- | |
| ## π οΈ Chapter 10: The Code Structure | |
| ### **10.1 File Organization** | |
| ``` | |
| focusflow/ | |
| β | |
| βββ app.py (1457 lines) | |
| β βββ Entire Streamlit frontend | |
| β - UI layout | |
| β - Calendar widget | |
| β - Chat interface | |
| β - Quiz display | |
| β - Material Design CSS | |
| β | |
| βββ backend/ | |
| β βββ main.py (335 lines) | |
| β β βββ FastAPI app | |
| β β - 15 API endpoints | |
| β β - Health check | |
| β β - Dependency injection | |
| β β | |
| β βββ rag_engine.py (492 lines) | |
| β β βββ Core RAG logic | |
| β β - ingest_document() | |
| β β - query_knowledge_base() | |
| β β - generate_lesson() | |
| β β - generate_quiz() | |
| β β | |
| β βββ student_data.py (315 lines) | |
| β β βββ Profile management | |
| β β - load_profile() | |
| β β - save_profile() | |
| β β - Supports JSON & Supabase | |
| β β | |
| β βββ config.py (94 lines) | |
| β β βββ Configuration | |
| β β - LLM provider switching | |
| β β - get_llm() | |
| β β - get_embeddings() | |
| β β | |
| β βββ supabase_storage.py (139 lines) | |
| β β βββ Supabase adapter | |
| β β - Cloud DB operations | |
| β β - Error handling | |
| β β | |
| β βββ database.py (100 lines) | |
| β βββ SQLite models | |
| β - Sources, Schedules, Mastery | |
| β | |
| βββ Dockerfile (44 lines) | |
| β βββ Container configuration | |
| β - Multi-service startup | |
| β - Health checks | |
| β | |
| βββ requirements.txt (25 packages) | |
| β βββ streamlit | |
| β βββ fastapi | |
| β βββ langchain | |
| β βββ chromadb | |
| β βββ supabase | |
| β βββ ... | |
| β | |
| βββ README.md | |
| βββ TECHNICAL_SUMMARY.json | |
| βββ ARCHITECTURE_EXPLAINED.md (this file!) | |
| ``` | |
| --- | |
| ### **10.2 Code Flow Example** | |
| **Let's trace: User uploads PDF** | |
| ``` | |
| 1. app.py (Line ~998) | |
| uploaded_file = st.file_uploader("Upload PDF") | |
| if uploaded_file: | |
| files = {"file": uploaded_file} | |
| resp = requests.post(f"{API_URL}/upload", files=files) | |
| β | |
| 2. backend/main.py (Line ~50) | |
| @app.post("/upload") | |
| def upload_file(file: UploadFile, db: Session = Depends(get_db)): | |
| temp_path = save_temp_file(file) | |
| result = ingest_document(temp_path, db) | |
| β | |
| 3. backend/rag_engine.py (Line ~40) | |
| def ingest_document(file_path, db): | |
| loader = PyPDFLoader(file_path) | |
| docs = loader.load_and_split( | |
| text_splitter=RecursiveCharacterTextSplitter( | |
| chunk_size=1000, | |
| chunk_overlap=200 | |
| ) | |
| ) | |
| β | |
| 4. backend/rag_engine.py (Line ~55) | |
| embeddings = get_embeddings() # From config.py | |
| vector_store = Chroma.from_documents( | |
| documents=docs, | |
| embedding=embeddings, | |
| persist_directory="./chroma_db" | |
| ) | |
| β | |
| 5. backend/database.py (Line ~30) | |
| new_source = Source( | |
| filename=file_path, | |
| type="pdf", | |
| is_active=True | |
| ) | |
| db.add(new_source) | |
| db.commit() | |
| β | |
| 6. backend/main.py (Line ~65) | |
| return {"status": "success", "chunks": len(docs)} | |
| β | |
| 7. app.py (Line ~1005) | |
| if resp.status_code == 200: | |
| st.success("PDF uploaded!") | |
| # Refresh sources list | |
| ``` | |
| **Every feature follows similar flow:** | |
| Frontend β API endpoint β RAG/DB logic β Return result β Update UI | |
| --- | |
| ## π¨ Chapter 11: Known Issues & Future Improvements | |
| ### **11.1 Current Limitations** | |
| 1. **ChromaDB Ephemeral on Cloud** | |
| - **Problem:** Vector DB resets on container restart | |
| - **Impact:** Must re-upload PDFs after restart | |
| - **Why:** HF Spaces free tier doesn't support persistent volumes | |
| - **Solution:** Upgrade to persistent storage OR use S3/external volume | |
| 2. **Frontend Doesn't Send Student ID Header** | |
| - **Problem:** All API calls missing `X-Student-Id` header | |
| - **Impact:** Cloud users might share profile (bug!) | |
| - **Fix needed:** Update all `requests.post()` calls to include `get_headers()` | |
| - **Lines to change:** ~15 API calls in app.py | |
| 3. **No User Authentication** | |
| - **Problem:** Anyone with link can access | |
| - **Impact:** Not production-ready | |
| - **Solutions:** | |
| - Add Streamlit auth | |
| - Use Supabase authentication | |
| - Add OAuth (Google, GitHub) | |
| 4. **Quiz Questions Not Always Perfect** | |
| - **Problem:** AI sometimes generates unclear questions | |
| - **Why:** LLM hallucination, limited context | |
| - **Solutions:** | |
| - Increase k (retrieve more chunks) | |
| - Better prompt engineering | |
| - Add question validation | |
| --- | |
| ### **11.2 Future Enhancements** | |
| **Short-term (1-2 weeks):** | |
| - β Fix student ID header issue | |
| - β Add persistent ChromaDB (external volume) | |
| - β Improve quiz prompts | |
| - β Add loading spinners | |
| **Medium-term (1-2 months):** | |
| - π User authentication (Supabase Auth) | |
| - π PDF annotation support | |
| - π Spaced repetition algorithm | |
| - π Export study plan to calendar (.ics) | |
| - π Mobile-responsive design | |
| **Long-term (3-6 months):** | |
| - π Collaborative study rooms (multi-user sessions) | |
| - π Video lecture ingestion (YouTube transcripts) | |
| - π Voice input/output | |
| - π Advanced analytics (learning curves, predictions) | |
| - π Plugin system (custom quiz types, etc.) | |
| --- | |
| ## π Chapter 12: Performance & Scalability | |
| ### **12.1 Current Performance** | |
| **Local Mode:** | |
| - PDF upload (10 pages): ~5 seconds | |
| - Study plan generation: ~30 seconds | |
| - Question answering: ~3-5 seconds | |
| - Quiz generation: ~15 seconds | |
| **Bottleneck:** LLM inference (slowest part) | |
| **Cloud Mode:** | |
| - PDF upload (10 pages): ~8 seconds (network latency) | |
| - Study plan generation: ~45 seconds (API rate limits) | |
| - Question answering: ~5-7 seconds | |
| - Quiz generation: ~20 seconds | |
| **Bottleneck:** HuggingFace API rate limits (free tier) | |
| --- | |
| ### **12.2 Scalability** | |
| **Current limits:** | |
| | Component | Limit | Notes | | |
| |-----------|-------|-------| | |
| | Supabase | 500MB storage | Free tier | | |
| | HF Inference API | ~1000 requests/day | Free tier | | |
| | PDF upload size | 250MB | Streamlit limit | | |
| | Chunks in ChromaDB | ~100K chunks | Memory limit | | |
| **How to scale:** | |
| 1. **More users:** | |
| - Current: ~100 concurrent users (free HF Spaces) | |
| - Upgrade: ~1000+ users (paid HF Spaces) | |
| - Better: Deploy to AWS/GCP with auto-scaling | |
| 2. **Bigger PDFs:** | |
| - Current: ~100 pages max (4-5 PDFs) | |
| - Upgrade: Use external ChromaDB (persistent volume) | |
| - Better: Distributed vector DB (Pinecone, Weaviate) | |
| 3. **Faster responses:** | |
| - Current: 3-5 sec per query | |
| - Use GPU for local Ollama: 1-2 sec | |
| - Use larger HF models: Same speed, better quality | |
| --- | |
| ## π Chapter 13: Learning Journey | |
| ### **13.1 What You Learned Building This** | |
| By building FocusFlow, you've learned: | |
| **Frontend:** | |
| - β Streamlit for rapid UI development | |
| - β CSS for styling (Material Design) | |
| - β State management (session_state) | |
| **Backend:** | |
| - β FastAPI for building APIs | |
| - β HTTP request/response cycle | |
| - β Dependency injection pattern | |
| **AI/ML:** | |
| - β How LLMs work (prompting, context) | |
| - β Vector embeddings and similarity search | |
| - β RAG (Retrieval-Augmented Generation) | |
| - β LangChain framework | |
| **Databases:** | |
| - β Vector databases (ChromaDB) | |
| - β Relational databases (PostgreSQL, SQLite) | |
| - β JSONB storage patterns | |
| **DevOps:** | |
| - β Docker containerization | |
| - β Multi-service orchestration | |
| - β Cloud deployment (HuggingFace Spaces) | |
| - β Environment variables and secrets | |
| **Architecture:** | |
| - β Microservices pattern (frontend + backend) | |
| - β API design | |
| - β Data modeling | |
| - β Hybrid cloud/local architecture | |
| --- | |
| ### **13.2 Skills That Transfer to Other Projects** | |
| **This architecture applies to:** | |
| - π Document Q&A systems (legal docs, research papers) | |
| - π₯ Medical diagnosis assistants (symptom β diagnosis) | |
| - π E-commerce product search (natural language) | |
| - π Educational platforms (coursework, tutorials) | |
| - πΌ Internal company knowledge bases | |
| - π€ Customer support chatbots with context | |
| **The pattern is always:** | |
| 1. Ingest documents β Vector DB | |
| 2. User query β Similarity search | |
| 3. Retrieved context β LLM | |
| 4. Generated answer β Show with citations | |
| --- | |
| ## π― Final Summary | |
| **FocusFlow in 3 sentences:** | |
| 1. **Upload PDFs** β AI chunks them and stores embeddings in ChromaDB | |
| 2. **Ask questions** β RAG retrieves relevant chunks, LLM generates answers with citations | |
| 3. **Study systematically** β AI creates multi-day plans, adaptive quizzes, tracks mastery | |
| **Technology stack:** | |
| - **Frontend:** Streamlit (Python-only, rapid dev) | |
| - **Backend:** FastAPI (async, fast, modern) | |
| - **AI:** Ollama/HuggingFace + LangChain (hybrid local/cloud) | |
| - **Vector DB:** ChromaDB (semantic search) | |
| - **Database:** Supabase (cloud) / SQLite (local) | |
| **Deployment:** | |
| - **Local:** 100% private, offline, powerful | |
| - **Cloud:** Accessible, multi-user, easy to demo | |
| **Unique features:** | |
| - Auto study plan generation from PDFs | |
| - RAG with exact source citations | |
| - Hybrid architecture (works offline AND online) | |
| - Session-based multi-user support | |
| - Material Design professional UI | |
| --- | |
| ## π What's Next? | |
| **Now that you understand the architecture:** | |
| 1. **Try modifying it:** | |
| - Change UI colors | |
| - Add new quiz types | |
| - Improve prompts | |
| - Add features | |
| 2. **Apply to other domains:** | |
| - Medical Q&A from research papers | |
| - Legal document analysis | |
| - Code documentation assistant | |
| 3. **Scale it up:** | |
| - Add authentication | |
| - Deploy with persistent storage | |
| - Use faster LLMs (GPT-4, Claude) | |
| 4. **Contribute:** | |
| - Fix the student ID header bug | |
| - Add persistent ChromaDB | |
| - Improve quiz quality | |
| --- | |
| **Remember:** Every complex system is just simple parts connected together. You've now seen how ALL the parts work! π | |
| **Questions to test your understanding:** | |
| 1. Why do we use ChromaDB instead of just PostgreSQL? | |
| 2. What's the difference between `llm.invoke()` in Ollama vs HuggingFace? | |
| 3. How does RAG make AI answers more accurate? | |
| 4. Why is the frontend separate from the backend? | |
| 5. What happens when a PDF is uploaded (step-by-step)? | |
| If you can answer these, you **truly understand** the architecture! π§ β¨ | |