SlideTutor — Turning Lecture PDFs into a Grounded Learning Loop
Inspiration
SlideTutor began with the way I was actually studying from lecture slides. I often had several PDFs open, searched them one at a time, copied pages into a chatbot, and then lost track of which answer came from which slide. Quiz generation and mistake tracking happened in separate tools, so none of those steps informed the next one.
I built SlideTutor to keep the whole process in one place:
Open a slide
→ ask a question
→ check the cited page
→ take a quiz
→ review mistakes
→ return to the relevant evidence
The main constraint was that the PDFs had to remain the source of truth. SlideTutor could explain, translate, test, and recommend what to review, but students should always be able to verify its output against the original material.
What it does
SlideTutor is a local Streamlit application that turns a collection of lecture PDFs into a study workspace.
Students can create projects, organize multiple PDFs, browse page thumbnails, inspect the original slide, and ask for an explanation or translation of the current page. Free Ask supports follow-up questions and returns file-and-page citations.
For questions that need more context, SlideTutor can use a bounded retrieval agent. The agent can read selected pages, inspect neighboring slides, or search the current PDF. It is limited to three read-only tools, a maximum of three rounds, fixed call and context budgets, and the current file scope. If it fails before retrieving useful evidence, the application falls back to a stable single-turn planner.
SlideTutor includes two assessment workflows:
- Fast Quiz generates practice questions quickly and can prioritize unresolved mistakes from earlier attempts.
- Reviewed Final Exam uses a stricter pipeline for mixed-format exams:
Topic catalog
→ exam blueprint
→ evidence binding
→ question generation
→ deterministic validation
→ semantic review
→ at most one repair
→ activation
My first exam implementation allowed the model to return filenames and page numbers directly. The citations looked plausible, but there was no guarantee that the model had actually used those pages.
I removed that responsibility from the model. The planner now creates coverage slots without citations. The application retrieves real slide evidence for each slot, assigns trusted evidence identifiers, and only then asks the model to write the questions. Final citations are reconstructed from those identifiers instead of copied from model output.
The assessment system supports multiple-choice, true/false, fill-in-the-blank, and short-answer questions. Objective questions are scored deterministically. Fill-in answers are graded in one bounded AI batch as correct or incorrect, while short answers use rubric-based partial credit.
After submission, SlideTutor generates question-level feedback and a Weakness Report. Every reported weakness or strength must be supported by scored questions and their citations. When a student answers everything correctly, the system produces a Mastery Summary instead of inventing areas for improvement.
The Dashboard separates historical performance from current review needs. It shows recent weaknesses, mastered topics, review priorities, and the pages the student should revisit. Attempt history is stored at the project level, while temporary conversational context remains session-only.
How I built it
I built SlideTutor in Python and Streamlit, with Pydantic models defining the boundaries between retrieval, agents, exam generation, grading, and storage.
PyMuPDF handles the default PDF extraction and page rendering. Marker is optional and is used for pages where formulas, tables, or complex layouts make basic extraction unreliable. Both outputs pass through a quality-routing layer. A failed enhanced parse cannot make an otherwise usable PDF unavailable.
Retrieval combines exact title and phrase matching, multilingual BM25, and multilingual dense embeddings. Reciprocal rank fusion merges the rankings. When the embedding backend is unavailable, the application falls back to TF-IDF.
File and page scope are enforced before retrieved text reaches the model. Page identities are retained throughout retrieval, generation, grading, and storage.
Streamlit reruns created a separate set of problems. Parsing, indexing, Q&A, and exam generation can take long enough that blocking the interface is not practical, so they now run as background jobs. Each job stores the request that created it, reports progress, supports cancellation, and can only be finalized once.
Indexes and parsed page content also use generation-aware activation. A failed or cancelled rebuild cannot replace the last working version with partial data.
I used Codex with GPT-5.6 during development, mainly to inspect unfamiliar parts of the repository before changing them, turn acceptance criteria into implementation plans, and create regression tests for bugs I had already reproduced.
It was particularly useful when tracing problems across Streamlit job state, session state, persistent history, and UI rendering. I still reviewed architectural changes, generated code, and test failures manually. SlideTutor itself uses an OpenAI-compatible provider layer and does not require GPT-5.6 as its runtime model.
The current repository passes 306 automated tests covering retrieval scope, agent policies, parser fallbacks, background-job lifecycles, reviewed exam validation, AI grading, persistent history, quiz feedback, and UI state behavior.
Challenges I faced
Preventing fabricated citations
Prompt instructions were not enough to make citations trustworthy. A model could still return a convincing filename and page number that had never been part of its evidence.
For Reviewed Final Exam, I changed the pipeline so the planner proposes topics without citations. The application retrieves and binds real evidence to each planned question, assigns an internal evidence ID, and later maps that ID back to the correct file and page.
The model can write a question from trusted evidence, but it cannot invent the final citation.
Limiting the retrieval agent
An open-ended agent introduced repeated searches, unnecessary latency, and unpredictable context growth. More autonomy did not automatically produce better answers.
I reduced the agent to three read-only slide tools and restricted it to the current PDF. It stops after three rounds or when it has enough evidence. If it retrieves useful material before failing, that evidence can still be passed to the grounded answerer.
This kept the agent observable and made its failure behavior easier to test.
Generating reliable quizzes
Quiz generation exposed many small failure modes: missing fields, duplicate questions, incorrect type ratios, leaked answers, fabricated citations, ambiguous fill-in questions, and incomplete repair responses.
I added schema validation, type quotas, deterministic quality checks, evidence verification, duplicate detection, bounded semantic review, and at most one repair pass.
Repair output must include every requested question. It cannot silently remove a question because the model forgot to return it.
Keeping Streamlit stable during long tasks
Early versions mixed together the running job, the current page, saved answers, and temporary UI state. Streamlit reruns could leave controls disabled, move a streamed answer to another part of the page, lose history after refresh, or display a result under the wrong slide after navigation.
I eventually separated four things:
- immutable job state,
- persistent answer and attempt records,
- session-only conversational memory,
- the UI projection for the currently selected page.
This made it possible to navigate while a job was running, preserve the page that originally created the task, cancel safely, and prevent duplicate finalization.
Turning scores into trustworthy advice
A grading error does not affect only one question. It can change the total score, weakness analysis, and every later review recommendation.
I encountered a case where a correct fill-in answer received zero points while the generated explanation simultaneously said the answer was correct.
After that, I changed submission into an atomic pipeline. All AI grading must complete successfully before the score, attempt history, and Weakness Report are saved. A partial grading result cannot become part of the student record.
What I learned
The main lesson was that grounding could not be added only at the prompt level. It had to be reflected in retrieval scope, evidence identifiers, validation, storage, and error handling.
I also became more deliberate about where to use a model. Models were useful for explanation, semantic planning, grading open-ended answers, and reviewing generated questions. Deterministic code was better for citations, permissions, schemas, question counts, score calculation, and deciding whether an output was complete enough to save.
Some evaluations also led me not to add features. I considered a reranker, a heavier vector database, and automatic cache eviction, but the retrieval and storage audits did not show enough benefit to justify the additional complexity.
What I am proud of
SlideTutor started as a page-by-page PDF viewer and gradually became a complete learning workflow without losing the ability to return to the original source.
In one representative Reviewed Final Exam run, the system used two PDFs to generate ten mixed-format questions, including cross-file synthesis questions. Every final citation retained its real file, page, and evidence identity. Grading completed without pending results, and the exam, audit metadata, attempt history, and Mastery Summary all reloaded correctly from storage.
The result is more than a PDF chatbot. An answer leads back to evidence, quiz results lead to specific weaknesses, and those weaknesses lead to the next pages the student should review.
What’s next
The next steps are public deployment, broader user testing, and better support for scanned or image-heavy slides.
I also plan to replace the current priority-based review suggestions with a lightweight spaced-repetition schedule such as SM-2-lite, and to evaluate retrieval and assessment quality across more subjects and document styles.
SlideTutor currently supports local PDF projects and bounded agent behavior. I intend to keep those limits visible rather than presenting unsupported document types or unlimited autonomy as finished features.
Built With
- codex
- function-calling
- gpt-5.6
- python
- rag
- streamlit
Log in or sign up for Devpost to join the conversation.