11.2 OpenHands in der Praxis
Als erste Aufgabe soll unser künstlicher Junior-Software-Entwickler eine Web-Applikation mit einer sehr einfachen Benutzerverwaltung erstellen. Das Backend soll in Python programmiert sein, und die Benutzer sollen in einer SQLite-Datenbank gespeichert werden. Eine Webseite dient zur Verwaltung der Benutzer: Hier können neue Benutzer hinzugefügt und bestehende gelöscht oder verändert werden.
Prompt: Create a JSON REST-API backend using python. Add a route health which responds with HTTP status code 200.
Diese Aufgabe ist für ein mächtiges Modell wie gpt-4o natürlich ein Kinderspiel. Folgende Schritte führt OpenHands aus und kommt dabei nur leicht ins Straucheln:
-
Die Datei app.py wird erstellt. Sie enthält den HTTP-Endpunkt für /health und setzt den Webserver-Port auf 5000.
-
Mit dem Kommando python3 /workspace/app.py wird der Server als Hintergrundprozess gestartet.
-
Der Aufruf curl http://localhost:5000/health scheitert mit der Fehlermeldung Failed to connect to localhost port 5000.
-
Mit dem Kommando lsof -i :5000 versucht OpenHands, zu prüfen, ob der Serverprozess auf Port 5000 läuft. Auch dieses Kommando scheitert, da lsof nicht in dem Sandbox-Container installiert ist.
-
Da die Schritte 3 und 4 so schnell hintereinander ausgeführt wurden, fand sich noch keine Fehlermeldung für den gescheiterten Serverstart aus Schritt 2 im Logfile. Erst jetzt taucht der Fehler ModuleNotFoundError: No module named 'flask' auf.
-
OpenHands behebt das Problem mit der Installation des Python-Moduls.
-
Der neuerliche Aufruf von curl liefert das erwartete Ergebnis, und OpenHands gibt die Kontrolle an den Benutzer zurück.
Nach 7 Schritten und 0,05 $ Kosten ist die erste Aufgabe erfüllt. Ein menschlicher Programmierer hätte den Fehler mit der fehlenden Modul-Installation wohl gar nicht erst gemacht und, wenn doch, das Problem sofort nach dem Server-Start bemerkt.
OpenHands soll die Anwendung jetzt um eine einfache Benutzerverwaltung mit einer Datenbank im SQLite-Format erweitern.
Prompt: Add code for a simple user administration, where users are stored in a sqlite database.
Nach mehreren Fehlern, die OpenHands aber allesamt selbst beheben kann, gibt es zwei weitere Routen zu unserem Backend: Einmal kann die Liste aller Benutzer mit GET abgerufen werden. Die zweite Route dient zum Erstellen neuer Benutzer mit POST. Wir sind inzwischen bei 28 Schritten und Kosten von 0,29 $ angekommen.
Als Nächstes möchten wir ein Web-Frontend für die Anwendung haben:
Prompt: Add a web frontend where I can add a user to the database.
Die Eingabemaske auf der sehr schlichten HTML-Seite verwendet JavaScript ohne zusätzliche Bibliotheken, was ganz in unserem Sinn ist. Beim Abschicken des Formulars wird die Funktion fetch verwendet, um die eingegebenen Daten an das Backend zu schicken. Außerdem erweitert OpenHands das Backend, damit die Webseite unter der Adresse http://localhost:5000/ ausgeliefert werden kann.
Wir brauchen nun aber auch noch einen Weg, um die Benutzer zu löschen oder zu bearbeiten.
Prompt: Add code for deleting and editing users.
OpenHands kümmert sich hierbei nur um das Backend und fügt die Routen mit den HTTP-Methoden DELETE und PUT hinzu. Anschließend wird der DELETE-Aufruf mit einer nicht existierenden Benutzer-ID getestet, was zu einer Fehlermeldung führt. OpenHands wertet das offenbar als erfolgreichen Test und meldet stolz, dass der Code hinzugefügt wurde und getestet ist. Inzwischen sind 48 Schritte abgearbeitet, und wir haben 0,59 $ ausgegeben. Der fehlende Frontend-Code wird in nur einem Schritt ergänzt. Da hier mehr Tokens anfallen, kostet dieser Schritt auch etwas mehr.
Prompt: Add frontend code so that I can see a list of all users with edit and delete buttons.
Abschließend wollen wir noch ein paar Beispiel-Benutzer anlegen lassen, damit wir die Applikation ausprobieren können.
Prompt: Insert 5 example users.
OpenHands ruft dazu fünfmal die REST-API mit curl und Test-Benutzerdaten auf, wobei jeder Aufruf 0,02 $ kostet. Gut zu wissen, wenn Sie zum Beispiel 10.000 Test-User hinzufügen wollen.
Abbildung 11.4 Die »fertige« Web-Applikation mit einer Liste von Benutzern
Jetzt werden Sie mit Recht sagen, dass man für dieses einfache Beispiel auch ChatGPT oder einen anderen Chatbot im Browser verwenden kann. Immerhin bekommt man auch dabei präzise Anweisungen, welche Dateien und Ordner erstellt werden müssen.
Nicht zu viel auf einmal!
Eigentlich hätten wir Ihnen hier gerne ein vollständiges Beispiel mit einem Prompt in dieser Form präsentiert:
Prompt: Create a backend JSON-REST-API in golang with a simple user administration. Users should have Email, Name, Password and get stored in a sqlite database. Add a frontend in vue.js where I can add, edit and delete users.
Die erste Reaktion von OpenHands ist vielversprechend: Es wird ein Plan vorgestellt, in dem zuerst das Backend inklusive Datenbank und anschließend das Frontend erzeugt werden soll. Aber schon die Initialisierung des Go-Moduls schlägt fehl. Bei mehrfachen Versuchen, das Problem zu beheben, wird der Ordner für das Go-Modul verschachtelt unterhalb des letzten Versuchs erstellt. Beim Frontend-Code war das Ergebnis leider auch nicht besser.
OpenHands brach nach 37 Minuten und 60 Schritten ohne irgendein nennenswertes Ergebnis ab. Weder bei dem gewünschten Backend in Go noch bei dem Frontend gab es verwertbaren Code. Nachdem das nicht unser erster Versuch war, der so kläglich scheiterte, konnten wir die Zeit wenigstens für die Mittagspause nutzen.
Fazit
Als wir mit der Arbeit an den Abschnitten zu OpenHands starteten und das technische Konzept dahinter zu verstehen begannen, waren unsere Erwartungen sehr hoch gesteckt. Die Faszination, wie gut ein LLM mit natürlicher Sprache und auch mit Programmiersprachen umgehen kann, trugen seinen Teil dazu bei. Die Ernüchterung folgte aber auf den Fuß, und das Scheitern von OpenHands an banalen Dingen, wie zum Beispiel einem falschen Pfad in der Ordnerstruktur, lassen uns doch mit großen Zweifeln an einer raschen Umsetzung eines autonomen Software-Ingenieurs zurück.
Nichtsdestotrotz bietet OpenHands einen sehr spannenden Ausblick, wie ein Teil der Software-Entwicklung in Zukunft funktionieren könnte. Es handelt sich um ein noch sehr junges Projekt, das vor allem von der Weiterentwicklung der Sprachmodelle massiv profitieren wird.
Am meisten enttäuscht hat uns die große Diskrepanz zwischen lokalen Modellen und den Modellen von OpenAI: Während lokale Modelle bei Code-Vervollständigung oder als Chat-Bot, wie wir es in anderen Kapiteln in diesem Buch vorgestellt haben, durchaus brauchbare Ergebnisse erzielen, war das bei OpenHands leider nicht der Fall. Wenn effiziente Software-Entwicklung in Zukunft nur mehr mit einem Zugang zu einem der Tech-Giganten möglich ist (inklusive der unvermeidbaren Datenüberwachung), dann wäre das für uns eine sehr traurige Entwicklung.