11 Level-3-Tools: OpenHands und Aider
Bei selbststeuernden Autos gibt es fünf standardisierte Stufen (Level), die das Ausmaß der Unterstützung ausdrücken: assistiertes Fahren, teil-, hoch- und voll automatisiertes Fahren sowie vollkommen autonomes Fahren. Einige KI-Publikationen haben damit begonnen, dieses Konzept auf das autonome Coding zu übertragen (siehe Tabelle 11.1).
Level |
Beispiele |
Beschreibung |
---|---|---|
0 |
– |
menschliches Coding ohne KI-Unterstützung |
1 |
GitHub Copilot |
Code Completion: Vervollständigung von Code-Schnipseln |
2 |
ChatGTP |
Code Creation: zielgerichtete Programmierung ganzer Funktionen |
3 |
OpenHands, Aider |
Supervised Automation: menschliche High-Level- Anweisungen, die das KI-Tool in mehreren Schritten selbstständig ausführt; menschliche Kontrolle und Fehlersuche |
4 |
– |
Full Automation: wie oben, aber ohne die Notwendigkeit menschlicher Kontrolle |
5 |
– |
Full Autonomy: das KI-Tool setzt die Ziele selbst |
Tabelle 11.1 Verschiedene Stufen der KI-Unterstützung beim Coding
Aktuell gibt es noch keinen Standard für die Autonomie des KI-Codings. Je nach Quelle variieren die Level-Bezeichnungen und -Beschreibungen stark. Wir haben hier die Nomenklatur von »Levels of AGI for Operationalizing Progress on the Path to AGI« (2023) übernommen. Auch wenn unklar ist, ob sich diese Einteilung dauerhaft durchsetzen wird, erscheint sie uns für das Erste zweckmäßig:
https://arxiv.org/abs/2311.02462
https://sourcegraph.com/blog/levels-of-code-ai
Schon die Zuordnung von Werkzeugen wie GitHub Copilot oder ChatGPT in Level 1 und 2 ist problematisch: Natürlich können Sie Chat-basierte Tools auch für Level-1-Aufgaben verwenden und nur nach Code-Details fragen. Aber Chat-basierte Werkzeuge sind zunehmend in der Lage, relativ komplexe Prompts zu beantworten (»Erstelle ein minimales Framework für eine REST-API mit Python und Flask«). Umgekehrt kann GitHub Copilot viel mehr als nur Code Completion. Insofern liegen beide Tools (und viele andere KI-Werkzeuge mit ähnlichen Funktionen) irgendwo in der Schnittmenge zwischen Level 1 und Level 2. Die eigentliche Durchführung, also das Erstellen der Code-Dateien, bleibt aber in jedem Fall die Aufgabe des Menschen.
In diesem Kapitel wollen wir Ihnen zwei Software-Projekte vorstellen, die dem Level 3 entsprechen. Sie können OpenHands oder Aider beauftragen, ein konkretes Problem in einer Code-Datei zu beheben oder zur Realisierung einer neuen Funktion alle dafür erforderlichen Dateien einzurichten – am besten gleich samt Git-Commit. Ihre Anweisungen sind viel abstrakter als bei Level 1 und 2 – vergleichbar mit Arbeitsaufträgen an einen Junior Developer. Sie kümmern sich nicht um die Details der Durchführung. Sie hinterfragen also nicht jeden Variablennamen, jede Schleife etc. Sie testen den resultierenden Code aber. Sie brauchen immer noch Fachwissen, um die grundsätzliche Sinnhaftigkeit des Codes zu beurteilen, Fehler zu erkennen und klare Aufträge zu formulieren, wie der Code weiterentwickelt wird.
Schon an dieser Stelle wollen wir darauf hinweisen, dass OpenHands und Aider zwar großartige Werkzeuge mit viel Potenzial sind, dass sie aber alles andere als perfekt funktionieren. Erwarten Sie also keine Wunder! Dennoch halten wir dieses Kapitel für wichtig, weil es zeigt, in welche Richtung sich KI-Tools zum Coding gegenwärtig entwickeln. GitHub Copilot oder ChatGPT sind keineswegs das Ende der Fahnenstange!
KI-Tools, die den Leveln 4 oder 5 entsprechen, sind aus heutiger Sicht schwer vorstellbar. Level 4 wäre so, als würden der Firmenchef oder die Abteilungsleiterin das Entwicklungsteam (heute) bzw. ein KI-Werkzeug (in der Zukunft) beauftragen, ein neues Programm zu entwickeln, das bestimmte Aufgaben erfüllt. Die Firmenführung hat selbst keine Ahnung vom Programmieren, interessiert sich auch gar nicht, welche Sprache oder welches Framework eingesetzt werden. Entscheidend ist nur, dass die Kunden mit dem Produkt zufrieden sind. Aus Ihrer Sicht als Leserin oder Leser ist es sehr zweifelhaft, ob ein funktionierendes Level-4-Tool überhaupt wünschenswert ist: Es würde große Teile des IT-Arbeitsmarkts kollabieren lassen.
Bei Level 5 würde die KI auch die Aufgabenstellung übernehmen. Die KI wäre vielleicht für den Erfolg eine Software-Firma verantwortlich. Aufgrund von Kundenfeedback erkennt sie ein Problem und beauftragt dessen Lösung oder die Entwicklung einer neuen Komponente, die den Kunden die Bedienung erleichtert. Level 5 ist aktuell reine Science-Fiction.
11.1 OpenHands
OpenHands (ehemals OpenDevin) wird als Open-Source-Projekt mit der freien MIT-Lizenz auf GitHub entwickelt. Mitte 2024 ist die aktuelle Version 0.9 erschienen; die Community ist sehr aktiv, wovon auch 31.200 GitHub-Sterne zeugen.
Abbildung 11.1 Die GitHub-Seite von OpenHands
Im Unterschied zu den bisher vorgestellten Arbeitstechniken mit KI-Assistenten kann OpenHands auf das Dateisystem zugreifen und dort Dateien und Ordner verwalten (sofern Sie diesen Zugriff gewähren).
Was sich im ersten Moment nur nach einer Kleinigkeit anhört, hat großes Potenzial: Das KI-Tool kann so ganze Projekte verwalten, Dateien anlegen und selbstständig Programme kompilieren. Ihr KI-Assistent wäre nicht mehr auf Chat oder Hinweise in der IDE beschränkt, sondern könnte eigenständig arbeiten.
Beispielsweise ist es in Kombination mit Docker-Containern möglich, den erzeugten Quellcode in einer sicheren Umgebung auszuprobieren und zu verbessern. Sie sehen schon, wo die Reise hingeht: Wird zum Beispiel ein Fehler beim Kompilieren einer Datei gefunden, kann die KI-Software anhand der Fehlermeldung versuchen, das Problem automatisch zu beheben. Für jeden Schritt erstellt OpenHands einen Prompt, der an ein LLM gesendet wird. Die Antwort wird analysiert und gegebenenfalls in Kommandos umgesetzt.
Auf diese Weise könnten Befehle an die KI-Assistenten auf einer abstrakteren Ebene gestellt werden. Anstatt dass Sie die einzelnen Schritte selbst abarbeiten, könnten Sie auch fordern, dass beispielsweise eine React-App erstellt wird, die PDFs anzeigt. Ihr KI-Assistent soll dann selbstständig die notwendigen Pakete installieren, die Ordnerstruktur und die Dateien anlegen, den Webserver starten, Test-User anlegen und die API mit curl testen usw.
Wir haben dies im Abschnitt 11.2, »OpenHands in der Praxis«, ausprobiert und testen, ob OpenHands selbstständig eine kleine Webanwendung mit ein paar Benutzern anlegen kann.
Das richtige Sprachmodell (LLM) für OpenHands
Beim Ausprobieren von OpenHands erzeugen Sie potenziell sehr viele Anfragen an ein Sprachmodell. Wenn Sie dazu einen Cloud-Provider verwenden, kann das schnell teuer werden (wir sprechen aus Erfahrung). OpenHands unterstützt auch lokale LLMs, aber unsere Versuche mit llama3.1, codegemma oder deepseek-coder waren sehr enttäuschend. Allesamt lieferten sie keine brauchbaren Ergebnisse. Mit proprietären Modellen wie gpt-4o (die Standard-Einstellung bei OpenHands) konnten wir kleine Erfolge erzielen, die wir Ihnen hier vorstellen möchten.
Installation
Damit Sie das volle Potenzial von OpenHands ausschöpfen können, muss das Programm auch Software installieren können. Soll OpenHands zum Beispiel Software in der Sprache Go erstellen und testen, benötigt es dazu den Compiler und die Go-Module, die dieses Programm verwendet. Würden diese Komponenten bei jedem Versuch auf dem Betriebssystem Ihres Computers installiert werden, so wäre Ihr Computer bald ziemlich verunstaltet.
Docker-Container bieten hier eine ideale Lösung: OpenHands darf in einem Sandbox-Container quasi machen, was es will. Wenn Sie OpenHands beenden, wird der Container (mit all der installierten Software) gelöscht. Das Arbeitsverzeichnis, in dem der von Ihnen gewünschte Code erstellt wird, bleibt dabei natürlich erhalten. Wir gehen im Weiteren davon aus, dass Sie grundlegende Erfahrung mit Docker haben und dieses auf Ihrem Computer installiert haben. Außerdem sollten Sie ein Terminal-Fenster verwenden, in dem eine gängige Unix-Shell (zum Beispiel bash oder zsh) läuft. Unter Linux und macOS sollte das kein Problem sein, unter Windows müssen sie dazu WSL mit einem Linux-System verwenden.
Der Start der aktuellen OpenHands-Version gelingt wie folgt:
WORKSPACE_BASE=$(pwd)/workspace
docker run -it \
--pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=\
ghcr.io/all-hands-ai/runtime:0.9-nikolaik \
-e SANDBOX_USER_ID=$(id -u) \
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
-v $WORKSPACE_BASE:/opt/workspace_base \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app-$(date +%Y%m%d%H%M%S) \
ghcr.io/all-hands-ai/openhands:0.9
Beachten Sie, dass dabei im aktuellen Verzeichnis ein Ordner workspace erstellt wird, in dem Ihre neue Software entwickelt wird. Sollte dieser Ordner schon vorhanden sein, wird er samt den vorhandenen Inhalten eingebunden. Sie können dieses Verzeichnis ändern, indem Sie die Variable WORKSPACE_BASE in der ersten Zeile anpassen.
Das Einbinden des Sockets /var/run/docker.sock erlaubt dem Container, den Docker-Daemon zu kontrollieren. OpenHands benötigt diese Einstellung, damit der Sandbox-Container von der Anwendung gestartet werden kann. Die Kontrolle des Docker-Daemon gibt dem Container aber auch Zugriff auf alle anderen Docker-Ressourcen auf Ihrem Computer. Starten Sie OpenHands also nicht auf einem System, auf dem wichtige Docker-Anwendungen produktiv laufen.
Beim Start wird ein Container von dem aktuellen Docker-Image abgeleitet, dem der Name openhands-app-XXXXX zugewiesen wird, wobei XXXXX mit dem aktuellen Datum und der Uhrzeit ersetzt wird. Durch diese Namensgebung wird sichergestellt, dass Sie den Container eines abgebrochenen Versuchs später leicht wiederfinden. Der Container enthält alle Log-Dateien, die während des Versuchs angelegt wurden, was für eine Analyse praktisch sein kann.
Die Web-Applikation läuft anschließend auf http://localhost:3000. Der Sandbox-Container wird automatisch gestartet, sobald Sie die Web-Oberfläche laden, und mit dem Namen openhands-sandbox-YYYYY versehen, wobei YYYYY für eine zufällig erzeugte, einmalige ID steht. Nach dem erfolgreichen Start können Sie sich die beiden Container mit dem Docker-Sub-Kommando ps anzeigen lassen (die Ausgabe wurde wegen der langen Namen speziell formatiert):
> docker ps --format '{{.Image}} {{.Names}}'
ghcr.io/all-hands-ai/runtime:0.9-nikolaik openhands-sandbox...
ghcr.io/all-hands-ai/openhands:0.9 openhands-app-20240910163059
Die Web-Oberfläche
Sobald Sie die Installation erfolgreich absolviert haben, können Sie mit der Anwendung von OpenHands starten. Dazu öffnen Sie in Ihrem Web-Browser die Adresse http://localhost:3000 mit der Web-Oberfläche von OpenHands.
Im linken Teil entsteht der Chat mit OpenHands. Hier geben Sie Ihre Anforderungen ein, und OpenHands erklärt die Schritte, die ausgeführt werden. Im rechten oberen Teil des Browser-Fensters können Sie den erzeugten Code (und etwaige andere Dateien und Ordner) ansehen. Darunter steht ein interaktives Terminal zur Verfügung, von dem auch OpenHands selbst Gebrauch macht. Es handelt sich um eine Shell im Sandbox-Container.
Abbildung 11.2 Die Web-Oberfläche von OpenHands gibt es aktuell nur im »Dark-Mode«
Damit OpenHands Ihre Anweisungen abarbeiten kann, müssen Sie zunächst das Sprachmodell (LLM) und den Agent konfigurieren, wobei der Agent die Kommunikation zwischen dem LLM und der restlichen Software übernimmt. Der entsprechende Konfigurationsdialog erscheint beim ersten Aufruf der Web-Oberfläche und kann jederzeit erneut über das Schraubensymbol rechts unten aufgerufen werden.
Abbildung 11.3 Die Standard-Konfigurationseinstellungen von OpenHands
Um das voreingestellte Modell gpt-4o von OpenAI zu verwenden, müssen Sie den API-Key angeben, den Sie zuvor in den Einstellungen Ihres OpenAI-Accounts angelegt haben (siehe Kapitel 10, »Code automatisiert verarbeiten«). Als Agent für das Modell gpt-4o dient der voreingestellte CodeActAgent.
Womit wir beim Thema lokale LLMs wären: Wie bereits erwähnt, waren unsere Erfolge mit lokalen Sprachmodellen äußerst überschaubar. Auch die Online-Hilfe von OpenHands bestätigt diese Beobachtung und verweist auf die Modelle GPT-4 und Claude 3 als derzeit beste Partner für OpenHands.
Vielleicht hat sich diese Situation gebessert, wenn Sie das Buch in Händen halten, und Sie möchten auch der kostengünstigeren Variante mit lokalen Modellen eine Chance geben. OpenHands unterstützt die API von Ollama, die wir schon im Abschnitt 9.3, »Ollama«, vorgestellt haben. Damit der Zugriff auf Ihre lokalen Ollama-Modelle funktioniert, müssen Sie beim Start des Containers die Variable LLM_BASE_URL setzen:
docker run \
...
-e LLM_BASE_URL="http://host.docker.internal:11434" \
...
ghcr.io/all-hands-ai/openhands:0.9
Sollte ollama nicht auf Ihrem lokalen Computer laufen, sondern auf einem Computer im LAN (wie es bei unseren Versuchen der Fall war), dann tragen Sie statt host.docker.internal den DNS-Namen des Computers ein, auf dem der Dienst läuft. Vergewissern Sie sich, dass der openhands-app-Container Zugriff auf den Port 11434 auf diesem Computer hat und keine Firewall dazwischenfunkt. Sie können dann im Konfigurationsdialog unter Model die Zeichenkette ollama/llama3.1 eingeben (wenn Sie das LLM llama3.1 von Ihrer lokalen Installation verwenden möchten). Beachten Sie, dass ein Umschalten auf ein Modell eines Cloud-Providers, wie gpt-4o von OpenAI, nur dann gelingt, wenn Sie den Container neu starten und die Variable LLM_BASE_URL nicht definieren.
Bei unseren Versuchen empfanden wir die Fehlermeldungen im Browser-Chat als nicht sehr hilfreich. OpenHands gibt hier wenig technische Fehlermeldungen aus, was oft zu sehr verkürzten, generischen Meldungen führt. Viel hilfreicher war die Log-Ausgabe im Terminal-Fenster, in dem wir den Docker-Container gestartet hatten. Diese Meldungen sind sehr detailliert und geben in der Regel schnell Auskunft über das eigentliche Problem. Hier ein Ausschnitt aus dem Logfile der nachfolgenden Python-Web-Applikation:
CodeActAgent LEVEL 0 LOCAL STEP 13 GLOBAL STEP 13
06:37:31 - openhands:INFO: llm.py:486 - Cost: 0.04 USD |
Accumulated Cost: 0.43 USD
Input tokens: 7757
Output tokens: 53
06:37:31 - ACTION
**CmdRunAction (source=EventSource.AGENT)**
THOUGHT: Let's use `netstat` to find the process using port 5000
and then kill it.
First, let's find the process ID (PID) using port 5000.
COMMAND:
netstat -tuln | grep :5000
06:37:31 - openhands:INFO: runtime.py:359 - Awaiting session
06:37:31 - openhands:INFO: runtime.py:263 -
------------------------------Container logs:--------------------
|INFO: 172.17.0.1:53856 - "GET /alive HTTP/1.1" 200 OK
|INFO: 172.17.0.1:53856 - "POST /execute_action HTTP/1...
-----------------------------------------------------------------
06:37:31 - openhands:INFO: session.py:139 - Server event
06:37:31 - OBSERVATION
**CmdOutputObservation (source=EventSource.AGENT, exit code=1)**
bash: netstat: command not found
[Python Interpreter: /openhands/poetry/openhands-ai-5O4_aCHf-p...
openhands@200f871dd6cf:/workspace $
06:37:31 - openhands:INFO: session.py:139 - Server event
Behalten Sie daher immer das Terminal-Fenster mit diesen Log-Meldungen im Blickfeld, wenn Sie mit OpenHands experimentieren.