Förderjahr 2025 / Projekt Call #20 / ProjektID: 7913 / Projekt: IndeRun
IndeRun macht hybride KI-Anwendungen einfacher: KI-Aufgaben können lokal auf iOS, Android oder im Web ausgeführt werden – und wenn nötig kontrolliert auf die Cloud ausweichen. Mit Capability-Checks, Policy-basiertem Routing und Streaming entscheidet
In unserem letzten Beitrag haben wir mit IndeRun v0.1 erstmals eine nutzbare Version unseres Provider-Frameworks veröffentlicht. Damals stand vor allem das Fundament: ein gemeinsames API für unterschiedliche KI-Provider, einheitliche Verträge und die Möglichkeit, zur Laufzeit zwischen verschiedenen Ausführungswegen zu wählen.
Seitdem hat sich einiges getan. Aus dem Architekturkonzept ist inzwischen ein Framework geworden, das dieselbe KI-Aufgabe tatsächlich auf unterschiedlichen Plattformen lokal ausführen und – wenn erlaubt und notwendig – automatisch auf einen Cloud-Provider ausweichen kann.
Ein besonders wichtiger Anwendungsfall dabei sind hybride Apps mit Capacitor.
Eine Anfrage, unterschiedliche Ausführungswege
Stellen wir uns eine einfache Funktion vor: Eine App soll einen Text vereinfachen.
Aus Sicht der Anwendung soll dabei möglichst egal sein, wo das Sprachmodell tatsächlich läuft. Auf einem geeigneten Apple-Gerät kann beispielsweise Apple Foundation Models verwendet werden. Auf unterstützten Android-Geräten steht mit ML Kit GenAI beziehungsweise Gemini Nano ebenfalls ein lokaler Ausführungsweg zur Verfügung. Im Web können je nach Umgebung unter anderem browserseitige oder über ONNX eingebundene Modelle genutzt werden.
Falls lokale Ausführung nicht verfügbar ist, kann IndeRun – sofern die konfigurierte Policy das erlaubt – dieselbe Anfrage über einen OpenAI-kompatiblen Cloud-Provider ausführen.
Der Anwendungscode muss dafür nicht für jeden Provider neu geschrieben werden.
Genau diese Trennung zwischen Aufgabe und Ausführungsweg ist der Kern von IndeRun.
Lokale Ausführung ist eine Laufzeitentscheidung
Eine wichtige Erkenntnis aus der bisherigen Entwicklung ist, dass „On-Device unterstützt“ allein noch nicht ausreicht.
Ob ein Provider tatsächlich verwendet werden kann, hängt zur Laufzeit von mehreren Faktoren ab: vom Betriebssystem, vom konkreten Gerät, von der Verfügbarkeit des lokalen Modells, von Netzwerkverbindungen und gegebenenfalls von Zugangsdaten.
Deshalb besitzt IndeRun inzwischen eine Capability-Abfrage. Provider geben nicht nur an, was sie grundsätzlich unterstützen, sondern auch, ob sie in der aktuellen Umgebung tatsächlich verfügbar sind.
Die Routing-Logik arbeitet mit diesen Informationen und den Vorgaben einer Anfrage.
So kann eine Anwendung zum Beispiel festlegen:
- local_required: Die Daten dürfen das Gerät nicht verlassen. Ist kein lokaler Provider verfügbar, wird die Anfrage nicht ausgeführt.
- local_preferred: Lokale Ausführung wird bevorzugt, die Cloud darf aber als Fallback verwendet werden.
- cloud_allowed: Lokale und Cloud-Provider können verwendet werden.
- cloud_required: Die Anfrage soll ausschließlich über einen Cloud-Provider laufen.
Damit wird aus „On-Device oder Cloud“ keine hart codierte Entscheidung im Anwendungscode, sondern eine explizite Policy.
Fallback bedeutet nicht einfach „try/catch“
Besonders viel Arbeit steckt dabei in einem Detail, das auf den ersten Blick unspektakulär klingt: dem Fallback.
Wenn ein gewünschter Provider nicht verfügbar ist, soll IndeRun nicht einfach blind den nächsten ausprobieren. Zuerst wird geprüft, welche Provider die konkrete Aufgabe und den angeforderten Interaktionsmodus überhaupt unterstützen.
Provider können beispielsweise aufgrund von Datenschutzvorgaben, fehlender Konnektivität oder fehlenden Gerätefähigkeiten bereits vor der Ausführung ausgeschlossen werden.
Die Routing-Entscheidung ist dabei deterministisch. Für dieselbe Anfrage und denselben Capability-Zustand soll auch derselbe Provider beziehungsweise dieselbe Fallback-Reihenfolge entstehen.
Ebenso wichtig ist für uns, nachvollziehbar zu machen, warum ein Provider ausgewählt oder ausgeschlossen wurde. Gerade bei unterschiedlichen Geräten ist diese Transparenz beim Debugging entscheidend.
Streaming jetzt plattformübergreifend
Ein weiterer großer Schritt seit v0.1 ist Mode 2: Streaming.
Neben run() für klassische Request-Response-Aufgaben unterstützt IndeRun inzwischen auch stream(). Ergebnisse können damit inkrementell an die Anwendung geliefert werden.
Das betrifft nicht nur den Web-SDK. Die Streaming-Semantik wurde für Web, iOS und Android vereinheitlicht und auch in den Capacitor-Bridge integriert.
Dabei mussten einige Unterschiede zwischen den zugrunde liegenden Plattformen normalisiert werden. Manche Provider liefern einzelne Text-Deltas, andere Snapshots. Manche können eine laufende Generierung wirklich abbrechen, bei anderen kann IndeRun nur verhindern, dass nach einem Abbruch weitere Ergebnisse an die Anwendung weitergereicht werden.
Für die aufrufende App soll sich das trotzdem gleich verhalten.
Nach einem cancel() werden keine weiteren Events mehr ausgeliefert und der Lauf endet mit einem definierten terminalen Zustand. Diese Garantien werden zentral im IndeRun-Engine-Layer umgesetzt und nicht für jede Plattform erneut erfunden.
Warum wir Capacitor bewusst „dünn“ halten
Parallel zur Hauptbibliothek gibt es inzwischen das Paket @independo/capacitor-inderun.
Seine Aufgabe ist bewusst begrenzt.
Die Capacitor-Integration soll keine zweite IndeRun-Implementierung sein. Sie ist lediglich die Brücke zwischen JavaScript und den jeweiligen Plattform-SDKs:
- Im Browser wird der Web-SDK verwendet.
- Unter iOS delegiert die Bridge an den Swift-SDK.
- Unter Android delegiert sie an den Kotlin-SDK.
Routing, Provider-Auswahl, Fallback, Fehlerbehandlung und Streaming-Semantik bleiben in der eigentlichen IndeRun-Runtime.
Diese Trennung ist wichtig, weil sonst sehr schnell drei leicht unterschiedliche Implementierungen derselben Logik entstehen würden.
Mit der aktuellen Version unterstützt die Capacitor-Integration sowohl run() als auch stream(), kann die verfügbaren Provider über checkCapabilities() abfragen und nutzt auch im Web die dort konfigurierten lokalen Provider.
Damit können hybride Apps erstmals denselben IndeRun-Ausführungsweg über Web, iOS und Android verwenden.
Was aktuell bereits funktioniert
Der Schwerpunkt liegt weiterhin auf Text-zu-Text-Aufgaben.
Aktuell stehen unter anderem folgende Bausteine zur Verfügung:
- ein gemeinsamer Routing-Kern,
- Policy-basierte Provider-Auswahl,
- automatische Fallback-Ketten,
- Capability-Checks zur Laufzeit,
- ein OpenAI-kompatibler Cloud-Provider,
- Apple Foundation Models,
- Android ML Kit GenAI,
- ONNX Runtime für eigene lokale Modelle,
- browserseitige lokale Ausführungswege,
- run() für nicht-streamende Ausführung,
- stream() inklusive Abbruchsemantik,
- SDKs für TypeScript, Swift und Kotlin,
- sowie eine Capacitor-Integration für hybride Apps.
Die Hauptbibliothek ist derzeit bei Version 0.3.2, die Capacitor-Integration bei 1.1.0.
Beide Projekte sind Open Source und unter der MIT-Lizenz verfügbar.
Was noch nicht fertig ist
Trotz der Fortschritte ist IndeRun noch kein fertiges allgemeines KI-Framework.
Realtime-Sessions beziehungsweise der intern als Mode 3 bezeichnete bidirektionale Ausführungsmodus sind noch nicht umgesetzt. Nicht jeder lokale Provider unterstützt Streaming. Und natürlich ist lokale KI weiterhin stark von der tatsächlich vorhandenen Hardware und den jeweiligen Betriebssystemfunktionen abhängig.
Gerade diese Einschränkungen sind aber ein wichtiger Grund für das Projekt: Anwendungscode soll nicht selbst für jede Gerätegeneration herausfinden müssen, welche KI-Funktion gerade verfügbar ist und welchen Fallback er stattdessen verwenden soll.
Der nächste Engpass ist nicht mehr die Architektur
Zu Projektbeginn war unsere größte Frage, wie eine solche Abstraktion überhaupt sinnvoll aufgebaut werden kann.
Inzwischen hat sich der Engpass verschoben.
Die wesentlichen technischen Bausteine sind vorhanden. Jetzt geht es stärker darum, IndeRun für andere Entwickler verständlich, auffindbar und einfach ausprobierbar zu machen.
Dazu gehören ein klarerer Getting-Started-Pfad, bessere Beispiele und eine Referenzanwendung, die lokale Ausführung und Cloud-Fallback sichtbar demonstriert.
Außerdem wollen wir IndeRun stärker mit bestehenden Entwickler-Ökosystemen verbinden, statt zu erwarten, dass Anwendungen ihre gesamte bestehende KI-Schnittstelle ersetzen. Ein geplanter nächster Schritt ist deshalb eine Integration in den Vercel AI SDK Provider-Ansatz.
Unser Ziel bleibt dabei bewusst pragmatisch: IndeRun soll eine verlässliche technische Schicht für Anwendungen werden, bei denen lokale Verarbeitung, Offline-Fähigkeit, Datenschutz und kontrollierter Cloud-Fallback tatsächlich einen Unterschied machen.
Gerade in unseren eigenen barrierefreien Anwendungen können wir diese Anforderungen unter realen Bedingungen testen.
Die zentrale Frage lautet damit nicht mehr nur:
„Können wir dieselbe KI-Aufgabe auf unterschiedlichen Plattformen ausführen?“
Sondern zunehmend:
„Können Entwickler eine Funktion einmal bauen und IndeRun zuverlässig entscheiden lassen, wo sie auf dem jeweiligen Gerät am sinnvollsten ausgeführt wird?“
Genau daran arbeiten wir als Nächstes weiter.