An adaptive-learning runtime that builds a per-learner concept graph from any source text, then drives question selection against it, inserting newly-detected prerequisite gaps as live graph nodes mid-session.
video_2x_small.mp4
A learner gives Web a goal and a source (paper, syllabus, chapter). The system runs a brief Socratic intake, then synthesizes a prerequisite DAG of concepts grounded in the source, lays it out as an interactive graph, and runs adaptive practice over it. Each attempt updates the learner's proficiency, schedules the next review via SM-2, and — when the LLM classifies a wrong answer as a prerequisite gap rather than a misconception — proposes a new concept node that, once accepted, is inserted into the graph with inferred edges and pre-generated questions.
The loop closes inside a single session: a wrong answer can grow the graph it's drawn from. Mastered concepts trigger an extension proposal so the graph also expands upward toward the learner's stated goal.
- Concept graph is first-class and multi-tenant.
UnitGraphrows shareConceptrows throughGraphMembershiprather than duplicating them; mastery state lives on the concept, not the membership. Cross-graph extensions are tracked byGraphLink. (adaptive-tutor/prisma/schema.prisma) - Mastery is a two-clock model. SM-2 decides when to review; an
Elo-style update decides how much a single attempt moves the needle.
Backward prerequisite-confidence propagation lets a correct answer on a
high-level concept lift the priors on its dependencies.
(
adaptive-tutor/src/lib/algorithms/sm2.ts,adaptive-tutor/src/lib/algorithms/questionSelector.ts) - Question selection scores three signals.
priority = uncertainty × graph-centrality × prerequisite-readiness. Difficulty within a concept targetsproficiency + 0.15— Vygotsky's zone of proximal development as a one-line rule. - LLM is in the loop, not on top of it. Curriculum-graph synthesis
emits structured JSON validated by Zod and cycle-checked via Kahn's
algorithm before persistence; an error classifier grades free-response
answers into
CORRECT/MINOR/MISCONCEPTION/PREREQUISITE_GAPand writes to a gap-detection ledger that drives live graph mutation. - Provider-agnostic LLM transport. Vercel AI SDK v6 with
Anthropic-compatible endpoint pluggability — defaults to MiniMax,
override
ANTHROPIC_BASE_URLfor native Anthropic, switch packages for OpenAI.
Next.js 16 (App Router, Turbopack) · React 19 · TypeScript · Tailwind v4 · Prisma 7 + libSQL / SQLite · Vercel AI SDK v6 · Zustand · @xyflow/react · d3-force · Zod · Vitest.
cd adaptive-tutor
cp .env.example .env # fill in ANTHROPIC_API_KEY (or MINIMAX_API_KEY)
npm install
npx prisma db push # initialize SQLite at prisma/dev.db
npm run dev
open http://localhost:3000See ARCHITECTURE.md for the closed-loop diagram —
curriculum-graph synthesis → question selector → attempt + LLM evaluator
→ proficiency / SM-2 / gap detection → graph mutation → back to the
selector.
adaptive-tutor/ — Next.js app (all runtime code)
src/app/(tabs)/ — chat, learn, graph
src/app/api/ — 30+ route handlers
src/lib/algorithms/ — sm2, questionSelector, graphValidator, forceLayout
src/lib/prompts/ — phase-specific LLM prompts
prisma/schema.prisma — concept-graph + evidence ledger
scripts/ — seed and debug scripts
docs/internal/ — design notes
ARCHITECTURE.md
LICENSE
v1 was the project that won Yale's CS hackathon. Current work is a learning-outcomes study in collaboration with Yale faculty; a handful of edtech teams are looking at it in parallel.