Pi Durable: Earendil veröffentlicht Pi 1.0 und ein Framework für langlebige Agenten

Server im dunklen Raum mit einem kleinen leuchtenden Zylinder als Sinnbild für einen Datenspeicher
Deine Reaktion:

„Nach unzähligen Stunden der Härtung, Wartung und aktiven Entwicklung ist Pi jetzt ein solides Fundament, auf dem man bauen kann.“ So begründet das Team von Earendil in seiner Ankündigung vom 1. Oktober den Schritt, den es zusammen mit der Pi-Community vollzogen hat: Pi 1.0 ist erschienen. Die Ankündigung kommt ohne Pathos aus. Statt eines großen Versprechens steht dort eine nüchterne Feststellung über Reife.

Wer sich mit Coding-Agenten beschäftigt, kennt die Grenze, um die es hier geht. Ein Agent, der im Terminal einer einzigen Person dient, ist ein Werkzeug. Ein Agent, der stundenlang läuft, aus mehreren Oberflächen erreichbar ist und einen Absturz übersteht, ist Infrastruktur. Zwischen beidem liegt keine Modellverbesserung, sondern eine Schicht Software, die man Harness nennt. Um diese Schicht geht es im Kern — und sie ist der Grund, warum neben Pi 1.0 noch ein zweites Paket auftaucht.

Pi 1.0 als stabiler Kern, Pi Durable als offenes Experiment

Pi 1.0 soll der stabile Kern sein, auf dem gebaut wird. Der Coding-Agent Pi bleibt, was er war: Er läuft in einem Terminal, wird von einer Person gesteuert, und wenn der Prozess stirbt, schaut man nach, was passiert ist, und sagt ihm, es soll weitermachen. Das ist kein Mangel, sondern so ist dieses Werkzeug gedacht, und daran ändert Pi 1.0 nichts.

Parallel erscheint mit Pi Durable ein ausdrücklich experimentelles Paket. Laut Earendil ist es für lang laufende, durable und formbare Agenten gebaut, die überall laufen können – wobei „überall“ derzeit heißt: überall dort, wo eine JavaScript-Laufzeit vorhanden ist. Es geht nicht um ein einzelnes Produkt: Die Technologie soll in der Form angeboten werden, die jeweils am besten passt, statt in einer einzigen vorgegebenen. Dafür braucht es ein Agenten-Framework, das an jedem Ort läuft, aus unterschiedlichen Oberflächen erreichbar ist, unbegrenzt lange Gespräche trägt, katastrophale interne wie externe Fehler übersteht und mehrere Menschen und Clients gleichzeitig mit denselben Gesprächen arbeiten lässt.

Pi Durable ersetzt den Coding-Agenten nicht. Es teilt nicht nur Code mit ihm, etwa die Bibliothek pi-ai, sondern auch dessen Prinzipien: Minimalismus und Formbarkeit. Deshalb können beide nebeneinander existieren. Pi Durable dient als Spielwiese, auf der Entwürfe erprobt werden, ohne den Coding-Agenten im Alltag zu stören. Was sich dort bewährt, fließt später zurück in Pi.

Was ein Harness ist: Storage, Gespräche, Tools und Tasks

Ein Harness ist nach dem Verständnis von Earendil Storage plus die Maschinerie, die nötig ist, um ein oder mehrere Gespräche mit großen Sprachmodellen parallel zu betreiben. Er stellt die Werkzeuge bereit, die diese Modelle aufrufen, und die Umgebungen, in denen diese Werkzeuge laufen. Am besten lässt sich das als Leitstand mit Logbuch vorstellen: Der Leitstand fährt mehrere Vorgänge gleichzeitig, und jede Handlung wird vorher ins Logbuch geschrieben, damit sie nicht verloren geht.

Ein Gespräch wiederum ist eine Interaktion zwischen einem Menschen und einem Agenten, festgehalten als Transkript. Der Agent ist das Sprachmodell zusammen mit seinen Einstellungen, etwa dem Thinking Level, und den Werkzeugen, die es aufrufen darf. Die Werkzeuge arbeiten über eine Ausführungsumgebung, und das kann ein Laptop sein, eine entfernte virtuelle Maschine oder eine Sandbox im Arbeitsspeicher. Welche Werkzeuge und welche Umgebung ein Agent bekommt, entscheidet jedes Gespräch für sich. Alles, was der Harness ausführt, vom Modellaufruf bis zur Werkzeugausführung, ist ein Task.

Auffällig ist vor allem die Größe. Der gesamte Quellcode liegt ohne Tests bei rund 15.000 Zeilen, was mit GPT etwa 150.000 und mit Claude etwa 250.000 Tokens entspricht. Das ist der Worst Case, denn für den Aufbau einer Anwendung braucht ein Agent selten alles; allein die Storage-Backends umfassen 3.000 Zeilen, die er in der Regel überspringen kann. Die Absicht: Der Agent soll den Harness selbst verstehen können, auf dem er läuft.

Lange Läufe an jedem Ort: SQLite, JSONL und der Speicherbedarf

Langlebige Agenten brauchen einen Ort, an dem sie liegen. Ein Harness in Pi Durable öffnet deshalb über einem Storage-Backend, und mitgeliefert werden drei Varianten: Speicher, SQLite und JSONL. Dazu kommen eine Konformitäts-Suite und Benchmarks, damit eigene Backends geprüft werden können. Der Code für SQLite und JSONL verwendet keine Node-APIs, sodass er mit einem kleinen Adapter auch unter Bun oder innerhalb eines Cloudflare Durable Object läuft. Das Interface selbst ist klein genug, um es auf einen Key-Value-Store oder auf Postgres zu setzen.

Zur Ordnung gehört, dass immer nur ein Prozess einen Storage besitzt, während sich andere Clients an diesen Prozess anhängen. Bei SQLite hält der Harness ausschließlich das Arbeits-Set im Speicher: die aktiven Transkripte, laufenden Tasks und wartenden Eingaben. Alles andere bleibt auf der Platte, bis es gebraucht wird. Aktive Transkripte sind dabei von Natur aus begrenzt, weil die Kompaktierung ältere Nachrichten zusammenfasst, bevor sie das Kontextfenster sprengen. So passt selbst ein Gespräch mit zehntausenden Nachrichten bequem in den Arbeitsspeicher.

Die Kompaktierung ist dabei kein Sonderfall, sondern ein Task wie jeder andere, und sie läuft, während das Gespräch weitergeht. Nähert sich der Kontext dem Limit, fasst eine Hintergrund-Kompaktierung ältere Nachrichten zusammen, und die Zusammenfassung wird an der nächsten Turns-Grenze eingesetzt. Gewartet wird nur, wenn die nächste Anfrage sonst nicht passen würde. Weist der Anbieter eine Anfrage dennoch als zu lang zurück, kompaktiert der Harness und versucht es einmal erneut. Ältere Nachrichten bleiben ohnehin im Storage, und ein reset() geht noch weiter: Es beginnt einen neuen Kontext, wahlweise aus einer Übergabenotiz, während alles Vorherige durchsuchbar bleibt.

Nach dem Absturz weiterlaufen: Checkpoints und genau-einmal

Entscheidend ist die Frage, was passiert, wenn der Prozess stirbt. Der Laptop schläft ein, der Container wird neu ausgerollt, der Speicher läuft über. In Pi Durable speichert jeder Schritt eines Laufs einen Checkpoint, bevor er weitergeht. Ein neuer Prozess öffnet denselben Storage, findet die unfertigen Tasks und setzt jeden an seinem letzten Checkpoint fort. Hier tut das Logbuch aus der Analogie seine Arbeit: Es muss nichts rekonstruiert werden, es wird gelesen.

Im Detail wird eine abgebrochene Modellanfrage erneut gesendet, während die Teilantwort im Transkript bleibt und als abgebrochen markiert wird. Ein abgebrochener Werkzeugaufruf läuft nur dann erneut, wenn er selbst erklärt, dass das sicher ist. Andernfalls teilt man dem Modell mit, dass der Aufruf unterbrochen wurde, und übergibt die bisherige Ausgabe, damit es entscheiden kann. Eingereihte Nachrichten bleiben eingereiht. Eine requestId macht eine Einsendung genau-einmal wirksam, sodass ein Client, der nach einem Absturz erneut sendet, die ursprüngliche Einsendung zurückbekommt statt zweimal zu fragen.

Subagenten sind in Pi Durable nicht eingebaut, aber laut den Entwicklern in wenigen Zeilen Code gebaut. Ein Subagent läuft in einem eigenen Gespräch und setzt nach einem Absturz ebenfalls an seiner Stelle fort. Ein Subagenten-Werkzeug, das gefahrlos wiederholt werden kann, findet seinen Subagenten wieder und wartet auf dessen Antwort. Damit ist der Subagent kein Sonderfall der Architektur, sondern schlicht ein Gespräch, das von einem Werkzeugaufruf besessen wird.

Viele Gespräche gleichzeitig, Forks und eigene Agenten je Unterhaltung

Ein einzelner Harness fährt so viele Gespräche gleichzeitig, wie gebraucht werden, und zwar mit denselben Garantien wie im Einzelfall. Ein Gespräch startet neu oder forkt ein anderes an einer beliebigen Stelle seines Transkripts und sieht dessen Historie bis zu diesem Punkt, ohne sie zu kopieren. Das Beispiel, das Earendil dafür anführt, ist ein Slack-Kanal, in dem ein Agent Erwähnungen beantwortet und jemand einen Thread öffnet. Der Kanal ist ein Gespräch, der Thread ein Fork an genau der Nachricht, auf die geantwortet wird. Beide laufen gleichzeitig, ohne sich zu blockieren.

Jedes Gespräch speichert zudem seinen eigenen Agenten: das Modell, den Thinking Level, die ausgewählten Erweiterungen samt aktiven Werkzeugen, zusätzliche Anweisungen und das Arbeitsverzeichnis in seiner Ausführungsumgebung. Ein Prüfer, der neben dem Hauptagenten läuft, kann so ein günstigeres Modell nutzen, nur lesende Werkzeuge erhalten und in einem eigenen Checkout arbeiten. Die Trennung von Gespräch und Agent erlaubt damit unterschiedliche Rollen im selben System, ohne dass eine Rolle die andere verlangsamt.

Ebenso wichtig ist Earendil, dass viele Menschen und Clients gleichzeitig mit denselben Gesprächen arbeiten können. Weil alles, was eine Oberfläche braucht, als festgeschriebener Zustand vorliegt, kann sich eine beliebige Zahl von Clients an jedes Gespräch im Harness anhängen. Ein Client bekommt zuerst die aktuelle Ansicht – Transkript, die gerade gestreamte Antwort, laufende Werkzeuge samt Ausgabe, eingereihte Nachrichten, den Agenten und den Verbrauch – und danach nur noch die Änderungen. Wer später dazukommt oder die Verbindung verliert, startet wieder bei der aktuellen Ansicht, und jeder Client kann ein laufendes Gespräch steuern oder eine Folgefrage einreihen.

Erweiterungen, Hooks und was davon in Pi zurückfließt

Alles, was ein Agent tun kann, soll nach dem Willen der Entwickler steckbar sein, und jedes eingesteckte Teil soll an der Dauerhaftigkeit teilnehmen. Eine Erweiterung ist deshalb ein benanntes Bündel aus Systemprompt-Abschnitten, Werkzeugen, Hooks und Tasks. Die Anwendung installiert Erweiterungen in einer Registry, und jedes Gespräch wählt aus, was es nutzt, wobei es nur die Namen speichert. Der Systemprompt wird vor jeder Anfrage aus den Abschnitten der gewählten Erweiterungen neu gebaut, und Änderungen werden im Transkript an der Stelle festgehalten, an der sie passiert sind. Ein Neustart oder ein Fork sieht damit genau das, was das Modell gesehen hat; bei Modellen, die Änderungen mitten im Gespräch unterstützen, wird nur die Änderung gesendet, damit der Prompt-Cache gültig bleibt.

Werkzeuge werden ähnlich behandelt: Jeder Aufruf ist ein eigener dauerhafter Task, dessen Absicht vor der Ausführung gespeichert wird. Ein gleichnamiges Werkzeug in einer späteren Erweiterung ersetzt das frühere, und ein wrap verkleidet das jeweils gewinnende Werkzeug. Hooks greifen in Tasks ein, etwa in die Erzeugung einer Modellantwort, den Aufruf eines Werkzeugs oder die Kompaktierung. Sie können eine Anfrage umschreiben, einen Aufruf blockieren oder ein Ergebnis ersetzen. Da ein Hook nach einem Absturz erneut laufen kann, speichert eine Entscheidung sich in einem Memo, bei dem der erste Schreibvorgang gewinnt. Fehler in einem Hook werden gemeldet, und die Kette läuft weiter, außer bei beforeTool, wo ein Fehler den Aufruf blockiert.

Formbar heißt bei Pi Durable auch: Der Code eines laufenden Agenten lässt sich ändern, ohne ihn anzuhalten. Die Registry darf sich ändern, während Gespräche laufen; wer eine Erweiterung unter einem bereits vergebenen Namen installiert, ersetzt sie in einem Schritt. Ein Werkzeugaufruf, der schon läuft, endet mit dem Code, mit dem er begonnen hat, erst der nächste nutzt den neuen. Weil Gespräche nur Namen speichern und nie Code, übernehmen sie nach einem Neustart, was der neue Prozess installiert.

Auch der durable Anwendungszustand gehört zu diesem Bild: eine To-do-Liste, ein Plan, ein Ticket sollen so dauerhaft sein wie das Gespräch selbst. Solche Dokumente sind typisiertes JSON, liegen neben dem Transkript und werden in denselben atomaren Commits geändert, sodass der Zustand nie dem Transkript widerspricht, aus dem er entstanden ist. Tasks und Gespräche bilden dabei einen gemeinsamen Besitzbaum, und das Abbrechen eines Tasks bricht ab, was er besitzt, von unten nach oben. Vordergrund-Tasks gehören zur aktuellen Arbeit eines Gesprächs, Hintergrund-Tasks laufen weiter, während das Gespräch untätig ist. Damit lässt sich ein Subagent bauen, der den Turn überlebt, der ihn gestartet hat. Durable heißt nicht fehlerfrei, sondern wiederaufsetzbar. Ein System, das nach einem Absturz an der richtigen Stelle weitermacht, ist etwas anderes als eines, das nie abstürzt — und für lang laufende Agenten ist das die realistischere Eigenschaft. Wer einen Coding-Agent mit langer Laufzeit baut, bekommt hier einen Werkzeugkasten, der ausdrücklich experimentell ist; die API kann sich laut Earendil noch ändern. SQLite-Storage, Forks und Hooks sind kein fertiges Produkt, sondern eine Grundlage, auf die man die eigene Anwendung stellen kann.

Quelle: earendil.com

Deine Reaktion:
Artikel teilen:
Krötzsch-Check0 — 100
Fakten 58
Relevanz 72
Hype 32
Einschätzung 68
Redaktion 50 Stand 50 · noch keine Stimmen
Ist das Hype?
Sebastian Krötzsch
Autor

Sebastian Krötzsch

Sebastian Krötzsch schreibt auf sebask.de über Künstliche Intelligenz, Automatisierung, digitale Systeme und die Frage, was davon im Alltag wirklich nützlich ist. Ohne Buzzword-Nebel, dafür mit klarem Blick auf Praxis, Tools und echte Wirkung.