Agentische Coding-CLIs: Loops, Kontext und Berechtigungen
Was ein agentisches Coding-CLI wirklich funktionieren lässt: Tool-Call-Loops, Kontextverwaltung, Berechtigungsmodelle und Client/Server-Design im Praxischeck.

Das Modell ist der einfache Teil. Das zumindest behaupte ich, und nachdem ich in den letzten Jahren dabei zugesehen habe, wie ein Dutzend agentischer Coding-CLIs aufgestiegen, geforkt und gestolpert ist, halte ich das für richtig: Ein agentisches Coding-CLI steht oder fällt mit seinem Harness, nicht mit seinem Modell. Der Release von OpenCode 2.0 – ein Open-Source-Coding-Agent für das Terminal, der diese Woche ordentlich an Fahrt aufgenommen hat – ist ein guter Anlass, das laut auszusprechen. Die interessanten Neuerungen in diesem Release sind keine neuen Modellintegrationen. Es geht um eine Trennung in Client und Server, Plugins mit Hot-Reloading, im Hintergrund laufende Tasks und eine neu aufgebaute Agent-Loop. Also Infrastruktur, kurz gesagt. Die Infrastruktur ist das Produkt.
Ich bin ein ehemaliger ML-Engineer, deshalb hat mich diese Schlussfolgerung zunächst geärgert. Ich hätte gern gehabt, dass die Modellqualität den Unterschied macht. Wenn ich mir aber anschaue, warum ich solche Tools behalte oder wieder aufgebe, lautet die Antwort nie „Das Modell ist klüger geworden“. Sondern eher: „Das Tool fragt mich nicht mehr bei jedem einzelnen Befehl nach einer Freigabe“, oder „Es lädt meine Konfiguration endlich ohne Neustart neu“, oder „Ich kann eine GUI an eine Session auf einem entfernten Rechner anhängen“. Schauen wir uns deshalb die drei Subsysteme genauer an, die bestimmen, ob ein Coding-Agent nützlich ist: die Tool-Call-Loop, die Kontextverwaltung und das Berechtigungsmodell. Danach gestehe ich ein, wo die provokante These an ihre Grenzen stößt.
Die Tool-Call-Loop ist ein verteiltes System
Zieht man das Marketing ab, ist jeder Coding-Agent im Kern dasselbe Programm: Man ruft das Modell mit einem Prompt und einer Liste von Tools auf, bekommt entweder Text oder einen Tool-Call zurück, führt das Tool aus, hängt das Ergebnis an und wiederholt das Ganze. Das klingt trivial. Ist es aber nicht, und Tools, die die Schleife als trivial behandeln, fühlen sich schon nach fünf Minuten echter Nutzung klapprig an.
Überlegen wir, womit die Loop tatsächlich umgehen muss. Tool-Ausführungen scheitern: Der Compiler wirft Fehler, die Test-Suite hängt, die Datei existiert unter diesem Pfad gar nicht, weil das Modell sie halluziniert hat. Das Modell erzeugt fehlerhaftes JSON für die Tool-Argumente. Ein Tool-Call dauert vierzig Sekunden, und der Nutzer drückt mitten im Lauf Escape. Zwei Tool-Calls kommen in einer Runde an, und einer von beiden darf nicht laufen, wenn der andere fehlschlägt. Das Kontextfenster füllt sich mitten in der Aufgabe, und irgendetwas muss nachgeben. All das sind Probleme von Nebenläufigkeit und Fehlerbehandlung, keine Intelligenzprobleme. Ich habe schon früher argumentiert, dass LLM-Agenten nichts anderes als verteilte Systeme sind, und das Coding-CLI ist dafür das reinste Beispiel: Eine unzuverlässige, nicht deterministische Remote-Komponente (das Modell) koordiniert sich mit lokalen, wirksamen Komponenten (Shell, Dateisystem, LSP), und die Loop ist das Konsensprotokoll zwischen ihnen.
Deshalb ist es relevant, dass OpenCode 2.0 seine Loop Berichten zufolge auf Basis von Effect neu aufgebaut hat, einem TypeScript-Framework für strukturierte Nebenläufigkeit und typisierte Fehler. Diese Entscheidung zeigt, dass das Team die Loop nicht mehr als „while-Schleife mit fetch darin“ betrachtet, sondern als das, was sie ist: ein System aus unterbrechbaren, kombinierbaren, wiederholbaren Effekten mit expliziten Fehlerkanälen. Wenn die Agent-Loop echte Abbruchsemantik hat, wird „Nutzer drückt Escape“ zu einem Ereignis erster Klasse statt zu einem korrumpierten Zustand. Sind Tool-Ergebnisse typisiert, kann man die Ausgabe des Modells validieren, bevor etwas ausgeführt wird. Das passt gut zu Techniken wie Constrained Decoding, bei denen man den Ausgaberaum des Modells einschränkt, sodass fehlerhafte Tool-Calls unmöglich werden und nicht bloß abgefangen werden.
Client/Server ist das Feature, das niemand bewirbt
Eine der folgenreichsten Designentscheidungen eines Coding-CLIs ist, ob der Agent ein Prozess oder ein Dienst ist. Das naive Design – ein Prozess, ein Terminal, und die Session stirbt mit dem Terminal – war der Ausgangspunkt der meisten dieser Tools, und es ist eine Decke, an die man stößt. Das Client/Server-Modell von OpenCode, bei dem ein langlebiger Server die Sessions besitzt und beliebig viele Clients (TUI, Desktop-App, Web-UI) sich daran anhängen, zieht diese Decke ein. In der Praxis heißt das: Die Session überlebt das Schließen des Terminals, man kann den Agenten auf einem entfernten Dev-Rechner laufen lassen und von einer nativen App auf dem Laptop steuern, und mehrere Oberflächen können dieselbe Session beobachten.
Wer schon einmal versucht hat, einen Agenten über SSH auf einer VM laufen zu lassen, und die Session dann durch einen Reconnect verloren hat, weiß, dass das keine nette Zugabe ist. Es ist der Unterschied zwischen Spielzeug und Infrastruktur. Langlaufende Agenten gehören in dieselbe Kategorie wie Builds und Test-Suiten: Dinge, die man startet, liegen lässt und später wieder nachsieht. Die im Hintergrund laufenden Tasks von OpenCode 2.0 gehen in dieselbe Richtung: Der Agent hört auf, eine synchrone Unterhaltung zu sein, und wird zu einem Job-Runner mit Chat-Oberfläche.
Nun der Haken, denn ich vertrete diese Meinung konsequent: Eine Server-Architektur bedeutet nicht zwingend einen dauerhaften Daemon. Mehrere Kommentatoren haben mit Argwohn angemerkt, dass plötzlich jedes Agent-Harness einen dauerhaften Hintergrundprozess auf dem eigenen Rechner haben will. Dieses Bauchgefühl ist richtig. Ich habe schon geschrieben, dass CLI-Tools standardmäßig keine Hintergrund-Daemons installieren sollten, und dazu stehe ich. Es gibt eine saubere Mittellösung: den Server bei Bedarf starten, auf das Projektverzeichnis beschränken und beenden, sobald der letzte Client die Verbindung trennt. So bekommt man Session-Persistenz und Multi-Client-Anbindung, ohne dass ein immer aktiver Prozess vom eigenen Rechner nach Hause funkt. Dass OpenCode die Konfiguration aus dem Ordner der Session lädt und nicht aus dem Arbeitsverzeichnis des Servers – eine weitere Änderung in 2.0 –, zeigt, dass das Team verstanden hat: Der Server sollte dem Projekt folgen, nicht umgekehrt.
Die Kontextverwaltung entscheidet über die Qualität
Frag jemanden aus der Praxis, warum ein Agent nach einer Stunde Arbeit „dumm geworden“ ist, und die Antwort ist fast nie eine Modellregression. Es ist Context Rot. Das Fenster ist voll mit veralteter Tool-Ausgabe, Sackgassen und dem vollständigen Text von Dateien, die vor vierzig Runden relevant waren. Das Modell trifft Entscheidungen in einem Heuhaufen, und die Trefferquote beim Wiederfinden von Details sinkt lange, bevor man das nominelle Token-Limit erreicht.
Ein gutes Harness behandelt den Kontext als Budget mit einer Zuteilungsstrategie, nicht als Rohrleitung. Konkret bedeutet das mehrere Dinge, die zusammenspielen:
- Kürzung von Tool-Ausgaben mit Rückholmöglichkeiten. Ein Testlog mit 5.000 Zeilen sollte nur als die vierzig fehlgeschlagenen Zeilen plus einem Hinweis in den Kontext gelangen, dass das vollständige Log unter einem Pfad liegt, den das Modell erneut lesen kann. Das Harness entscheidet, was relevant ist; das Modell entscheidet, wann es mehr braucht.
- Unter-Sessions und Sub-Agenten. „Schau nach, wie Auth in diesem Repo funktioniert, und berichte zurück“ sollte in einem isolierten Kontext laufen, der eine Zusammenfassung liefert statt des gesamten Explorationsprotokolls. Die verbesserte Kommunikation zwischen Unter-Sessions in OpenCode 2.0 setzt genau diese Idee um.
- Komprimierung, die die Absicht bewahrt. Wenn das Fenster voll wird, muss die bisherige Unterhaltung zusammengefasst werden. Ein Harness, das naiv zusammenfasst, verliert mit dem Rauschen auch die Vorgaben des Nutzers („Finger weg vom Billing-Modul“). Gute Komprimierung behält Entscheidungen und Vorgaben wörtlich und verdichtet nur die Erzählung.
- Konfiguration und Skills als Kontext, nicht als Code. Projektweite Anweisungen, Plugin-definierte Tools und Skill-Dateien belegen alle Platz im Fenster. Dass sie per Hot-Reload aktualisiert werden – ebenfalls eine Neuerung in 2.0 –, ist wichtig, weil man das Verhalten des Agenten nur iterativ verbessern kann, wenn man seinen Kontext ändern kann, ohne die Session neu zu starten.
Nichts davon ist Modellintelligenz. Aber alles davon bestimmt, wie intelligent das Modell wirkt. Ein Frontier-Modell mit einer schlampigen Kontextstrategie verliert bei jeder Aufgabe, die länger als zwanzig Minuten dauert, gegen ein günstigeres Modell hinter einer disziplinierten Strategie.

Berechtigungsmodelle: Das unscheinbare Feature, das über die Einführung entscheidet
Hier eine Frage aus der HN-Diskussion, die ich für die wichtigste Produktfrage in diesem Bereich halte: Gibt es irgendetwas zwischen „jeden Befehl freigeben“ und dem Yolo-Modus? Vollautomatische Freigabe ist ernsthaft gefährlich, denn ein Coding-Agent mit Shell-Zugriff kann in einer Runde ein rm -rf ausführen, ein git push --force absetzen und deine Umgebungsvariablen abfließen lassen. Rein manuelle Freigabe ist ernsthaft unbrauchbar: Wer achtzig Befehle pro Stunde freigibt, beaufsichtigt den Agenten nicht, sondern ist eine langsame Tastatur mit Unterbrechungsfunktion. Das Tool, das die Mitte trifft, gewinnt die Pragmatiker.
Die Mitte ist ein abgestuftes Berechtigungsmodell, und dessen Gestaltungsraum ist besser verstanden, als viele denken:
- Lesen vs. Schreiben vs. Ausführen. Lesezugriffe sind nahezu kostenlos; Schreibzugriffe sollten auf den Projektbaum beschränkt sein; bei der Ausführung entscheidet die Richtlinie am meisten.
- Allowlists mit Argumentbewusstsein.
git statuswird automatisch freigegeben,git pushfragt nach. Naive Tools vergleichen nur den Binärnamen, gute Tools berücksichtigen Verb und Flags, dennnpm testundnpm publishsind dieselbe Binärdatei mit völlig unterschiedlichem Schadenspotenzial. - Session-gebundene Freigaben. „Diesen Befehl in dieser Session immer erlauben“ ist das wertvollste Berechtigungsfeature überhaupt. Es macht aus siebzig Nachfragen eine einzige.
- Eindämmung von Unumkehrbarem. Netzwerkzugriff, alles außerhalb des Projektverzeichnisses und alles, was Zugangsdaten berührt, sollte strukturell eingeschränkt sein und nicht nur per Nachfrage kontrolliert werden.
Genau diesen letzten Punkt vernachlässigen die meisten Harnesses, weil Nachfragen einfach sind und Eindämmung schwer ist. Aber eine Nachfrage ist eine Frage, von der das Modell hofft, dass du sie am Freitagabend um 18 Uhr richtig beantwortest. Den Prozessbaum des Agenten zu sandboxen – mit eingeschränktem Netzwerk und begrenzten Dateisystem-Mounts – macht ganze Fehlerklassen unmöglich, egal was Modell oder Nutzer tun. Den Zielkonflikt habe ich ausführlich in Eindämmung vs. Überwachung bei KI-Agenten dargelegt; in Kurzform: Nachfragen sind Überwachung, Sandboxing ist Eindämmung, und für alles Unumkehrbare willst du Eindämmung. Das CLI-Ökosystem lernt diese Lektion langsam. Diejenigen, die sie am schnellsten lernen, werden sich das Vertrauen verdienen, das Nutzer brauchen, um automatische Freigabe für die langweiligen 90 Prozent tatsächlich zu aktivieren.
Erweiterbarkeit und das Problem selbst gehosteter Modelle
Zwei kleinere Lektionen aus der 2.0-Diskussion verdienen Aufmerksamkeit. Erstens: „Alles ist ein Plugin“ setzt sich durch. Nutzer bauen Skills, Konfigurationseditoren und Workflow-Hooks auf diesen Harnesses auf, und das Harness, das Plugins erstklassig macht – mit Hot-Reload, der Möglichkeit, Sessions zu beobachten, und der Möglichkeit, das Verhalten zu verändern –, verstärkt den Aufwand der Community, statt dagegen zu arbeiten. Ein Hinweis darauf, dass OpenCode das ernst nimmt: Die eigene GitHub-App sortiert Fehlerberichte, indem sie das Problem reproduziert und die Ergebnisse kommentiert. Der Agent pflegt im Grunde den Agenten selbst. Diese „Selbstwahrnehmung“, die Nutzer gelobt haben, ist ein Ergebnis der Plugin-Architektur, nicht des Modells.
Zweitens: Modellunabhängigkeit ist schwieriger, als sie aussieht, und das ist ein Problem des Kontextformats. Ein Nutzer hat ein hervorragendes lokales Modell ausprobiert, das darauf trainiert ist, Befehle in Bash abzusetzen, während das Harness hartnäckig JavaScript-artige Tool-Calls erwartete. Beide konnten schlicht nicht zusammenarbeiten. Das ist die versteckte Kopplung in jedem Agent-Harness: Tool-Call-Format, Annahmen im System-Prompt und die Trainingsverteilung des Modells müssen zusammenpassen. Ein Harness, das die Konventionen einer einzigen Modellfamilie fest verdrahtet, ist nicht modellunabhängig, sondern bestenfalls modelltolerant. Wenn lokale Modelle für Coding-Agenten wichtig werden – und aus Kosten- und Datenschutzgründen sollten sie das –, brauchen Harnesses austauschbare Tool-Call-Dialekte, nicht nur austauschbare API-Endpunkte.
Wo die provokante These an ihre Grenzen stößt
Ich habe gesagt, das Modell sei der einfache Teil. Zeit, die Ränder einzugestehen. Die These gilt für das Design des Harness – Loops, Kontext, Berechtigungen –, aber es gibt Stellen, an denen das Modell tatsächlich der Engpass ist. Die Zuverlässigkeit bei der Tool-Nutzung ist selbst im Modell antrainiert; ein Modell, das nicht konsistent gültige Funktionsaufrufe erzeugt, lässt jedes Harness kaputt wirken, und kein Effect-basiertes Konzept für strukturierte Nebenläufigkeit repariert ein Modell, das mit dem eigenen Schema streitet. Mehrstufige Planung über lange Zeiträume trennt Modellklassen weiterhin auf eine Weise, die man innerhalb einer einzigen Session spürt. Und die Gegenüberstellung von Harness und Modell hat ein Verfallsdatum: Sobald Modelle agentisches Verhalten ins Training aufnehmen (native Tool-Nutzung, natives langfristiges Planen), wandern Fähigkeiten vom Harness in die Gewichte, und das heute clevere Harness-Feature wird zur verschwendeten Mühe von morgen. Teams, die Harnesses bauen, sollten davon ausgehen, dass sie ein Gerüst bauen, das Modelle irgendwann überflüssig machen. Ehrlich gesagt ist das ein Argument für Open-Source-Harnesses mit Plugin-Ökosystemen, denn die überleben über die Community und nicht über eine vorübergehende Fähigkeitslücke.
Außerdem gibt es eine UX-Untergrenze, die keine Architektur entschuldigt. Manche Nutzer haben OpenCode 2.0 ausprobiert und es trotzdem klobig gefunden; andere beklagten einen langsamen Start und eine immer weiter wachsende Datenbank mit toten Chat-Verläufen. Das sind keine tiefen Probleme, aber sie bringen Leute dazu, ein Tool in den ersten zehn Minuten wieder abzulegen, bevor die elegante Agent-Loop überhaupt zeigen kann, was sie kann. Politur ist ebenfalls ein Feature, und genau daran sparen Open-Source-Projekte am häufigsten.
Das Modell schreibt den Code, aber das Harness entscheidet, ob du ihm genug vertraust, um ihn ausführen zu lassen.
Mein pragmatischer Rat, als jemand, der diese Kategorie beim Umbau beobachtet hat: Wähl dein Coding-Tool so aus, wie du eine Datenbank wählen würdest, nicht wie einen Gewinner eines Modell-Benchmarks. Schau dir die Fehlerbehandlung der Loop an, die Kontextstrategie, die Granularität der Berechtigungen und ob Sessions das Schließen des Terminals überleben. Genau diese Teile werden auch nach dem nächsten Modell-Release noch zählen, wenn wieder alle gleich klug sind.


