Endlich souverän: So kommuniziert die Theia-IDE mit dem IONOS-Model-Hub

Seit den ersten Gehversuchen mit der Theia-IDE und dem Ionos-Model-Hub sind einige Tage vergangen. Das liegt unter anderem daran, dass andere Projekte dazwischen gekommen sind. So ist aus privaten Bedarf heraus, ein WordPress-Plugin entstanden, dass Reisestationen aus der beliebten Polarsteps-App in WordPress-Artikel verwandeln kann. Ein weiterer, gravierenderer Grund ist allerdings, dass die Lösung für das Problem mit dem „Bad Request“ aus dem letzten Blogartikel meiner KI-Reihe dann doch nicht so leicht zu lösen war, wie gehofft.

Nur mal eben die Theia-IDE kompilieren

Ein Grund, warum ich die Open-Source-Community so wertschätze, sind die Mitglieder eben dieser. Im Englischen als Contributor bekannt, sorgen Sie dafür, dass große und kleine Projekte am Leben bleiben. So auch in diesem Fall. Das GitHub-Issue, dass ich zu meinem Problem eröffnete hatte, erhielt bereits nach zwei Tagen eine erste Antwort. Leider war es zu diesem Zeitpunkt nicht einfach damit getan, den „developerMessageSettings“-Eintrag auf „system“ zu setzen. Allerdings, war die Antwort sehr dicht an der letztendlichen Lösung. Dazu später mehr.

Der nächste Schritt auf der Suche nach der Ursache, war der Hinweis auf eine Variante der Theia-IDE, in der ein erweitertes Logging der Kommunikation mit den OpenAI-Endpunkten aktiviert ist. Leider handelte es sich hier allerdings nur um einen GitHub-Branch, sprich einer angepassten Version der IDE, die nicht einfach installiert werden kann. Was folgte, war eine Reise quer durch den Alptraum Electron. Eine Electron-App ist im Kern eine Website, die in einem eigenen kleinen Browser (Chromium) läuft, aber wie ein normales Programm auf dem Computer erscheint. Entwickler nutzen dafür Web-Technologien wie HTML, CSS und JavaScript. Electron sorgt gleichzeitig dafür, dass die App Zugriff auf typische Betriebssystemfunktionen hat, etwa Dateien öffnen oder Benachrichtigungen anzeigen. So entsteht eine Anwendung, die sich wie eine echte Desktop-App anfühlt, obwohl sie technisch auf Web-Technik basiert. Dies ist auch der Grund dafür, warum die Theia-IDE relativ leicht als „echte“ Internetseite genutzt werden kann. Im Hintergrund setzt das Projekt auf NodeJS. Ähnlich wie andere Programmiersprachen erlaubt es NodeJS, Funktionen auf anderen Paketen für die eigene Anwendung zu nutzen. Da NodeJS ursprünglich ausschließlich für den Einsatz auf Servern gedacht war, arbeitet die Sprache teilweise recht eng mit dem Betriebssystem zusammen. Wenig überraschend, ließ sich die Theia-IDE also nicht direkt kompilieren. Stattdessen fand ich nach einigem Suchen im Internet heraus, dass ich noch folgende Pakete auf meinem Ubuntu-Laptop installieren musste:

sudo apt install libxkbfile-dev libsecret-1-dev

Zwar konnten hiernach alle Abhängigkeiten erfolgreich installiert werden, es kam aber zu weiteren Problemen. Genauer gesagt zwang das Kompilieren meinen Laptop aus Studenten-Zeiten in die Knie. Als ich den Laptop 2011 gekauft habe, war NodeJS gerade einmal zwei Jahre alt und acht Gigabyte noch mehr als genug. Nach einem Hinweis aus dem Github-Issue und einer „Vibe-Coding“-Session *schüttel* mit Google’s Gemini konnte ich durch folgende Änderungen an den Konfigurationsdateien der Theia-IDE doch noch ans Ziel gelangen und den Resourcen-Hunger von NodeJS bezwingen.

# examples/electron/package.json
 
 "scripts": {
    "bundle": "npm run rebuild && node --max-old-space-size=4096 ../../node_modules/.bin/theia build --mode development",
    "start": "theia start --no-sandbox --plugins=local-dir:../../plugins --ovsx-router-config=../ovsx-router-config.json",
# examples/electron/webpack.config.js

configs[0].cache = {
    type: 'filesystem',
};

configs[0].devtool = 'eval-cheap-module-source-map';

configs[0].optimization = {
    ...configs[0].optimization,
    minimize: false
};

Debugging der Kommunikation zwischen der Theia-IDE und der OpenAI-Schnittstelle von IONOS

Der Grund weshalb all dies nötig war, ist das diese Variante der Theia-IDE, sobald sie gestartet wurde, die Kommunikation zwischen sich selbst und einer OpenAI-Schnittstelle dokumentiert. Konkret zeigt sie dem Nutzer die HTTP-Anfrage und auch die -Antwort an, die das Programm an IONOS verschickt beziehungsweise empfängt. Auffällig hierbei war, dass nach der Anfrage, die den Fehler

400 litellm.BadRequestError: OpenAIException - Error code: 400 - {'object': 'error', 'message': '', 'type': 'BadRequestError', 'param': None, 'code': 400} Received Model Group=meta-llama/CodeLlama-13b-Instruct-hf Available Model Group Fallbacks=None

wirft, eine zweite Anfrage – ebenfalls an den IONOS-AI-Modelhub – gesendet wird, die erfolgreich ist. Nun galt es also herauszufinden, wo der Unterschied zwischen den beiden Anfragen lag. Zuerst nahm ich an, dass die Länge der Anweisung, die an das KI-Modell gesendet wurde, zu lang war und deshalb zu Problemen führte. Nach einigem Testen, erwies sich dies aber als Holzweg. Stattdessen, versteckte sich die Lösung – wie eingangs bereits erwähnt – doch im ersten Hinweis aus der GitHub-Diskussion: In der ersten Anfrage ist der „role“-Parameter auf „developer“ gesetzt, in der zweiten, erfolgreichen Anfrage hingegen auf „user“. Rollen werden in der OpenAI-API dazu genutzt, die Reihenfolge der Anfragen an das Modell zu priorisieren. Die erfolgreiche „user“-Rolle ist dabei weniger relevant, als die „developer“-Rolle. Diesem Forumbeitrag zufolge, werden Anweisungen in der „system“-Rolle – dem ursprünglichen Hinweis aus dem GitHub-Issue – seit einer API-Änderung Ende 2024 in die „developer“-Rolle überführt. Dies ist vermutlich auch der Grund, warum die erste Antwort nicht gleich die erhoffte Lösung brachte. Da sowohl die „system“- als auch die „developer“-Rolle bei Anfragen an den IONOS-AI-Modelhub zum „Bad Request“-Fehler führte, entschloss ich mich die Theia-IDE in den Einstellungen anzuweisen, anstelle der zwei Rollen, die „user“-Role zu verwenden.

{
   "ai-features.openAiCustom.customOpenAiModels": [
       {
           "model": "meta-llama/CodeLlama-13b-Instruct-hf",
           "url": "https://openai.inference.de-txl.ionos.com/v1",
           "id": "IONOS Code Llama 13b",
           "apiKey": "eyJ0eXAiOi...Rest...Des...Tokens...Des...KI-Nutzers...aus...dem...DCD...",
           "developerMessageSettings": "user"
       }
   ]
}

Und siehe da: HEUREKA! Der „universal“-Agent der IDE antwortete auf mein „Hallo“ mit einer Reihe von Dingen, die er für mich erledigen könnte. So einfach kann es manchmal sein.

Auf der Suche nach der Ursache – litellm im IONOS-AI-Modelhub

Ein Blick auf den ursprünglichen Fehlercode zeigt, dass anders als von mir zu erst angenommen nicht die Theia-IDE, sondern der IONOS-AI-Modelhub im Hintergrund auf das Projekt litellm setzt.

400 litellm.BadRequestError: OpenAIException - Error code: 400 - {'object': 'error', 'message': '', 'type': 'BadRequestError', 'param': None, 'code': 400} Received Model Group=meta-llama/CodeLlama-13b-Instruct-hf Available Model Group Fallbacks=None

Schaut man sich ein wenig im litellm-Repository auf GitHub um, so stößt man auf verschiedene Hinweise, die vom selben Fehler berichten, wenn auch in etwas anderer Form. Es ist also davon auszugehen, dass die litellm-Implementierung, die IONOS nutzt, derzeit wohl ähnliche Probleme plagt.

Fazit: Souveränität erfordert eben doch etwas Hingabe

Obwohl ich mich freue, dass ich jetzt mit meinem Projekt „Souveräne KI-getriebene Softwareentwicklung“ fortfahren kann, zeigt es einmal mehr, dass doch etwas Einsatz gefordert ist, wenn man sich von den großen US-Anbietern losreißen will. Für mich heißt dies nun leider auch, dass wir Oktober haben: Von jetzt an zahle ich also für die Anfragen an IONOS. Im Datacenter-Designer scheint es aber keine tagesaktuelle Abrechnung zu geben. Dies bringt mich zu einer meiner Eingangsfragen zurück: Wie lassen sich explodierende Kosten vermeiden? Die Antwort: litellm. Mehr dazu in meinem nächsten Beitrag.