Pinned Post

OpenSpec UI: ein Live-Dashboard für deine Specs

Bild
OpenSpec UI: ein Live-Dashboard für deine Specs Wer mit einem KI-Agenten und OpenSpec arbeitet, kennt das Bild. Im Projekt wächst ein Verzeichnis openspec/ heran: Changes mit proposal.md , design.md , tasks.md und ihren Delta-Specs, daneben die kanonischen Specs der einzelnen Capabilities. Die Absicht hinter dem Code steht damit endlich geschrieben, statt sich in ihm zu verstecken. Nur verteilt sie sich über Dutzende Markdown-Dateien, und der Editor zeigt eben Dateien. Was er nicht zeigt, ist der Zustand. Woran arbeitet der Agent gerade? Welcher Task ist der nächste offene? Und was hat sich verändert, während ich zehn Minuten woanders hingeschaut habe? Genau diese Lücke füllt OpenSpec UI , ein kleines Phoenix-LiveView-Dashboard, das lokal neben deinem Projekt läuft und den OpenSpec-Workspace im Browser zeigt — live, während gearbeitet wird. Der Code liegt offen auf GitLab: https://gitlab.com/public_elixir/openspec_ui Ein Blick statt Datei-Hopping Du startest den Server, gibst d...

Ich habe ein ML-Feature gebaut — und nie Python angefasst

Ich wollte meine Banktransaktionen automatisch kategorisieren. Jeder Reflex sagte: Python, ein separater ML-Service, eine MLOps-Pipeline. Am Ende waren es rund 200 Zeilen Elixir, und das Ganze ist heute das wartungsärmste Feature der ganzen App.

Ich baue privat eine kleine Finanz-App. Sie zieht Kontoumsätze von der Bank und soll sie in Kategorien einsortieren: Lebensmittel, Miete, Versicherung, Einkommen und so weiter. Klingt trivial, ist es aber nicht. Denn Banktexte sehen so aus:

DE12 3456 / EDEKA SAGT DANKE//KOELN/DE 2024-11-03T08:14
LASTSCHRIFT 1U1 TELECOM GMBH KD-NR 4711

Kryptisch, abgekürzt, oft deutsch und voller Boilerplate. Eine Liste aus if String.contains?-Abfragen würde immer weiter wachsen und trotzdem ständig danebenliegen. Es ist ein Klassifikationsproblem, also ein Fall für Machine Learning.

Spannend finde ich den Reflex, der dann einsetzt. Für die meisten Teams heißt „ML" automatisch „zweite Welt": ein eigener Python-Service, ein separates Repo, irgendwo ein Modell-Artefakt, dazwischen gRPC oder eine Queue. Dazu kommen ein zweites Deployment, eine zweite Sprache und ein zweiter Satz Betriebssorgen. Das eigentliche Feature ist winzig, der Rattenschwanz dahinter dafür umso länger.

Ich habe mich gefragt, ob das wirklich sein muss. Meine App läuft auf Elixir/Phoenix, also auf der Erlang-VM (der „BEAM"). Und das Elixir-Ökosystem hat in den letzten Jahren einen kompletten ML-Stack bekommen: Nx (Tensoren, ähnlich wie NumPy), EXLA (Compilation auf CPU/GPU über Googles XLA) und Bumblebee (vortrainierte Transformer-Modelle direkt von Hugging Face).

Das Ergebnis: Das ML-Feature lebt in derselben Codebasis wie der Rest der App, ohne zweiten Service und ohne zweite Sprache. Das „Modell" ist ein ganz normaler Prozess unter demselben Supervisor wie meine Datenbank-Verbindung:

# In der Application-Supervision-Tree — der Classifier ist
# einfach ein weiteres Kind, kein externer Dienst.
children = [
Finance.Repo,
{Phoenix.PubSub, name: Finance.PubSub},
Finance.Classifier.Bumblebee # lädt das Modell, startet die Inferenz
]

Wenn der Classifier abstürzt, startet OTP ihn neu. Dieselbe Fehlertoleranz, die meine Web-Requests schützt, schützt also auch die Inferenz, und ich musste dafür nichts Neues lernen.

Was mich an dem Projekt überrascht hat, war nicht, dass es funktioniert, sondern wie wenig Sonderbehandlung ML auf der BEAM überhaupt braucht. Es fühlt sich nicht wie ein angeflanschtes Fremdsystem an, sondern wie ein normaler Teil der Anwendung.

In den nächsten Artikeln gehe ich die Entscheidungen durch, auf denen das Ganze beruht:

  1. Klassifizieren ohne Trainingsdaten: wie ich ohne ein einziges gelabeltes Beispiel auskomme.
  2. Lernen ohne Retraining: wie eine Korrektur im UI das Verhalten sofort verbessert.
  3. Skalieren ohne Infrastruktur: wie das Modell auf einer anderen Maschine läuft, ohne dass mein Code etwas davon merkt.
  4. Wann man bewusst kein ML nimmt: denn die beste KI-Entscheidung ist manchmal, gar keine zu treffen.

Vielleicht hältst du ML für etwas, das nur Spezialisten in einem eigenen, separaten System bauen. Dabei kann es ein ganz normaler Teil deiner bestehenden App sein.

Im nächsten Teil: Wie man kategorisiert, ohne ein Modell zu trainieren.

→ Weiter zu Teil 2: Klassifikation ohne ein einziges Trainings-Label

Kommentare

Beliebte Posts aus diesem Blog

Splitting an ML model and a web app across two BEAM nodes — the technical blueprint

Jido in Practice: Agents in Elixir as Composable Actions

A Foundation Model in the BEAM: On-Chain Anomalies with Google TimesFM in Elixir