Connect with us

Entwicklung & Code

Asynchrone Programmierung – Teil 3: Parallelität in C++ mit Qt6


close notice

This article is also available in
English.

It was translated with technical assistance and editorially reviewed before publication.

Das Qt6-Framework ist insbesondere wegen seiner mächtigen Werkzeuge zur Erstellung von Bedienoberflächen für eingebettete Geräte mit C++ weit verbreitet. Doch die Einsatzzwecke gehen über Embedded hinaus.

Weiterlesen nach der Anzeige


Martin Meeser

Martin Meeser

Martin Meeser ist selbständiger Diplominformatiker (Uni) und bietet Dienstleistungen zum Thema Softwareentwicklung an: Individual-Software-Entwicklung, Beratung zu Prozessen und Schulungen. In zahlreichen Projekten betreute er bisher Kunden unter anderem aus den Bereichen Automotive, Finance, Raumfahrt, Radioastronomie und Medizintechnik.

Dieser Artikel ist der dritte Teil aus der Serie „Asynchrone Programmierung“, die Mechanismen und Frameworks für die effiziente und nachhaltige Entwicklung von nichtlinearen Programmabläufen in verschiedenen Sprachen vorstellt. Asynchrone Programme benutzen keine fehleranfälligen und schwer zu debuggenden Thread-Mechanismen wie Locks und Semaphoren, sie verschwenden folglich keine Ressourcen durch Blockieren von Threads und sie skalieren nativ mit den zur Verfügung stehenden Prozessorkernen.

Im Gegensatz zu den bereits vorgestellten Mechanismen der Boost::Asio-Bibliothek, die de facto den C++ Standard darstellen und daher möglichst nativ in C++ eingebettet sind, bietet Qt aus seiner Historie heraus ein Event-System: den Qt-eigenen Signal-Slot-Mechanismus, QThreadPool und – etwas neuer – QFuture und QPromise.

Auf aktuellen Debian- und Ubuntu-Linuxen kann man Qt6 über die bekannte Paketverwaltung APT installieren:

sudo apt install qt6-base-dev

Dies installiert derzeit die Version 6.8.2. Möchte man die neueste Version (aktuell 6.10.2) verwenden oder arbeitet man mit einem anderen System, benötigt man für den Download einen Benutzeraccount bei der Qt Group, dem Unternehmen, das Qt entwickelt. Qt ist in verschiedene Module aufgeteilt. Die Beispiele in diesem Artikel benötigen QtCore, das in jedem Qt-Projekt erforderlich ist und Grundfunktionen liefert, sowie QtConcurrent für Nebenläufigkeit.

Die Programme lassen sich mit dem Tool qmake des Herstellers oder mit dem CMake-Paket von Qt6 bauen. Das folgende Listing zeigt eine typische Konfiguration in CMakeLists.txt für ein Qt6-Projekt ohne Bedienoberfläche.

Weiterlesen nach der Anzeige


cmake_minimum_required(VERSION 3.18)
project(MyQt6ConsoleApp VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

find_package(Qt6 REQUIRED COMPONENTS Core Concurrent)

qt_standard_project_setup()

qt_add_executable(MyQt6ConsoleApp
    src/main.cpp
)
target_link_libraries(MyQt6ConsoleApp PRIVATE Qt6::Core Qt6::Concurrent)

install(TARGETS MyQt6ConsoleApp
    RUNTIME DESTINATION bin


Listing 1: Ein typisches Beispiel für CMakeLists.txt für eine Konsolenanwendung mit Qt6

Die Hauptfunktion jeder Qt-Anwendung folgt dem gleichen Muster: Entwicklerinnen und Entwickler erzeugen eine Instanz der Hauptklasse, hier QCoreApplication, und rufen vor dem Beenden der Funktion die Methode exec() dieser Instanz auf, um die Event Loop von Qt zu starten.

Event Loops stellen die Mechanismen und die API für die asynchrone Entwicklung bereit und orchestrieren den Programmablauf. Die Event Loop von Qt nimmt auch Ereignisse vom Betriebssystem entgegen und leitet diese weiter. Das Grundgerüst einer Qt6-Anwendung mit Starten der Event Loop sieht folgendermaßen aus:


#include 

int main(int argc, char* argv[])
{
    QCoreApplication app(argc, argv);
    // ...
    return app.exec();


Listing 2: Grundgerüst einer Qt6-Anwendung, die eine Qt Event Loop startet.

Die Methode exec() springt erst beim Aufruf von QCoreApplication::quit() zurück. In diesem einfachen Beispiel wird das Programm also niemals von sich aus enden, der Hauptthread der Applikation wird für die Event Loop verwendet. Grafische Anwendungen verwenden statt QCoreApplication eine der Ableitungen dieser Klasse: QAndroidService oder QGuiApplication. Um auf Events reagieren zu können, muss die entsprechende Klasse von der Klasse QObject erben und die Methode event() oder customEvent() überschreiben. Alle Events stammen von der Klasse QEvent ab. Es gibt im Qt Framework eine Reihe von definierten Event-Klassen, zum Beispiel QEvent:Timer, QEvent:SockAct und QEvent:Quit. Entwickler können auch eigene Event-Typen erzeugen, indem sie eine von QEvent abgeleitete Klasse anlegen.

Mit der statischen Methode postEvent() der Klasse QCoreApplication werden konkrete Events an die Event Loop übergeben, wie folgendes Listing zeigt.


#include 

const QEvent::Type MyEventType = QEvent::Type(QEvent::User + 1);

class MyEvent : public QEvent
{
public:
    MyEvent(const QString& msg) : QEvent(MyEventType), message(msg) {}
    QString message;
};

class MyReceiver : public QObject
{
    Q_OBJECT
protected:
    void customEvent(QEvent* ev) override
    {
        if (ev->type() == MyEventType)
        {
            MyEvent* myEvent = static_cast(ev);
            qDebug() << myEvent->message;
            QCoreApplication::quit();
        }
    }
};

int main(int argc, char* argv[])
{
    QCoreApplication app(argc, argv);

    MyReceiver receiver;
    QCoreApplication::postEvent(&receiver, new MyEvent("Kind of async
  hello world!"));

    return app.exec();


Listing 3: Beispiele für asynchrone Ausführung mit einem eigenen Event-Typen.

Die Methode postEvent() reiht das Ereignis in die Warteschlange ein und springt sofort zurück. Bisher gibt es allerdings nur einen Thread: den Haupt-Thread. Das bedeutet, dass das Programm blockiert, sobald innerhalb der Ereignisverarbeitung Code läuft, der selbst blockiert. Auch ein lang andauerndes Event verzögert den gesamten Programmablauf, was zu einem für Anwenderinnen und Anwender wahrnehmbaren Einfrieren des Programms führt.

Daher hat sich in Qt bewährt, explizit einen oder mehrere Arbeiter-Threads („Worker Threads“) zu erzeugen. Dazu legt man eine neue Instanz der Klasse QThread an. Ein Aufruf der Methode QThread::start() führt innerhalb des QThread eine separate Event Loop aus.

In Qt gilt der Grundsatz der Thread-Zugehörigkeit („Thread Affinity“): Jedes QObject ist einem QThread zugeordnet, initial demjenigen, in dem es erstellt wurde. Die Event-Verarbeitung erfolgt immer in dem Thread, der dem QObject zugeordnet ist. Der Thread lässt sich mit der Methode QObject::moveToThread() jedoch wechseln.

Auf diese Weise verlaufen Aufgaben parallel, wie folgendes Listing exemplarisch zeigt.


// MyReceiver und MyEvent analog zu Listing 3

int main(int argc, char* argv[])
{
    QCoreApplication app(argc, argv);
    qDebug() << QThread::currentThreadId();

    MyReceiver receiver;
    QThread qThread;
    qThread.start();
    receiver.moveToThread(&qThread);

    QCoreApplication::postEvent(&receiver, new MyEvent(QString("Kind of async hello world from 2nd thread")));

    return app.exec();
}


Listing 4: Erstellen und Verwenden eines QThread mit eigener Event-Loop.

Die Methode postEvent() springt sofort zurück und der Code setzt keine komplizierten und fehleranfälligen Mechanismen wie Locks oder Semaphore ein, die Erstellung und Zuordnung einzelner Threads sind aber explizit. Dieses Beispiel skaliert also nicht automatisch mit den zur Verfügung stehenden Ressourcen, so wie es bei einem Threadpool der Fall ist. Die folgende Abbildung fasst die grundlegenden Klassen einer Qt-Anwendung in einem UML-Klassendiagramm zusammen.


Diagramm Qt-Klassen

Diagramm Qt-Klassen

UML-Klassendiagramm der grundlegenden Qt-Klassen



Source link

Entwicklung & Code

Ladybird-Browser integriert Rust mit Hilfe von KI


Das freie Browser-Projekt Ladybird hat einen wichtigen Schritt in Richtung Speichersicherheit vollzogen: Die Entwickler haben zentrale Komponenten ihrer JavaScript-Engine LibJS von C++ nach Rust portiert. Der Port umfasst rund 25.000 Zeilen Code und wurde mit Unterstützung von KI-Werkzeugen innerhalb von zwei Wochen umgesetzt.

Weiterlesen nach der Anzeige

Konkret wurden der Lexer, Parser, Abstract Syntax Tree (AST) und der Bytecode-Generator von LibJS übersetzt. Diese Komponenten eigneten sich laut Hauptentwickler Andreas Kling besonders gut für den ersten Port, da sie relativ selbstständig arbeiten und sich durch die test262-Suite umfangreich testen lassen. Alle 52.898 Tests der test262-Suite sowie 12.461 Ladybird-spezifische Regressionstests verliefen ohne Probleme – die Rust- und C++-Implementierung erzeugen byte-identische Ausgaben.

Für die Übersetzung setzte Kling auf die KI-Modelle Claude Code und Codex, betont jedoch, dass es sich um eine Arbeit unter menschlicher Aufsicht (human-directed) handelte. Er steuerte den Prozess durch hunderte kleine Prompts und entschied selbst, welche Teile in welcher Reihenfolge portiert werden sollten. Nach der initialen Übersetzung führte er mehrere „adversarial“ Reviews durch, bei denen verschiedene KI-Modelle den Code auf Fehler und schlechte Muster prüften. Was manuell mehrere Monate gedauert hätte, war so in zwei Wochen erledigt.

Der resultierende Rust-Code trägt bewusst den Stil „translated from C++“, ist also nicht idiomatisches Rust. Diese Entscheidung fiel zugunsten der Kompatibilität mit der C++-Pipeline. Erst wenn die C++-Implementierung vollständig abgelöst wird, will das Projekt den Code in idiomatisches Rust überführen.

Die Entscheidung für Rust ist bemerkenswert, da Ladybird die Sprache 2024 noch abgelehnt hatte. Damals argumentierten die Entwickler, Rusts Ownership-Modell passe nicht gut zum objektorientierten Stil der Web-Plattform mit ihren tiefen Vererbungshierarchien und Garbage Collection. Als Alternative wurde Swift evaluiert, scheiterte jedoch an unzureichender C++-Interoperabilität und limitiertem Plattform-Support außerhalb des Apple-Ökosystems.

Weiterlesen nach der Anzeige

Nach einem Jahr Stillstand entschied sich Kling nun pragmatisch für Rust. Als Gründe nennt er das reifere Ökosystem für die Systemprogrammierung, die verbreiteten Rust-Kenntnisse in der Contributor-Community und die Tatsache, dass auch Firefox und Chromium bereits Rust integrieren. Vor allem aber bietet Rust Speichersicherheitsgarantien, die C++ fehlen – ein kritischer Faktor für Browser-Engines, die häufige Angriffsziele sind.

Einen vollständigen Ausstieg aus C++ plant Ladybird nicht. Die Sprache bleibt laut Kling die Hauptentwicklungssprache des Projekts. Der Rust-Port sei ein „Sidetrack, der lange läuft“. Neuer Rust-Code koexistiert mit bestehendem C++ über definierte Interop-Grenzen. Das Core-Team steuert bewusst, welche Komponenten wann portiert werden.

Ladybird entwickelt eine vollständig unabhängige Browser-Engine als Alternative zu den etablierten Engines Gecko (Firefox), Blink (Chromium) und WebKit (Safari). Noch befindet sich das Open-Source-Projekt in einer frühen Phase, eine erste Alpha-Version für Linux und macOS soll 2026 erscheinen.


(fo)



Source link

Weiterlesen

Entwicklung & Code

KI-Inferenz in Silizium gegossen: Taalas kündigt HC1-Chip an


Das 2023 in Kanada gegründete Start-up Taalas hat mit dem HC1 einen Technology Demonstrator angekündigt, der KI-Inferenz auf eine neue Stufe heben soll. Statt ein Sprachmodell per Software auf Allzweck-KI-Rechenbeschleunigern auszuführen, gießt Taalas das Modell sozusagen in Silizium. Das erste Produkt ist ein „fest verdrahtetes“ Llama 3.1 8B, das laut Herstellerangaben 17.000 Token pro Sekunde pro Nutzer erzeugen soll.

Weiterlesen nach der Anzeige

Laut Taalas bildet das Herzstück ein applikationsspezifischer Logikchip (ASIC) mit rund 53 Milliarden Transistoren, gefertigt bei TSMC im 6‑nm‑Prozess (N6) und 815 mm² Die‑Fläche.

Wie das Unternehmen in einem Blogbeitrag mitteilte, sei das nahezu zehnmal schneller als der aktuelle Stand der Technik. Zum Vergleich: Eine Nvidia H200 erreicht nach Nvidia-eigenen Baseline-Daten rund 230 Token pro Sekunde auf demselben Modell. Spezialisierte Inferenz-Anbieter wie Cerebras kommen laut den unabhängigen Benchmarks von Artificial Analysis auf rund 1.936 Token pro Sekunde – also etwa ein Neuntel des von Taalas beanspruchten Werts. SambaNova folgt mit 916 Token/s, Groq mit 609 Token/s.

Die Konkurrenz schläft jedoch nicht: Nvidia lizenziert seit Dezember 2025 Groqs Technik und hat große Teile des Designteams übernommen, um die eigene Position bei dedizierter Hardware zu stärken.

Taalas stellt zum Ausprobieren den Chatbot „Jimmy“ bereit, der tatsächlich mit bemerkenswerter Geschwindigkeit antwortet – knapp 16.000 Token pro Sekunde waren im Test erreichbar. Einen Preis für den HC1 nennt das Unternehmen bislang nicht. Interessierte Entwickler können sich für den Zugang zu einer Inference-API registrieren.

Das vor zweieinhalb Jahren gegründete Start-up verfolgt drei Kernprinzipien: totale Spezialisierung auf einzelne Modelle, die Verschmelzung von Speicher und Rechenlogik auf einem Chip sowie eine radikale Vereinfachung des gesamten Hardware-Stacks. Taalas beansprucht, Speicher und Rechenwerk bei DRAM-typischer Dichte auf einem einzelnen Chip zu vereinen. Damit entfalle die bei herkömmlicher Inferenz-Hardware übliche Trennung zwischen langsamem Off-Chip-DRAM und schnellem On-Chip-Speicher.

Das verspricht Cerebras zwar auch, baut dazu aber seine gigantische Wafer Scale Engine (WSE), die einen kompletten Wafer belegt und 15 kW Leistung in Hitze verwandelt.

Weiterlesen nach der Anzeige

Der Ansatz unterscheidet sich grundlegend von dem, was große Chiphersteller derzeit verfolgen. Nvidia setzt bei seinen KI-Beschleunigern wie dem H200 auf teures High Bandwidth Memory (HBM), aufwendige Gehäusetechnik (Packaging) und extrem hohe I/O-Datentransferraten.

Auch beispielsweise Googles TPU, Amazons Interentia oder Microsofts kürzlich angekündigter Azure-Beschleuniger Maia 200 nutzen bis zu 216 GByte HBM3E-Speicher bei einer Transferrate von 7 TByte/s. Microsoft verspricht zwar eine höhere Performance pro investiertem Dollar als bei Nvidia-Technik, doch Maia ist ebenfalls als Allzweckbeschleuniger für verschiedene KI-Modelle konzipiert.

Taalas eliminiert diese Komplexität, indem der HC1 ausschließlich für ein einzelnes Modell optimiert wird. Das Ergebnis komme ohne HBM, 3D-Stacking, Flüssigkühlung und Highspeed-I/O aus.

Das hat allerdings einen Preis in puncto Flexibilität. Der HC1 ist weitgehend fest verdrahtet – der Chip kann nur Llama 3.1 8B ausführen, nicht beliebige andere Modelle.

Llama 3.1 wurde Mitte 2024 vorgestellt, das ist im KI-Wettrüsten schon ein stattliches Alter. Die kompakte Version mit 8 Milliarden Gewichten (8 Billion, daher Llama 3.1 8B) läuft in quantisierter Form sogar auf einem Raspberry Pi 5 – wenn auch sehr langsam.

Immerhin lassen sich laut Taalas die Größe des Kontextfensters konfigurieren und per Low-Rank-Adapter (LoRA) Feinabstimmungen vornehmen. Zudem räumt das Unternehmen ein, dass die erste Silizium-Generation ein proprietäres 3-Bit-Datenformat nutzt, kombiniert mit 6-Bit-Parametern. Diese aggressive Quantisierung führe zu gewissen Qualitätseinbußen gegenüber GPU-Benchmarks mit höherer Präzision.

Taalas plant, sehr schnell Nachfolger zu liefern. Der schlanke, automatisierte und schnelle Entwicklungsprozess für KI-ASICs ist das eigentliche Ziel des jungen Unternehmens. Es wurde von den Tenstorrent-Gründern Ljubisa Bajic und Drago Ignjatovic ins Leben gerufen. Beide waren zuvor länger für AMD tätig, Bajic auch für Nvidia. Wegen der prominenten Namen – derzeit leitet der bekannte Chipentwickler Jim Keller Tenstorrent – erheischt Taalas viel Aufmerksamkeit in der KI-Szene.

Gerade einmal 24 Teammitglieder hätten das erste Produkt realisiert, bei Ausgaben von 30 Millionen US-Dollar – von insgesamt über 200 Millionen eingesammeltem Kapital. Für einen N6-Chip mit 53 Milliarden Transistoren sind 30 Millionen US-Dollar Entwicklungskosten sehr wenig. Angesichts der extrem hohen Preise für Allzweck-KI-Beschleuniger erwarten die Gründer eine lukrative Marktnische.

Taalas zielt mit seinen Chips ausdrücklich auf Rechenzentren verspricht dort Kosten, die 20-mal niedriger liegen sollen als bei konventioneller GPU-Inferenz, bei einem Zehntel des Stromverbrauchs.

Ein mittelgroßes Reasoning-Modell auf Basis der gleichen HC1-Plattform soll im Frühjahr in den Taalas-Laboren eintreffen und kurz darauf als Inference-Service verfügbar werden.

Danach plant das Unternehmen, mit der zweiten Chipgeneration HC2 ein Frontier-LLM umzusetzen. Die HC2-Plattform soll standardisierte 4-Bit-Gleitkommaformate unterstützen, höhere Packungsdichte bieten und noch schneller arbeiten. Ein Deployment ist für den Winter vorgesehen.

Die von Taalas genannten Leistungsdaten sind beeindruckend, lassen sich bislang aber nur eingeschränkt überprüfen. Die Benchmarks stammen aus hauseigenen Tests; unabhängige Messungen von Dritten liegen bisher nicht vor.

Auch ist unklar, wie sich die Qualitätseinbußen durch die aggressive Quantisierung in der Praxis auswirken – insbesondere bei komplexeren Aufgaben jenseits einfacher Chat-Konversationen. Ob das Konzept modellspezifischer Chips wirtschaftlich skaliert, wenn für jedes neue Modell eigenes Silizium gefertigt werden muss, bleibt ebenfalls abzuwarten.

Taalas geht es nicht um sogenannte „Edge AI“-Anwendungen, bei denen trainierte Modelle ohne Cloud-Anbindung direkt auf dem Gerät laufen. Das sind häufig Modelle für Spracherkennung, Sprachsteuerung, Objekterkennung in Videobildern für Überwachungskameras, Radar-Sensorauswertung oder Maschinenüberwachung durch Geräuschanalyse (Predictive Maintenance). Das ist die Domäne der Neural Processing Units (NPUs) mit derzeit 10 bis 90 Int8-Tops, die in verwirrender Vielfalt auf den Markt kommen: M5Stacks AI Pyramid-Pro, die Hailo-NPUs zum Nachrüsten des Raspberry Pi 5, Google Coral und die Embedded-Versionen von x86- und ARM-Prozessoren wie AMD Ryzen, Intel Panther Lake, Qualcomm Snapdragon, Mediatek Genio, Rockchip und etwa auch RISC-V-SoCs wie der SpacemiT K3. Auch die europäischen Automotive-Mikrocontroller-Spezialisten Infineon, STMicroelectronics und NXP offerieren alle Chips mit eingebauten NPUs, ebenso wie TI und Renesas.

Lesen Sie auch


(vza)



Source link

Weiterlesen

Entwicklung & Code

Volle Kontrolle – Gas Town orchestriert zehn und mehr Coding-Agenten


close notice

This article is also available in
English.

It was translated with technical assistance and editorially reviewed before publication.

Mad Max als Vorbild für Softwareentwicklung? Das neue Framework Gas Town des Entwicklers und Bloggers Steve Yegge orchestriert mehr als zehn Coding-Agenten gleichzeitig mit einer Architektur, die von der postapokalyptischen Filmreihe inspiriert ist. Der Ansatz: nicht perfekte Einzelagenten, sondern kontrolliertes Chaos mit Agenten-Rollen wie Bürgermeister, Wächter und Raffinerie, die alle an die Mad-Max-Filme angelehnt sind (siehe Tabelle am Ende des Artikels). Gas Town ist dabei nichts für schwache Nerven oder einen kleinen Geldbeutel.

Weiterlesen nach der Anzeige


Ingo Eichhorst

Ingo Eichhorst

Ingo Eichhorst ist AI Architect und Engineering Trainer bei IONOS. Seit über 15 Jahren arbeitet er in verschiedenen IT-Rollen wie CTO, Solution Architect und Software Engineer. Aktuell beschäftigt er sich intensiv mit KI-gestützter Softwareentwicklung, KI-Architektur und den Herausforderungen beim Einsatz von KI-Agenten in der Praxis.

Yegge betont, dass sich das System noch im Alpha-Stadium befindet und erhebliche Vorkenntnisse zu Coding-Agenten voraussetzt, um mit dem Chaos in der Stadt der Coding-Agenten umgehen zu können. Zudem benötigt man durch die starke Skalierung schnell ein zweites oder drittes Claude-Max-Abonnement von Anthropic, das je nach Variante 100 oder 200 US-Dollar pro Monat kostet.

Gas Town zählt zu einer ganzen Gruppe an Anwendungen, die von der Community derzeit heiß diskutiert werden und deren Ziel es ist, Coding-Agenten zu koordinieren. Zu diesen Orchestratoren gehören zum Beispiel Ralph, Loom oder AutoClaude. Yegge hat das Framework am 1. Januar 2026 veröffentlicht, nach nur siebzehn Tagen Entwicklungszeit. Allerdings steckt im Konzept die Erfahrung von über einem Jahr an Experimenten. Er hat es mithilfe von KI-Agenten in Go geschrieben.

Yegge geht von dem Gedanken aus, dass es schon immer die Aufgabe von Ingenieuren gewesen ist, komplexes Chaos in beherrschbare Strukturen zu verwandeln. Das Tool geht dabei einen Failure Mode nach dem anderen mit unterschiedlichen Konzepten an. Der Autor spricht von nichtdeterministischer Idempotenz, zwei Begriffen, die sich auf den ersten Blick ausschließen, aber durch die Kontrollstrukturen des Frameworks zusammenfinden. Die parallele Arbeit von drei bis fünf Coding- und anderen KI-Agenten kann zu chaotischen Systemzuständen führen. Was passiert beispielsweise, wenn mehrere Agenten an gleichen oder ähnlichen Aufgaben arbeiten? Wer kümmert sich um Merge-Konflikte? Wie lässt sich doppelte Arbeit verhindern? Gas Town bedient sich unterschiedlichster Konzepte, um Ordnung in das Chaos zu bringen (siehe folgende Abbildung).


Infografik Struktur Gas Town

Infografik Struktur Gas Town

Die Gas-Town-Architektur mit Control Plane (Mayor, Deacon) und Data Plane (Polecats, Rigs, Refinery, Witness). Der Task-Management-Agent Beads verwaltet alle Tasks, Convoys bündeln Aufgaben für die Arbeitsagenten.

Weiterlesen nach der Anzeige

Ein typischer Tag in der Stadt Gas Town beginnt damit, dass der menschliche Entwickler (Overseer) gemeinsam mit dem Hauptagenten, dem Bürgermeister (Mayor), die Aufgaben für den Tag in natürlicher Sprache festlegt. Der Bürgermeister zerlegt diese Aufgaben in kleinere Teilaufgaben und speichert sie im Task-Manager (Beads). Sobald die Vorbereitungen fertig sind, bündelt er Aufgaben in einem Arbeitsauftrag, im Convoy, und schickt sie in eines der Repositories, Rigs. Wenn Gas Town Zugriff auf eine gültige GitHub-Authentifizierung hat, kann der Bürgermeister Repositories einfach klonen und für die Verwendung mit Gas Town initialisieren.

Das Aufteilen der Aufgaben begegnet dem Problem der nachlassenden Qualität der Antworten von Coding-Agenten, je weiter sich ihr Kontextfenster füllt. Bei den Claude-LLMs sind das aktuell 200.000 Token. Bei Erreichen des Limits komprimiert der Coding-Agent die Dialoge, um Platz zu schaffen. In der Praxis führt schon ein zu sechzig Prozent gefülltes Kontextfenster zu einer merklichen Reduktion der Ausgabenqualität.

Im Rig werden Arbeiter-Agenten (Polecats) aktiv, die mit der Abarbeitung von Aufgaben beginnen. Je mehr Aufgaben anliegen, desto mehr Polecats treten in Aktion. Sie schaffen sich mit Git-Worktrees ihre eigene Arbeitsumgebung und kümmern sich eigenständig um die Umsetzung.

Über Mailboxes und Handoffs können sie miteinander kommunizieren. Das Mailbox-System ist von Erlang inspiriert und dient der Kommunikation zwischen langlebigen Agenten, wie dem Bürgermeister und dem Wächter. Handoffs hingegen arbeiten synchron und dienen der Übergabe des Arbeitszustands an eine neue Arbeiter-Instanz, wenn der Kontext über die oben beschriebene kritische Füllmenge hinaus ansteigt.

Da in Gas Town immer mal etwas schiefläuft, beschäftigt der Bürgermeister den Wächter (Deacon), der das Gesamtsystem periodisch analysiert, Zombieprozesse aufräumt, festgefahrene Sessions wieder anstößt und die wichtigsten Systemfunktionen am Leben hält. Im Unterschied zum Wächter, der auf Systemebene patrouilliert, überwacht der Aufseher (Witness) innerhalb eines Rigs einzelne Agenten. Jeden Agenten, den er etwa beim Faulenzen erwischt, ermordet er eiskalt und ersetzt ihn.

Mit mehreren Agenten kommt es zu vielen parallelen Änderungen, doppelter Arbeit und unzähligen Merge-Konflikten. Außerdem berichten mehr und mehr Entwicklerinnen und Entwickler, dass die Freude an ihrem Job abgenommen hat, seit sie nur noch Code von KI-Agenten reviewen.

Um diesen Problemen Herr zu werden, gibt es in Gas Town eine Raffinerie. Sie überprüft alle Arbeitsergebnisse der Agenten und räumt auf. Merge-Konflikte und schlechte Codequalität bekämpft sie mehrheitlich durch Qualitätskriterien, die sich über konfigurierbare Review-Presets und ein projektspezifisches CLAUDE.md anlegen lassen.

Nachdem alle Aufgaben abgeschlossen sind, meldet der Bürgermeister dem Entwickler stolz die erfolgreiche Abarbeitung der Convoy-Aufgabengruppe.

Agenten in Gas Town stellen austauschbare Instanzen dar, vergleichbar mit dem Konzept von Cattle statt Pets bei der Orchestrierung der Infrastruktur mit virtuellen Maschinen oder Containern, etwa mit Kubernetes. Auch darüber hinaus hat das Framework viel mit Kubernetes gemeinsam: Es gibt eine Control Plane (Bürgermeister und Wächter), die eine Data Plane (die Polecats und Aufseher) managen. Dabei sind die Arbeiter-Agenten (Polecats) austauschbar: Wenn sie den Dienst niederlegen oder stecken bleiben, werden sie durch eine neue Instanz ersetzt, ohne dass der Kontext aus der letzten Session verloren geht.

Wenn Entwicklerinnen und Entwickler blind mit Agenten Code produzieren, akkumulieren sich auf Dauer die technischen Schulden. Die tauchen auch als Fehlannahmen (Heresies) im inneren Monolog der Agenten auf, und menschliche Entwickler können sie darüber aufspüren und nachvollziehen. Grund für die Fehler ist oft das eingeschränkte Kontextfenster, aufgrund dessen Agenten aus dem Blick verlieren, was in der letzten Session vorgefallen ist. Früher gewählte Ansätze geraten in Vergessenheit und Agenten wählen mitunter fremde Designmethoden, die die Architekturkonsistenz verletzen. In einer größeren Codebasis können beispielsweise drei bis vier unterschiedliche Logging Libraries auftauchen.

Um dem zu begegnen, erfordert es sorgfältige Reviews durch Menschen, was wiederum am Produktivitätsgewinn durch die multiplen Agenten nagt. Gas Town wählt eine andere Strategie, die auf Stichproben basiert, den Sweeps: systematische Korrekturwellen, die Architektur-Drift und schlechte Praktiken eindämmen, ohne dass Entwickler alle Fehlannahmen bedenken oder alle Codezeilen einzeln analysieren müssen. Ein sechzigminütiger Review-Sweep mündet in konkreten Aufgaben für das Task-Management (Beads), die so in den Kontext der beteiligten Agenten gelangen. Das lenkt künftige Entscheidungen in die Richtung, die die menschlichen Entwickler für richtig halten.

Um einen Sweep zu starten, lassen sich Entwickler vom Bürgermeister über einen persistenten Workspace (~/gas-town//crew//rig/) einen Git-Worktree erzeugen und sehen dort die Arbeitsergebnisse eines Convoys wie gewohnt in der IDE oder im Terminal. Anstatt selbst Änderungen vorzunehmen, beauftragen sie den Bürgermeister mit der Erstellung von Korrekturaufgaben. Diese ändern das Verhalten der Agenten und führen zu einer weiteren Erhöhung der Codequalität. Nach und nach steigert sich so das Vertrauen in die Agentenschar und der Aufwand für Sweeps reduziert sich. Sweeps stellen eine Art Garbage Collection für technische Schulden dar. Zusätzlich sollten Developer aber nicht auf die gängigen Kontrollmethoden wie Rule-Dateien (AGENT.md oder CLAUDE.md) und statische Quality Gates wie Fitness Functions oder statische Codeanalyse verzichten.



Source link

Weiterlesen

Beliebt