ViperMind

Multi-Agent Python Tutor

A Python tutor where a LangGraph router hands each request to one of four agents, the LLM writes lessons and questions, and plain code decides who passes.

Beginner · Data Structures · Lists

Topic quiz, written by the LLM with its answer key

  1. What does len([3, 1, 4]) return?3
  2. Which method adds an item to the end of a list?append()
  3. For nums = [2, 4, 6], what is nums[-1]?2key 6
  4. What does [1, 2] + [3] give?[1, 2, 3]

3 of 4 correct, 75%Pass mark 70%, checked by code

Passed: Dictionaries unlocked
Illustration with made-up questions and answers. Not output from the live system.

The problem

Learning Python alone usually means jumping between videos and exercises with nobody checking whether you actually understood the last topic before moving on. I wanted a tutor that teaches a topic, tests it, and only lets you continue once you’ve shown you know it.

Constraints

  • Pass or fail has to be exact and repeatable. A learner can’t be held back, or pushed ahead, because a model graded generously one day.
  • Generated lessons cost time and money, so the same lesson shouldn’t be generated twice.
  • The tutor has to keep teaching when OpenAI or the cache is down.

How it works

The curriculum has three levels, Beginner, Intermediate and Advanced, each with two sections of five topics: 30 topics in all. Every request goes through a LangGraph router, which hands it to one of four agents: the tutor writes lessons, explanations and hints; the assessment agent writes quizzes, section tests and level finals; the content agent writes examples and practice problems; the progress agent reads the learner’s results. GPT-4 is called through LangChain and asked for JSON.

Each question comes with its answer key. When a learner submits, the code compares their answers with the key, scores the attempt, and checks it against the pass mark before progress is saved to PostgreSQL.

Key decisions

  1. The LLM writes the questions, code grades the answers. Every multiple-choice question is generated with its correct option. Scoring is a comparison with that key, so the same answers always get the same score.
  2. Pass marks that rise with the stakes. 70% to pass a topic quiz, 75% for a section test, 80% for a level final. Quizzes can be retaken freely; section tests and finals allow one retake. All of it lives in one configuration, adjustable without code changes.
  3. Cache generated lessons by their context. A lesson or explanation is stored in Redis under a hash of what it was generated from, so a repeat request is answered without calling the model. Lifetimes match how fast each kind of data changes: 24 hours for the curriculum, 1 hour for generated lessons and explanations, 5 minutes for a learner’s progress.
  4. Keep teaching when a dependency fails. If OpenAI fails, the tutor serves a pre-written lesson, question set or hint instead of an error. If Redis is unreachable, the app carries on without the cache. If the model returns broken JSON, a safe default takes its place.

Results

  • A complete learning path: 30 topics across 3 levels, with quizzes, section tests and level finals.
  • Runs as a 7-service Docker Compose stack: the FastAPI backend, the React frontend, PostgreSQL, Redis, Nginx, and Prometheus with Grafana for monitoring.
  • JWT sign-in with bcrypt-hashed passwords, and database changes managed with Alembic migrations.

What I’d do next

  • Grade short code answers by running them against tests in a sandbox, not just multiple choice.
  • Use structured outputs instead of parsing JSON from free text.
  • Add an evaluation set that checks generated questions for one clearly correct option before they reach a learner.

Next projectDocuPilot