← Blog

Ein selbstübersetzender Blog: SQLite, ein Markdown-Editor und ein lokales LLM

DEENESRUUK

Dieser Blog hat eine leicht ungewöhnliche Eigenschaft: Ich schreibe einen Beitrag einmal auf Englisch, und ein lokales Sprachmodell erzeugt die russischen und ukrainischen Versionen. Hier ist die Maschinerie – und wie immer habe ich das Modell bewusst aus dem kritischen Pfad gehalten.

Beiträge sind Daten, keine Dateien

Die erste Blog-Version speicherte jeden Beitrag als Markdown-Datei, die zur Build-Zeit kompiliert wurde. Nützlich für einen Entwickler, nutzlos zum Bearbeiten zwischendurch – jede Korrektur bedeutete einen Neuaufbau und ein erneutes Bereitstellen. Daher wurden die Beiträge in SQLite verlagert, eine Zeile pro (slug, language), und das Markdown wird zur Anforderungszeit zu HTML gerendert.

Diese einzige Änderung hat alles andere freigeschaltet: einen Admin-Editor. Hinter dem nur mit Passkey zugänglichen /admin befindet sich ein einfacher Markdown-Editor – Titel, Slug, Tags, ein großes Body-Feld und ein Published-Umschalter. Das Schreiben oder Korrigieren eines Beitrags ist nun ein Textarea und ein Speichern-Button, ohne sichtbaren Build-Schritt.

Ein Button, zwei Sprachen

Die Seite ist trilingual (EN / RU / UK), und drei handgeschriebene Kopien jedes Beitrags synchron zu halten, ist genau die Art von lästigem Geschick, das verdirbt. Daher gibt es neben jedem englischen Beitrag einen „Translate → RU & UK“-Button.

Man drückt ihn, und der Server übergibt den Beitrag an ein lokales Gemma-Modell (über Ollama im LAN – kein Text verlässt das Netzwerk). Ein strenges Prompt weist es an, Titel, Beschreibung und Inhalt zu übersetzen und dabei alle Markdown, Codeblöcke, URLs und technischen Begriffe (SQLite, BGP, Dateinamen) exakt so zu belassen, wie sie geschrieben wurden. Die Übersetzung läuft im Hintergrund – Sprachmodelle brauchen Zeit – und das Ergebnis wird als Entwurf gespeichert.

Dieses Wort ist wichtig. Übersetzungen veröffentlichen sich niemals von selbst. Sie landen als Entwürfe, damit ich sie lesen, die seltsamen umständlichen Formulierungen (besonders beim Ukrainischen) korrigieren kann und sie dann erst live schalten. Das Modell schreibt einen ersten Durchgang; ein Mensch gibt das letzte Wort.

Die Seite des Lesers

Jeder Beitrag landet unter drei URLs – /blog/…, /ru/blog/…, /uk/blog/… – mit einem kleinen Sprachumschalter im Artikel, der nur die tatsächlich veröffentlichten Versionen anzeigt. Jede Seite trägt ihre eigene kanonische URL, BlogPosting-Strukturdaten in ihrer jeweiligen Sprache und einen Eintrag in der Sitemap, damit Suchmaschinen drei ordentliche lokalisierte Artikel sehen und nicht eine Seite mit einer Query-String.

Und weil Ehrlichkeit billig und Vertrauen es nicht ist, tragen jeder Beitrag und das Blog-Index eine kurze Transparenznotiz: Die meisten Beiträge sind mithilfe von KI erstellt worden, und die RU/UK-Versionen wurden maschinell übersetzt und überprüft.

Das gleiche Prinzip, wiederholt

Wenn Sie die anderen Beiträge hier gelesen haben, erkennen Sie die Form wieder. Das LLM ist ein Entwurfs- und Übersetzungsassistent, nicht die Quelle der Wahrheit – das ist die SQLite-Zeile. Es läuft an der Seite, bei Bedarf, und produziert Entwürfe, die ein Mensch genehmigt; wäre Gemma ausgefallen, würde der Blog es nicht merken, ich hätte nur noch keine frische Übersetzung.

Ein Sprachmodell ist eine wunderbare Möglichkeit, einen Satz in einer anderen Sprache zu beginnen. Es ist ein schlechter Ort, um die redaktionelle Entscheidung zu beenden. Dieser Blog basiert auf dieser Linie.

Transparenz: Die meisten Beiträge werden mit KI-Unterstützung verfasst, und die nicht-englischen Versionen werden von einem lokalen LLM maschinell übersetzt und anschließend geprüft. Fehler entdeckt? Bitte gib mir Bescheid.