Projekt JARVIS, Tag 4: Aus dem Experiment wird langsam eine Plattform

Chris //

Nach der überraschend ausführlichen Namenssuche ging es wieder an die eigentliche Entwicklung.

Und während die ersten beiden Tage noch relativ klar abgegrenzt waren, wurde es jetzt deutlich schwieriger, jedem neuen Feature einen eigenen Tag zuzuordnen.

Denn inzwischen greifen immer mehr Komponenten ineinander.

Aus Wetter und Kalender wurden Orte, Routing, Warnungen, eine API, Telegram und schließlich sogar die ersten Schritte in Richtung Sprache.

Deshalb wird Tag 4 etwas umfangreicher.

JARVIS lernt, was Zuhause und Arbeit bedeuten

Eine der Grundlagen für viele kommende Funktionen sind Orte.

Wenn ich JARVIS frage:

Jarvis: Wie weit ist es von Zuhause zur Arbeit?

möchte ich natürlich nicht jedes Mal meine vollständige Adresse nennen.

Deshalb kennt die Konfiguration inzwischen feste Orte wie Zuhause und Arbeit.

Vereinfacht sieht das Konzept so aus:

location:
  home:
    name_env: JARVIS_HOME_NAME
    address_env: JARVIS_HOME_ADDRESS
    latitude_env: JARVIS_HOME_LATITUDE
    longitude_env: JARVIS_HOME_LONGITUDE

  work:
    name_env: JARVIS_WORK_NAME
    address_env: JARVIS_WORK_ADDRESS
    latitude_env: JARVIS_WORK_LATITUDE
    longitude_env: JARVIS_WORK_LONGITUDE

Auch hier liegen die eigentlichen persönlichen Werte wieder außerhalb der normalen Konfiguration.

Damit können immer mehr Module dieselben Ortsinformationen verwenden.

Dawarich Atlas und Valhalla übernehmen das Routing

Für die Geocodierung und Routenberechnung wollte ich möglichst wieder eine selbst gehostete Lösung verwenden.

Da bei mir ohnehin Dawarich Atlas aufgebaut wurde, lag es nahe, diesen Dienst auch für JARVIS zu verwenden.

Damit kann eine Adresse zunächst in Koordinaten umgewandelt werden.

Anschließend übernimmt Valhalla die eigentliche Routenberechnung.

Das Ergebnis sieht beispielsweise so aus:

Jarvis: Wie weit ist es von Zuhause zur Arbeit?

Von Zuhause zur Arbeit sind es mit dem Auto etwa
68,5 km.

Die berechnete Fahrzeit beträgt ungefähr 45 Minuten.

Damit kennt JARVIS erstmals nicht nur einen Ort.

Er versteht die Beziehung zwischen zwei Orten.

Und genau das ist später für Kalendertermine ziemlich wichtig.

Routing ist komplizierter als gedacht

Natürlich funktionierte auch das nicht sofort perfekt.

Geocoding Dienste können ausfallen.

Adressen können mehrdeutig sein.

Firmennamen und Straßenadressen können unterschiedliche Ergebnisse liefern.

Und selbst wenn die Koordinaten stimmen, muss eine natürlich formulierte Frage erst einmal korrekt zerlegt werden.

Dazu kamen klassische Fehler wie:

Dawarich Atlas Geocoding fehlgeschlagen
HTTP 503

Also musste auch hier wieder eine vernünftige Fehlerbehandlung eingebaut werden.

Mittlerweile gibt es zusätzlich einen direkten CLI Aufruf:

jarvis route plan "Frankfurt am Main"

Mit verschiedenen Fortbewegungsarten:

auto
bicycle
pedestrian

Damit ist das Routing nicht nur über das Sprachmodell erreichbar, sondern lässt sich unabhängig testen.

Das ist inzwischen ein Grundprinzip des Projekts.

Jede wichtige Funktion soll möglichst auch ohne LLM überprüfbar sein.

Wetterwarnungen kommen dazu

Das normale Wetter war bereits vorhanden.

Aber irgendwann stellte sich die Frage:

Was ist mit amtlichen Warnungen?

Gerade für einen Assistenten, der irgendwann morgens automatisch Informationen zusammenstellen soll, sind diese deutlich interessanter als die reine Temperatur.

Also kamen die Warnungen des Deutschen Wetterdienstes hinzu.

Später folgte zusätzlich MoWaS beziehungsweise NINA.

Damit kann eine Anfrage inzwischen beispielsweise so aussehen:

Jarvis: Zeige mir alle Warnungen für Zuhause

Und als Antwort können Informationen aus mehreren Quellen zusammengeführt werden:

Aktuelle amtliche Warnungen:

DWD:
Amtliche WARNUNG vor HITZE

MoWaS / NINA:
Geruchsbelästigung durch Brandrauch

Warnstufe: Gering
Gebiet: Rheingau Taunus Kreis

Wenn eine Warnung ein definiertes Ende besitzt, soll auch dieses in der Antwort auftauchen.

Das klingt nach einer kleinen Ergänzung.

Für spätere automatische Benachrichtigungen ist diese Information aber wichtig.

Der erste Schritt weg vom Terminal

Bis hierhin war die CLI der zentrale Einstiegspunkt.

Das ist für die Entwicklung sehr angenehm.

Langfristig sollen aber natürlich auch andere Geräte mit dem Core kommunizieren können.

Also bekam JARVIS einen HTTP Server.

Der Core ist damit nicht mehr ausschließlich über:

jarvis

erreichbar.

Anfragen können auch über eine API gestellt werden.

Damit tauchte allerdings direkt eine neue Frage auf:

Wie sichere ich die API ab?

Die Antwort für die erste Version sind Tokens.

Diese können direkt über die CLI erzeugt werden.

Zum Beispiel:

jarvis generate token

Und genauso wieder entfernt werden:

jarvis revoke token

Damit kann der Core weiterhin vollständig eigenständig betrieben werden.

Es ist keine zusätzliche Cloud und kein externer Authentifizierungsdienst erforderlich.

Einstellungen sollen später ebenfalls über die API erreichbar sein

Mit der API entstand direkt der nächste Gedanke.

Wenn später eine Weboberfläche existiert, möchte ich nicht jede Änderung per SSH in einer YAML Datei durchführen.

Also soll die API nach und nach auch Einstellungen verwalten können.

Zum Beispiel:

Ollama Server
Ollama Port
Ollama Modell
Zuhause
Arbeitsort
Atlas Server
Sprache
Zeitzone

Aktuell gibt es weiterhin eine globale Basiskonfiguration.

Langfristig sollen Einstellungen aber auch benutzerbezogen gespeichert werden können.

Denn sobald mehrere Benutzer auf dasselbe System zugreifen, hat natürlich nicht jeder denselben Kalender, dieselbe Heimatadresse oder dieselben Einstellungen.

Telegram wird zum ersten richtigen Client

Bevor ich eine komplette App oder Weboberfläche baue, gibt es allerdings bereits einen ziemlich praktischen Client:

Telegram.

Die Idee dahinter ist simpel.

Wenn JARVIS irgendwann selbstständig etwas mitteilen soll, brauche ich einen Kanal für Benachrichtigungen.

Zum Beispiel:

Für Zuhause besteht eine neue Unwetterwarnung.

Oder:

Dein erster Termin beginnt um 08:00 Uhr.
Aufgrund der Fahrzeit solltest du gegen 07:10 Uhr losfahren.

Oder später einfach der komplette Morgenbericht.

Deshalb läuft der Telegram Bot inzwischen als eigener Service:

jarvis-bot.service

Er befindet sich trotzdem im selben Core Projekt.

Das war eine bewusste Entscheidung.

Der Bot ist ein weiterer Zugriffskanal auf den Core und keine eigene KI Plattform.

Der Bot kann bereits angesprochen werden

Nach ein paar typischen Problemen mit Systemd und einem zunächst ungültigen Telegram Token lief schließlich auch der Bot.

Die Zugriffe können auf bestimmte Chat IDs beschränkt werden.

Damit reagiert der Bot nicht einfach auf jeden Benutzer, der ihn findet.

Für Tests gibt es eigene Befehle:

jarvis bot doctor
jarvis bot send

und natürlich den eigentlichen Bot Dienst.

Damit existiert erstmals ein Zugriff auf JARVIS, bei dem ich nicht direkt vor dem Terminal sitzen muss.

Das ist für die kommenden Funktionen ziemlich wichtig.

Der geplante Morgenbericht

Telegram ist gleichzeitig die Grundlage für eines der Features, auf das ich mich momentan am meisten freue.

Den Morgenbericht.

JARVIS soll zukünftig automatisch Informationen zusammenstellen wie:

Guten Morgen.

Heute werden etwa 23 °C erwartet.

Für deinen Wohnort liegen aktuell keine
Unwetterwarnungen vor.

Dein erster Termin beginnt um 08:30 Uhr.

Die aktuelle Fahrzeit beträgt ungefähr 47 Minuten.

Du solltest gegen 07:35 Uhr losfahren.

Dafür müssen mehrere der bisher unabhängig entwickelten Module zusammenspielen:

Kalender
   +
Wetter
   +
Warnungen
   +
Routing
   +
Benutzereinstellungen
   +
Telegram

Genau an diesem Punkt ergibt die bisherige modulare Architektur langsam Sinn.

Und dann kam Sprache

Ein JARVIS ohne Sprache fühlt sich natürlich irgendwann unvollständig an.

Also habe ich angefangen, mich mit STT und TTS zu beschäftigen.

STT steht für Speech to Text.

TTS steht für Text to Speech.

Die eigentliche Frage war allerdings nicht nur, welches Modell verwendet werden soll.

Viel wichtiger war die Architektur.

Soll jeder Sprachsatellit selbst Sprache erkennen und erzeugen?

Oder soll die komplette Verarbeitung zentral auf dem Server stattfinden?

Aktuell ist die Idee, dass der Core nicht direkt von einer bestimmten Hardware abhängig sein soll.

Ein Satellit kann Audio beziehungsweise Text an JARVIS übertragen und Antworten zurückbekommen.

Damit könnte später beispielsweise ein Raspberry Pi mit Mikrofon und Lautsprecher als Raum Satellit dienen.

Echtzeitkommunikation über WebSocket

Für Sprache reicht eine klassische REST Anfrage irgendwann nicht mehr aus.

Deshalb wurde zusätzlich eine Echtzeitkommunikation über WebSockets vorbereitet.

Damit kann ein Client dauerhaft mit JARVIS verbunden bleiben.

Ein zukünftiger Satellit könnte beispielsweise:

Mikrofon
   |
   v
STT
   |
   v
WebSocket
   |
   v
JARVIS Core
   |
   v
Antwort
   |
   v
TTS
   |
   v
Lautsprecher

verwenden.

Wo STT und TTS am Ende ausgeführt werden, kann je nach Hardware unterschiedlich sein.

Ein leistungsfähiger Satellit könnte einen Teil lokal erledigen.

Ein kleiner Satellit könnte die Arbeit dem Server überlassen.

Eine WebUI existiert inzwischen ebenfalls

Eigentlich wollte ich die Weboberfläche möglichst lange vermeiden.

Und grundsätzlich halte ich die Entscheidung vom ersten Tag immer noch für richtig.

Erst die Funktionen.

Dann die Oberfläche.

Inzwischen sind aber genügend Funktionen vorhanden, dass eine WebUI tatsächlich sinnvoll wird.

Sie dient aktuell vor allem zur Konfiguration und zum Testen.

Dazu gehören auch erste Echtzeittests für die WebSocket Verbindung.

Die WebUI ist trotzdem bewusst vom eigentlichen Core getrennt.

Das bedeutet:

WebUI
   |
   v
API
   |
   v
JARVIS Core

Der Core funktioniert weiterhin auch komplett ohne Oberfläche.

Das soll auch so bleiben.

Und das Sprachmodell?

Währenddessen läuft im Hintergrund weiterhin Ollama.

Bisher habe ich überwiegend mit:

llama3.2:3b

gearbeitet.

Dabei wird immer deutlicher, dass das Sprachmodell eigentlich nur einen Teil des Systems ausmacht.

Das Modell soll nicht meinen Kalender kennen.

Es soll keine Wetterdaten erfinden.

Und es soll auch keine Route schätzen.

Stattdessen entscheidet es, welche Werkzeuge für eine Anfrage benötigt werden.

Die eigentlichen Daten kommen aus den jeweiligen Diensten.

Im Prinzip also:

Benutzer
   |
   v
JARVIS
   |
   + Wetter
   + Kalender
   + Routing
   + Warnungen
   + weitere Tools
   |
   v
LLM für Interpretation und Antwort

Langfristig kann das Modell damit sogar austauschbar bleiben.

Was noch kommen soll

Mittlerweile existiert deshalb auch eine deutlich konkretere Roadmap.

Zu den nächsten größeren Schritten gehören Aufgaben und automatische Aktionen.

Also beispielsweise:

Morgenbericht
dynamische Warnungen
Terminerinnerungen
Abfahrtsbenachrichtigungen

Danach soll Home Assistant integriert werden.

Damit könnte der Assistent später auch auf Ereignisse im Smart Home reagieren oder Geräte steuern.

Ein weiteres geplantes Thema ist Medienwiedergabe über Plex.

Und später soll OpenClaw als zusätzliche Integrationsschicht dazukommen.

Der aktuelle Plan sieht grob so aus:

Version 0.5
Aufgaben und automatische Benachrichtigungen

Version 0.6
Home Assistant

Version 0.7
Plex und Musikwiedergabe

Version 0.8
OpenClaw

Bis dahin wird sich vermutlich noch einiges verändern.

Aber zum ersten Mal gibt es einen ziemlich klaren Weg.

Stand nach Tag 4

Wenn ich den aktuellen Stand mit dem ersten Tag vergleiche, ist überraschend viel passiert.

Inzwischen gibt es unter anderem:

  • eine lokale KI über Ollama
  • Wetterdaten
  • DWD Wetterinformationen
  • DWD Warnungen
  • MoWaS und NINA Warnungen
  • Nextcloud CalDAV
  • Kalenderabfragen
  • das Erstellen von Terminen
  • definierte Orte für Zuhause und Arbeit
  • Geocodierung über Dawarich Atlas
  • Routing über Valhalla
  • verschiedene Fortbewegungsarten
  • einen persistenten Speicher
  • eine Diagnosefunktion
  • eine HTTP API
  • Token Authentifizierung
  • vorbereitete benutzerbezogene Einstellungen
  • einen Telegram Bot
  • einen eigenen Telegram Service
  • erste Grundlagen für automatische Benachrichtigungen
  • STT und TTS Grundlagen
  • WebSocket Kommunikation für Echtzeitanfragen
  • erste Unterstützung für Sprachsatelliten
  • eine WebUI zum Konfigurieren und Testen
  • eine eigene Dokumentation
  • eine Roadmap für die kommenden Versionen

Das ist noch immer weit entfernt von dem JARVIS aus Iron Man.

Aber das war ehrlich gesagt auch nie das realistische Ziel.

Interessanter ist etwas anderes.

Am ersten Tag hatte ich im Grunde einen Python Prozess, der Wetterdaten anzeigen konnte.

Jetzt beginnen Kalender, Orte, Routing, Warnungen, Sprache, Telegram und KI langsam miteinander zu kommunizieren.

Und genau dadurch verändert sich das Projekt.

Es ist nicht mehr einfach nur:

Eine lokale KI mit ein paar Funktionen.

Langsam wird daraus tatsächlich ein persönlicher Assistent.

Oder besser gesagt:

eine Plattform für einen persönlichen Assistenten.

Und genau da möchte ich mit SVELNIK weitermachen.

Mal sehen, was davon am Ende wirklich funktioniert.

Denn genau deshalb habe ich dieses Projekt überhaupt angefangen.

Ich wollte wissen, wie viel von den beeindruckenden JARVIS Videos in sozialen Medien tatsächlich machbar ist, wenn man sich selbst hinsetzt und es baut.

Nach den ersten Tagen lautet meine Antwort:

Erstaunlich viel.

Aber der interessante Teil fängt vermutlich gerade erst an.