← All writing

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.

  1. Separate the engine from the subject plugin.
  2. Use the chat platform's free gifts: push, distribution, identity.
  3. Keep the LLM constrained with structured output and explicit state.
  4. 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.