AI / LLM Ops
Building an AI Language Tutor That Actually Works: 5 Modes, Spaced Repetition, and Cron-Driven Practice
How I replaced Duolingo with a custom AI tutor that adapts to my level, remembers what I struggle with, and bugs me at random times throughout the day.
I've been learning Spanish for a while now. A2, creeping toward B1 — travel-ready, not yet conversation-fluent. Like many developers, I tried the usual apps: Duolingo, Anki, Memrise. They all had the same problem: rigidity. Fixed lesson paths, generic vocabulary, no real conversation practice, and zero awareness of what I specifically struggle with.
So I built my own.
It's a skill for Hermes Agent — an AI assistant that runs on my Raspberry Pi and talks to me through WhatsApp. The tutor combines CEFR-based adaptive learning, SM-2 spaced repetition, grammar mastery tracking, and a cron-driven scheduler that randomly delivers practice throughout the day. Here's how it works.
The architecture: 5 modes, one skill
The tutor operates in five distinct modes, each triggered by natural language:
- Assess “Schätze mein Spanisch ein”
- Adaptive placement test — 10–15 questions across vocabulary, grammar and comprehension.
- Learn “Neue Lektion”
- 15–20 min session: warmup → 6–8 new words → grammar concept → mini-dialogue.
- Review “Wiederholung”
- SM-2 spaced repetition of due vocabulary, with AI-assigned quality scoring.
- Converse “Lass uns Spanisch reden”
- 8–12 exchange roleplay across 8 travel scenarios (restaurant, hotel, doctor…).
- Track “Wie steht's um mein Spanisch?”
- Progress dashboard — stats, streaks, skill balance and data-driven recommendations.
All state is local — four JSON files under ~/.hermes/language-data/spanisch/:
spanisch/
├── profile.json # CEFR level, grammar mastery matrix, learning goals
├── vocab.json # All words with SM-2 intervals, error counts, mastery scores
├── sessions.json # Full session log: mode, duration, topics, notes
└── progress.json # Aggregated stats, streaks, skill balance No cloud. No subscription. No lock-in. Just JSON.
SM-2: why flashcards alone don't cut it
The spaced-repetition system is SM-2 — the same algorithm behind Anki, but fully wired into the tutor's decision-making. Every word carries its schedule:
"sm2": {
"interval": 6,
"repetitions": 2,
"easiness": 2.3,
"next_review": "2026-07-13"
},
"mastery": 2 The key difference from Anki: the AI scores you, not you scoring yourself. When you translate a sentence in Review mode, the tutor evaluates your answer and assigns a quality of 0–5. That kills the “I kind of knew it, let's call it a 4” inflation that makes most self-scored SRS ineffective. Quality 1–2 triggers a reset (interval → 1 day); quality 3+ advances the interval. The easiness factor adapts per word, so your personal difficult words get more frequent review automatically.
Problem-word tracking: study smarter, not more
Not every new word counts as “learned.” The system tracks four states per word:
- presented shown, not yet used
- problem user made at least one error
- learning 1–2 correct uses, not yet solidified
- learned 3+ consecutive correct uses
Problem words get mandatory repetition in every subsequent session until they reach learned status — capped at 3 per session to avoid frustration. Your study time focuses on exactly what you're getting wrong, not re-drilling words you already know.
Grammar mastery: tracking concepts, not just words
Vocabulary is easy to track. Grammar is messier. The tutor maintains a grammar mastery matrix in profile.json:
"grammar_mastery": {
"ser_vs_estar": {"mastery": 0.6, "total_errors": 4, "last_error": "2026-07-03"},
"por_vs_para": {"mastery": 0.2, "total_errors": 8, "last_error": "2026-07-06"},
"indefinido_vs_imperfecto": {"mastery": 0.0, "total_errors": 0, "last_error": null},
"pronombres_objeto": {"mastery": 0.35, "total_errors": 6, "last_error": "2026-07-05"}
} Every grammar error is classified into one of these concepts. Mastery drops by 0.1 per error and rises by 0.05 per session with correct usage. The two weakest concepts get priority in every Learn and Review session — anything below 0.4 mastery even takes precedence over new grammar topics.
This creates a natural progression. The Spanish grammar hierarchy has 10 levels (presente → pretérito perfecto → indefinido → imperfecto → futuro → subjuntivo → condicional → imperativo → pronombres → por/para), and you don't advance until the current concept's mastery is solid.
The Korrektur-Protokoll: every error is a lesson
After every mistake — in any mode — the tutor follows a strict five-step protocol:
- 1 Show the correction — the complete, correct sentence.
- 2 Name the error — in one sentence: "You used ser instead of estar."
- 3 Explain the rule — 1–2 sentences in German, crisp and precise.
- 4 Track it — update grammar_mastery and/or vocab error_count.
- 5 Immediate re-practice — one similar sentence on the same concept before moving on.
Every error becomes a structured micro-lesson instead of a fleeting “oops, wrong.” The data persists, so the system actively hunts for your weak spots in future sessions.
Converse mode: actually speaking (without the pressure)
Converse mode is where it gets genuinely useful for travel prep. Eight scenarios — restaurant, hotel, directions, shopping, train station, doctor, making friends, phone calls. The AI plays the other role (waiter, receptionist, passerby) and adapts language complexity to your CEFR level.
- →Don't correct every error immediately — that destroys conversational flow. Corrections come every 3–4 exchanges.
- →At A2: corrections explained in German.
- →At B1: corrections in Spanish, German only for complex points.
- →Post-conversation debrief: 2–3 things that went well, 2–3 words to add to vocab, 1 grammar point noticed.
This mirrors how real language acquisition works: you need to produce language under mild pressure, not just recognize it in a multiple-choice quiz.
The cron scheduler: practice finds you
This is my favorite part. A Python script runs every hour from 9:00 to 22:00 via cron. It randomly selects ~3 times per day and delivers practice straight to my WhatsApp.
The recent innovation is dual-mode randomization. Each delivery randomly picks between:
- →Translation (50%): 5 German sentences to translate into Spanish, prioritizing my problem words and weak grammar. Mixes A2 and B1 difficulty.
- →Conversation (50%): a mini roleplay starter — “You're at a hotel reception in Madrid. The receptionist greets you…” — and we go from there.
There's also a variety enforcement rule: if the first two deliveries of the day were the same mode, the third is forced to the other. No three translation-only days.
The scheduler tracks everything in daily_practice.json:
{
"date": "2026-07-07",
"deliveries": [
{"hour": "10:00", "mode": "translation"},
{"hour": "15:00", "mode": "conversation"}
],
"total_deliveries": 87
} The probability is needed / remaining_hours — so early in the day there's a low chance of delivery, but if it's 20:00 and you still need all three, they get forced through. Practice distributes naturally across the day without being predictable.
Why this works better than apps
- 1 Adaptive to you, not a cohort. The system knows your exact error history, weak grammar concepts and problem words. Every session is personalized.
- 2 Real conversation practice. Multiple-choice and fill-in-the-blank don't teach you to produce language. Roleplaying with corrective feedback does.
- 3 It comes to you. No app to open. Practice arrives on WhatsApp at random intervals — no decision fatigue, no “I'll do it later.”
- 4 Full data ownership. All progress, vocabulary and session history live in plain JSON on your own machine. Exportable, backup-able, never vendor-locked.
- 5 Extensible. Want a new language? Copy the template, run Assess mode, and you're set up in 10 minutes.
The stack
- Agent
- Hermes Agent on a Raspberry Pi 5
- Model
- DeepSeek V4 Pro via OpenRouter
- Delivery
- WhatsApp (native integration)
- Scheduling
- System cron + Python scheduler
- Storage
- Local JSON with SM-2 data
- Cost
- ~$3–5/month in API credits
Open source
The language tutor skill and scheduler script are open source under the MIT license: github.com/d1gl3/hermes-skills (see skills/language-tutor/). The dual-mode conversation feature was just merged — the scheduler now randomly chooses between translation exercises and mini roleplays, with a variety guarantee so you never get three of the same in a row.
¿Quieres probarlo? Clone the repo, set up Hermes Agent, and run hermes cron create with the scheduler script. In 10 minutes you'll have an AI tutor that knows your weaknesses better than you do.