Knowledge Hub
Knowledge Hub, Part 1: Guided learning in a chat box (and how to afford it)
A subject-agnostic learning loop in Telegram: one engine, generated lessons, and a cache that makes LLM-powered practice cheap enough to run.
I have a graveyard of learning apps on my phone. They are not bad apps. They just sit behind a home screen, waiting for discipline to arrive.
The Knowledge Hub started from a simpler question: what if the lesson came to me instead? Put the learning loop inside a chat I already open, make it work for more than one subject, and keep the LLM bill low enough for one person to run.
The first proof of concept is a Telegram bot for German. But German is only the first subject. The useful part is the format.
The real idea: a format, not a German app
The product is not "a German tutor." The product is a micro-learning format. Pick a subject, break it into items, and the same engine can deliver it:
- it shows you one item at a time;
- it tracks your mastery of each (
seen → learned → mastered); - it quizzes you, harder as you improve; and
- it lets you use the item in conversation.
German is just instance #1. The same rows hold for the next subject — Python is the one queued next:
German (shipped) Python (next)
item a vocabulary word a concept / idiom
mastered recalled it three times applied it three times in context
quiz (new) translation, multiple choice "what does this expression do?"
quiz (known) gap-fill a sentence fill the blank / fix the bug
conversation roleplay in German explain or apply the concept
The columns change; the format does not. Adding a subject should mean writing a plugin, not rebuilding an app.
Why Telegram
Telegram gave the project a lot for free:
- Push — the lesson can arrive instead of waiting inside an app.
- Distribution — a link is the whole install path.
- Identity — one stable user per chat.
- UI — buttons and commands cover the first version.
Underneath: Aiogram for Telegram, FastAPI + Granian for the webhook, Redis for chat state, and Postgres for durable data. The important bit is the finite-state machine. A chat is always mid-something — quiz, onboarding, correction — and explicit states keep that from turning into a pile of flags.
The LLM on a short leash
The model writes the examples, quizzes, and explanations. A word arrives with a fresh sentence. You can ask for more, or for grammar help in the right language for your level.
It is useful because it is constrained:
Structured output. A quiz is a typed Quiz object, not prose that has to be
parsed and guessed at.
Simple state. Every item is seen, learned, or mastered, and that status
routes the quiz type:
seen -> recognition quiz (multiple choice)
learned / mastered -> production quiz (fill in the blank)
New items get recognition. Known items get production. The adaptivity is just a small enum used consistently.
A scheduler handles the habit loop: new words, quizzes, conversation prompts, and an evening recap in the learner's local time. A small gate quiz can unlock the next batch of words and also protects against duplicate sends.
Cost: cache first, model second
The architecture is shaped by cost. An LLM behind every word, quiz, explanation, and learner becomes a meter that never stops.
Two choices keep it sane.
Smart caching — generate once, reuse forever. Generated content goes into a cache keyed by word, content type, CEFR level, version, model, and variant. The first learner pays for an example sentence. Everyone after that gets a cache hit.
The cheapest model that clears the bar. The default is Gemini Flash for bounded generation, with a provider factory available when a task deserves a stronger model. Token usage, credits, and traces are tracked because you cannot manage a bill you cannot see.
I also kept the boring infrastructure in-house — auth, sessions, migrations, Postgres — because cost and understanding were part of the project.
What the proof of concept actually does
Today the bot supports email-code registration, generated examples, Know it /
Got it / More / Explain, translation and gap-fill quizzes, push quizzes,
roleplay conversations, evening recaps, streaks, profile, stats, and
settings.
The honest caveat: the engine is designed for any subject, but it currently has one subject. Python is the next test. That is where "mastered" becomes application, not recall, and where the generic parts will prove whether they are actually generic.
The project facts, status, and stack live in the Knowledge Hub lab note.
The reusable pattern
Build a guided-learning loop as a subject-agnostic format, deliver it through a chat the user already lives in, and make it affordable by caching everything that is the same for everyone.
- Separate the engine from the subject plugin.
- Use the chat platform's free gifts: push, distribution, identity.
- Keep the LLM constrained with structured output and explicit state.
- Cache generated content by its inputs, and use the cheapest model that passes.
Next
A bot that types German is a start. But you cannot speak to it, and not every learning surface belongs inside Telegram. Part 2 — Giving it a voice (and a web address): growing the system without rewriting the engine or breaking the bot.