← All projects

LOCAL AI · RAG · NEXT.JS + OLLAMA · IN DAILY USE

StudyBuddy v2A tutor that knows your course.

StudyBuddy turns downloaded online courses (videos, transcripts, PDFs and readings) into personal tutors: they answer Socratically, citing the exact minute of the video, and generate quizzes, spaced-repetition flashcards, summaries and explorable concept maps. Everything runs on a consumer GPU, and no data leaves the computer. It is a personal AI-assisted project: I chose the architecture, models and product, with the code written together with Claude Code.

Role
Personal AI-assisted project: architecture, model selection and product
Stack
Next.js 16 · React 19 · TypeScript · SQLite (Drizzle, sqlite-vec, FTS5) · Ollama · Transformers.js · Docker
Scale
783 documents from 9 courses · 2,321 chunks · ~3–6 s per answer on an RTX 4080 Super
Quality and status
Over 80 test files with node:test · prompt eval sets · in daily use, public code on GitHub
01

The goal

Online courses are full of material but short on interaction: hours of video and hundreds of files, and when you have a doubt, finding where it was covered is slow. General AI assistants do not know what your course says, make up details and ask you to upload the material to external services. I wanted a study companion that answers only from the course, cites its sources, makes me reason instead of handing me the answer and schedules my reviews, with no subscriptions or pay-per-use APIs.

02

How it works

An ingestion command reads the course folder, splits transcripts, readings and PDFs into passages that remember their minute in the video, and indexes them in a single SQLite file. For each question a hybrid search (semantic and keyword) finds 20 candidates, a cross-encoder on the GPU keeps the best 6, and a local 12B model answers using only those. Every model call goes through a single layer that assigns each task its own model.

Features

Socratic tutor with citations

The tutor does not give the answer: it confirms, adds a piece and asks the next question. Every answer shows numbered sources; clicking a transcript opens the built-in player at the exact minute the instructor covers it. It also works with questions in Italian on English material.

LLM-graded quizzes

Given a topic, the model generates a multiple-choice question constrained by a JSON schema. A second prompt acts as the judge: a 0–5 grade and an explanation anchored to the course text.

Spaced repetition with SM-2

Flashcards come from a topic or a concept on the map. You answer in your own words, the LLM grades it, and the SM-2 algorithm, the one behind Anki, decides when to show the card again.

Explorable concept maps

The model proposes concepts and relations, each with a definition, examples and sources. Double-clicking enters a bubble and the sub-level is generated from the material, reusing concepts already on the map. AI edits are atomic commands, so undo and redo work on them too.

Summaries and slides

Summaries work in blocks and then combine them (map-reduce), so even a whole module fits in the model’s context. Slides come with SVG illustrations drawn by the local model.

Library and guided import

The app scans the courses folder read-only, tells courses apart from specialisations and shows an editable preview before writing to the database. Import runs in the background; a per-file hash lets it skip unchanged files, and the few videos without subtitles are transcribed by Whisper.

Screens

A concept map about React: bubbles linked by relations such as “include” and “constrain”, with the useEffect concept card open on the right showing its definition, examples and links.
Concept map and concept card
Inside the useEffect bubble: sub-concepts generated from the material, such as Dependency Array and Cleanup Function, with dashed pills pointing to other levels.
Inside a bubble: the sub-level
The Socratic tutor: the lesson video, blurred, opened at 4:20 above a question about useEffect and the tutor’s reply, which answers with a question.
A citation opens the video at the right minute
A quiz on Flexbox and Grid with four options, six timestamped sources and the final grading with SM-2 quality 5 out of 5.
Quiz with sources and grading

Real app output, generated locally from a front-end course series, October 2026. Videos, the course name and file paths are blurred out of respect for the rights to the material.

Technical decisions

01

Hybrid search, fused by rank

Semantic search misses exact terms like useEffect; keyword search does not understand an Italian question on English material. I use both (sqlite-vec and BM25 on FTS5) and merge them with Reciprocal Rank Fusion, which combines the lists by rank and never has to compare incompatible scores.

02

Context silently cut off

Ollama defaults to a 4,096-token context and, when the prompt is longer, cuts off its beginning: exactly the course passages. I set the context to 16k explicitly.

03

Reranker from 13 seconds to 0.6

Without truncation, padding to the longest document pushed the cross-encoder to 13 seconds and 13 GB of RAM. With batches of 8 and at most 512 tokens it drops to 0.6 s on the GPU. On the GPU, int8 weights turned out slower than fp16, because many integer operators have no CUDA kernels and fall back to the CPU.

04

An invalid grade never resets a card

If the LLM judge returns invalid output even after a retry, the system reports an error instead of recording a zero. For SM-2, a zero means starting a card you already know from scratch.

05

Prompts measured, not guessed

Every prompt change is rerun on a fixed set of cases with hand-reviewed verdicts: exact agreement, agreement within one level and a confusion matrix, saved per prompt version. That is how the flashcard judge moved from a 0–5 score to a verdict that lists what the question requires and what the answer is missing.

06

A local app still needs protecting

A malicious site can point its domain at 127.0.0.1 or send cross-site requests to a local server. The APIs accept only local hosts and JSON writes, which force a CORS preflight; paths stay inside the home folder, and the video server only serves indexed files.

Something similar in mind?

Tell me about it ↗