Ubers Engineering-Team hat in einem Blogbeitrag das interne System AutoClean vorgestellt. Es ist an die Feature-Flag-Verwaltung des Unternehmens angebunden, findet Flags, die sich gefahrlos abschalten lassen, erzeugt automatisch einen Diff zum Entfernen des Codes und übergibt ihn nach bestandenen Tests an Ingenieure zur Freigabe. In den vergangenen Jahren hat das System über 16.000 Feature-Flags und mehr als eine Million Codezeilen bereinigt und läuft derzeit dauerhaft in mehreren Monorepos von Uber.
Als Autoren des Beitrags nennt Uber die Senior Software Engineers Daniel Ramos und Diego Marcilio sowie den Software Engineer Nikhil Parasaram.
Warum das Löschen von Code so schwer ist
Neue Funktionen werden bei Uber schrittweise per Feature-Flag ausgerollt, und auf der Plattform hängen gleichzeitig mehrere tausend Flags. Ist der Rollout abgeschlossen, bleiben Verzweigungen, Hilfsfunktionen, Aufrufstellen, Konfigurationen und Tests oft einfach stehen. Wer ein Flag entfernt, muss an all diesen Stellen gleichzeitig eingreifen und dabei sicherstellen, dass sich das Verhalten in Produktion in keiner Weise ändert.
Der Blog nennt einen neuen Kostenfaktor: Toter Code macht Menschen nicht nur das Lesen mühsamer, sondern KI-Coding-Assistenten verbrauchen beim Parsen der Codebasis für diese Zweige ebenfalls mehr Zeit und Token.
Die dreistufige Pipeline
Stufe eins: Umschreiben. Der Agent erhält Zugriff auf die Codebasis und ruft über MCP die von Uber selbst entwickelte und als Open Source veröffentlichte Code-Transformations-Engine PolyglotPiranha auf, die Boolesche Vereinfachungen und die Eliminierung von Bedingungen übernimmt. Die Begründung der Autoren ist eindeutig: Macht man bei der Vereinfachung Boolescher Ausdrücke einen Fehler, könne das "can silently change program behavior", also unbemerkt das Programmverhalten verändern. Deshalb überlasse man so viel wie möglich deterministischen Werkzeugen.
Stufe zwei: CI reparieren. Einfache Fehler behandeln deterministische Fixer, etwa das Entfernen nicht mehr benötigter Standardwerte oder das Beheben von Lint-Meldungen. Komplexere Fälle übernimmt der Agent, zum Beispiel die Entscheidung, ob ein Test gelöscht oder angepasst werden muss. Die Rechte jedes Fixers sind eng begrenzt; der Test-Fixer darf nur Testdateien anfassen. Die Schleife läuft, bis die CI besteht oder die Zahl der Versuche aufgebraucht ist.
Stufe drei: Verifikation. Nach bestandener CI läuft zunächst die statische Prüfung, danach übernimmt eine Verifikationsschicht namens CodeCourt, in der mehrere spezialisierte Review-Agenten parallel prüfen. Zu den im Blog aufgeführten Regeln gehören:
- nur löschen, nichts hinzufügen und keinen neuen Code einführen;
- das beobachtbare Verhalten bleibt unverändert;
- nur das vorgegebene Flag behandeln und nicht nebenbei verwandte andere Flags entfernen;
- keine Kommentare oder Spuren des Denkprozesses des Agenten hinterlassen.
Fällt auch nur eine Regel durch, wird der Diff verworfen und gelangt nie zu einem Menschen. Nach Angaben der Autoren arbeiten mehrere fokussierte Sub-Agenten besser, als wenn ein einzelner Agent einen ganzen Diff von Anfang bis Ende prüft.
Von Piranha zu Agenten
Die Grundlage von AutoClean ist Piranha, das Uber vor einigen Jahren als Open Source veröffentlicht hat. Dieses Werkzeug wurde von Anfang an zum Löschen veralteter Flags geschrieben und arbeitet mit statischem Umschreiben auf Basis von Regelabgleich. PolyglotPiranha erweiterte die Regel-Engine später auf mehrere Programmiersprachen. Die Neuerung liegt diesmal im Umfeld: Die Regel-Engine kümmert sich weiterhin um die fehleranfälligste Boolesche Logik, die Agenten übernehmen, was die Regeln nicht abdecken, etwa das Reparieren von Tests oder das Ergänzen von Aufrufstellen, und eine weitere Gruppe von Agenten prüft das Ergebnis gegen.
Der Blog räumt mehrere Fehlermuster offen ein: Agenten ändern Produktionscode, nur damit Tests durchlaufen, löschen Tests, deren Verhalten eigentlich erhalten bleiben sollte, oder beenden die Arbeit zu früh und hinterlassen eine halb fertige Bereinigung. Bei zu vielen Anweisungen übersehen sie zudem einzelne Vorgaben. Solche semantischen Probleme fallen in der CI nicht auf; die Beschränkung der Fixer-Rechte und die Einführung von CodeCourt zielen genau darauf ab.
Der Beitrag nennt weder Erfolgsquote noch durchschnittliche Laufzeit oder den Anteil verworfener Diffs. Der Beispielcode ist in Go geschrieben, und wie gut andere Sprachen abgedeckt sind, wird nicht näher ausgeführt. Nach Darstellung der Autoren müssen menschliche Reviewer nur noch eine Frage beantworten: Soll dieses Flag entfernt werden? Die mechanische Korrektheit ist in den drei vorgelagerten Stufen bereits einmal abgefangen worden.
Quellen: Offizieller Uber-Engineering-Blog, CocoLoop, GitHub-Projektseite von PolyglotPiranha; maßgeblich für die Bereinigungszahlen ist die im Uber-Blog genannte kumulierte Zählweise.