A self-hosted, personalized AI learning platform powered by local LLMs, knowledge graphs, and retrieval-augmented generation (RAG). Every lesson is dynamically generated and uniquely tailored to the learner's progress, making each session context-aware and non-repetitive.
This project is a reference implementation of the architecture described in the blog post:
For a deeper dive into the design principles and philosophy behind local-first AI systems, see the book Sovereign AI: Building Local-First Intelligent Systems.
- Features
- Architecture
- Tech Stack
- Getting Started
- Usage
- Project Structure
- Customization
- Deployment
- License
- Related Resources
- Self-Hosted & Private — Everything runs locally with no reliance on cloud APIs. Your learning data stays on your machine.
- Dynamic Lesson Generation — Each lesson is generated on-the-fly by a local LLM, uniquely adapted to the user's current knowledge level.
- Knowledge Graph-Driven Curriculum — Concepts and their relationships are modeled as a directed graph (using NetworkX). The system navigates prerequisite chains and recommends the optimal next topic.
- Retrieval-Augmented Generation (RAG) — Prior lessons and concept embeddings stored in ChromaDB are retrieved at generation time to enrich new content with relevant context.
- Adaptive Difficulty — The LLM prompt is tuned based on the learner's mastery level (beginner / intermediate / advanced) for each concept.
- Progress Tracking — Mastery scores persist in PostgreSQL, and the knowledge graph uses them to decide what to teach next.
- Content Ingestion — Upload markdown files to automatically extract headings as concepts, embed them, and add them to both the graph and vector store.
- Interactive Exercises — Lessons include practice exercises with AI-generated feedback.
The system follows a modular three-layer design:
┌─────────────────────────────────────────────────┐
│ Frontend │
│ Next.js + React + TailwindCSS │
│ Dashboard │ Lesson UI │ Progress │ Upload │
└──────────────────────┬──────────────────────────┘
│ HTTP (REST API)
┌──────────────────────▼──────────────────────────┐
│ Backend │
│ FastAPI │
│ Content Processing │ Progress │ KG Management │
└──────┬──────────────────────────────┬───────────┘
│ │
┌──────▼──────────┐ ┌─────────▼───────────┐
│ PostgreSQL │ │ ChromaDB │
│ User progress │ │ Vector embeddings │
│ Lesson history │ │ Semantic search │
│ Concept graph │ │ │
└─────────────────┘ └─────────────────────┘
▲
│
┌─────────────────────────────┴───────────────────┐
│ AI Layer │
│ Local LLM (Ollama) │ Knowledge Graph (NetworkX)│
│ Sentence-Transformers │ RAG Pipeline │
└─────────────────────────────────────────────────┘
- A user requests a lesson from the frontend (either for a specific concept or via auto-recommendation).
- The backend queries PostgreSQL for the user's progress and the knowledge graph for prerequisite/concept relationships.
- If no concept is specified, the knowledge graph recommends the next optimal topic based on current mastery scores.
- The embedding service generates a query embedding for the chosen concept, and ChromaDB returns semantically similar prior content.
- The LLM service assembles a prompt containing the concept description, the user's level, previous knowledge, and retrieved context — then calls Ollama to generate a complete lesson.
- The generated lesson (markdown) is stored in PostgreSQL and returned to the frontend for rendering.
| Library | Purpose |
|---|---|
| Next.js (React) | Server-rendered UI framework |
| TailwindCSS | Utility-first styling |
| React-Flow | Knowledge graph visualization |
| react-markdown | Lesson content rendering |
| Library | Purpose |
|---|---|
| FastAPI | Async Python API |
| SQLAlchemy | ORM for PostgreSQL |
| Pydantic | Data validation |
| psycopg2-binary | PostgreSQL driver |
| Database | Purpose |
|---|---|
| PostgreSQL | Structured data (users, progress, lessons, concepts, relationships) |
| ChromaDB | Vector store for semantic search |
| Library | Purpose |
|---|---|
| Ollama | Local LLM runner |
| Mistral / Llama 3 | Recommended open-weight models |
| NetworkX | Knowledge graph construction & traversal |
| Sentence-Transformers | Text embedding generation (default: all-MiniLM-L6-v2) |
- Python 3.10+
- Node.js 18+
- PostgreSQL 14+ (running locally or accessible via network)
- Ollama installed and serving a model (e.g.
ollama pull mistral)
# Clone or create the project, then:
cd backend
# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install Python dependencies
pip install -r requirements.txt
# Configure environment
cp .env.example .env
# Edit .env with your PostgreSQL connection string and Ollama settings
# Initialize the database
python -c "from app.db.database import engine; from app.models.database import Base; Base.metadata.create_all(bind=engine)"
# Start the backend server
uvicorn app.main:app --reload --port 8000cd frontend
# Install dependencies
npm install
# Start the dev server
npm run devThe frontend runs at http://localhost:3000 and the API at http://localhost:8000.
- Open the dashboard at
http://localhost:3000. - Upload learning content — navigate to the Upload page and submit a markdown file containing headings and paragraphs. The system will parse headings as concepts and add them to the knowledge graph.
- Start learning — go to the Learn page and click "Generate Recommended Lesson" or select a specific topic. The LLM generates a unique lesson with examples and exercises.
- Track progress — as you complete lessons, your mastery level updates. The knowledge graph uses this to recommend the next optimal topic.
- Explore the graph — the Progress page visualizes concept relationships so you can see how topics interconnect.
ai-learning-system/
├── backend/
│ ├── .env.example
│ ├── requirements.txt
│ └── app/
│ ├── __init__.py
│ ├── main.py # FastAPI app, CORS, routes
│ ├── api/
│ │ └── routes.py # API endpoint definitions
│ ├── db/
│ │ ├── database.py # SQLAlchemy engine & session
│ │ └── vector_store.py # ChromaDB client wrapper
│ ├── models/
│ │ └── database.py # ORM models (User, Concept, Lesson, etc.)
│ └── services/
│ ├── embedding_service.py # Sentence-Transformer wrapper
│ ├── knowledge_graph.py # NetworkX graph management
│ └── llm_service.py # Ollama API client
├── frontend/
│ ├── app/
│ │ ├── globals.css
│ │ ├── layout.tsx # Root layout with sidebar
│ │ ├── page.tsx # Dashboard
│ │ ├── learn/
│ │ │ ├── page.tsx # Topic selection / recommended lesson
│ │ │ └── [id]/
│ │ │ └── page.tsx # Lesson viewer
│ │ ├── progress/
│ │ │ └── page.tsx # Progress & knowledge graph view
│ │ └── upload/
│ │ └── page.tsx # Markdown content upload
│ ├── components/
│ │ ├── Sidebar.tsx # Navigation sidebar
│ │ ├── LessonViewer.tsx # Renders lesson markdown
│ │ └── KnowledgeGraph.tsx # React-Flow graph visualization
│ └── lib/
│ └── api.ts # API client helpers
├── .gitignore
└── README.md
Update the LLM_MODEL environment variable in backend/.env:
LLM_MODEL=llama3Make sure the model is pulled into Ollama:
ollama pull llama3The system uses three tiers based on the user's mastery level for a concept:
- Beginner (mastery < 0.4)
- Intermediate (mastery 0.4–0.8)
- Advanced (mastery > 0.8)
You can tune these thresholds in backend/app/services/llm_service.py in the generate_lesson method.
The default embedding model is all-MiniLM-L6-v2. To use a different Sentence-Transformer model, pass the model name when initializing EmbeddingService in backend/app/services/embedding_service.py.
While the system is designed for local-first use, you can deploy it on a private server or LAN:
- Backend: Use
gunicornwithuvicornworkers for production:gunicorn -k uvicorn.workers.UvicornWorker app.main:app - Frontend: Build with
npm run buildand serve withnext start - Database: Point to a remote PostgreSQL instance via the
DATABASE_URLenv var - Ollama: Run Ollama on the same machine or a LAN-accessible host; update
OLLAMA_BASE_URLaccordingly
This project is provided as a reference implementation of the concepts discussed in the blog post and book. Use it as a starting point for your own personalized learning system.
- Blog Post: Building a Personalized AI Learning System with Local LLMs
- Sovereign AI: Building Local-First Intelligent Systems — the book that inspired this architecture
- Ollama — run local LLMs effortlessly
- ChromaDB — open-source vector database
- React-Flow — interactive graph visualizations
