6 Punkte von GN⁺ 3 시간 전 | Noch keine Kommentare. | Auf WhatsApp teilen
  • Als es in Zig ohne Speichersicherheit weiterhin zu Lecks und Abstürzen kam, migrierte Bun 535.496 Zeilen Code mit 64 AI-Agenten nach Rust und verkürzte eine auf 1–2 Jahre geschätzte Arbeit auf 11 Tage
  • Ausgangspunkt des Erfolgs war ein 600 Zeilen langes PORTING.md; danach folgten dateiweises paralleles Konvertieren, zwei adversarielle Reviews, das Beheben von Compilerfehlern, lokale Tests und das Bestehen von CI in dieser Reihenfolge
  • Für 6.500 Commits wurden laut API-Preisen 165.000 US-Dollar sowie 5,9 Milliarden nicht gecachte Input-, 690 Millionen Output- und 72 Milliarden gelesene Cache-Input-Token verbraucht
  • Bei manueller Arbeit hätten vermutlich drei Ingenieure mit tiefem Wissen über die Codebasis etwa ein Jahr lang Produktverbesserungen, Bug- und Security-Fixes sowie die Entwicklung neuer Features stoppen müssen, weshalb die Neuschreibung selbst schwer umsetzbar gewesen wäre
  • Um denselben Ansatz zu wiederholen, braucht es Ingenieure mit tiefem Verständnis der Codebasis, eine starke Test-Suite, deren Ergebnisse vertrauenswürdig sind, und die Bereitschaft, trotz ungewissem Erfolg Token-Kosten zu tragen

Warum Bun sich für eine Rust-Neuschreibung entschieden hat

  • Bun ist ein komplexes Produktionsprojekt, das über eine JavaScript-Runtime hinaus viele Funktionen bietet
    • JavaScript-, TypeScript- und CSS-Transformation, Bundling, Minifizierung
    • Test-Runner und npm-kompatibler Paketmanager
    • Modulauflösung, WebSocket-Client, Node.js-Implementierung und verschiedene Module
  • Die monatlichen Downloads liegen bei 22 Millionen; Claude Code und OpenCode hängen davon ab, und Vercel, Railway und DigitalOcean unterstützen es direkt
  • Zig ist keine speichersichere Sprache, daher treten auch in aktuellem Bun weiterhin Memory Leaks, speicherbedingte Abstürze und Schreibzugriffe außerhalb des Heap-Bereichs auf
    • Das Bun-Team patchte den Zig-Compiler und führte End-to-End-Tests für Memory Leaks ein, konnte die Probleme aber nicht beseitigen
    • Beim gleichzeitigen Umgang mit den Lebensdauern von Garbage-Collected-Werten und manuell verwalteten Werten entstanden kleine Lecks und sporadische Abstürze
    • Bei jeder Speicherallokation mussten Freigabestelle und mögliche doppelte Freigabe, JavaScript-Exception-Handling sowie die Pointer-Sichtbarkeit des konservativen Stack-Scanners geprüft werden
  • In sicherem Rust werden use-after-free und double-free zu Compilerfehlern, und fehlende Freigaben auf Fehlerpfaden lassen sich über automatische Bereinigung auf Basis von Drop behandeln
  • Es wurde auch geprüft, Rust-artige Smart Pointer direkt in Bun einzuführen, aber das hätte gegenüber Rust eine schlechtere Ergonomie bei fehlenden gleichwertigen Garantien geboten

Warum bestehende Rewrite-Projekte lange dauern

  • Während der Neuschreibung werden der ursprünglichen Codebasis weiter Features hinzugefügt, weshalb sich der Fertigstellungstermin oft immer weiter verschiebt
    • Eine auf 9 Monate geschätzte Arbeit kann nach 9 Monaten noch etwa 6 weitere Monate benötigen
    • Selbst nach 15 Monaten können wegen des Nachziehens neuer Features noch mehrere Monate Arbeit übrig sein
    • Selbst mit Glück endet es erst nach einem zweimonatigen Feature-Freeze in etwa 18 Monaten, sodass eine anfängliche Schätzung von 9 Monaten auf mehr als 2 Jahre anwachsen kann
  • Buns Zig-Code umfasst ohne Kommentare 535.496 Zeilen, daher wurde geschätzt, dass ein kleines Ingenieurteam etwa ein Jahr brauchen würde, um ihn in eine andere Sprache zu übertragen
  • Ein Jahr ohne sichtbare Verbesserungen für Nutzer war keine realistische Option, daher sollte mit Fable geprüft werden, ob sich die Rust-Portierung innerhalb einer Woche validieren lässt

Vorabdesign und Validierung für die Portierung

  • Im ersten Schritt wurde etwa 3 Stunden lang mit Claude besprochen, wie Zig-Patterns Rust-nah abgebildet werden können; das wurde in einem 600 Zeilen langen PORTING.md festgehalten
  • Die Portierungsrichtlinien enthalten konkrete Einschränkungen, um Buns bestehende Ausführungsstruktur zu erhalten
    • tokio, rayon, hyper, async-trait, futures werden nicht verwendet
    • Module mit I/O-Zugriff wie std::fs, std::net, std::process sind verboten
    • Da Bun seinen eigenen Event Loop und die System Calls kontrolliert, werden statt async fn wie im bisherigen Zig Callbacks und State Machines verwendet
    • Wenn Konflikte mit dem Borrow Checker auftreten, werden nötige skalare Werte in lokalen Variablen gespeichert, das Borrow beendet und danach erneut geborgt
    • Die Verwendung roher Pointer zur Umgehung des Borrow Checkers ist verboten; an Stellen mit Strukturänderungen werden Portierungsnotizen hinterlassen
  • Von insgesamt 1.448 Dateien wurden zunächst 3 Dateien neu geschrieben; danach führte Claude in einer von der Implementierung getrennten Session zwei adversarielle Reviews durch

Parallelarbeit mit 64 AI-Agenten

  • Die Arbeit wurde so aufgeteilt, dass Dateien unabhängig voneinander bearbeitet werden konnten, und 64 AI-Agenten liefen parallel
  • Anfangs entstanden Konflikte, weil mehrere Agenten denselben Repository-Stand bearbeiteten
    • Ein Agent führte git stash aus, danach führten andere Agenten git stash pop und git reset HEAD --hard aus
    • Jedem Agenten ein eigenes Worktree zuzuweisen scheiterte am Speicherplatz wegen der Größe des Bun-Repositories; zudem mussten die Änderungen am Ende ohnehin gemeinsam kompiliert werden
  • Der Workflow wurde angepasst: Mit Ausnahme von Befehlen zum sofortigen Committen bestimmter Dateien wurden Git-Befehle wie git stash und git reset verboten; auch cargo und lang laufende Befehle durften nicht verwendet werden
  • Am Ende wurde die Arbeit auf 4 Worktrees verteilt, in denen jeweils 16 Claude-Instanzen Dateien committen und pushen sollten
  • In zwei Tagen übertrugen die Agenten 535.496 Zeilen Zig-Code; jeder Commit durchlief vor der Übernahme zwei adversarielle Reviews

Compilerfehler und Test-Fixes

  • Die erste Konvertierung war abgeschlossen, aber der Code kompilierte nicht; daher ließ Bun Claude die Fehler pro Crate, also pro oberster Rust-Kompilationseinheit, beheben
  • Im Abschnittstitel ist von etwa 1.600 Compilerfehlern die Rede, im Zitat jedoch davon, dass beim Auflösen zyklischer Abhängigkeiten rund 16.000 Fehler sichtbar wurden
  • Auch das Beheben der Fehler wurde parallelisiert
    • In jeder Crate wurde cargo check ausgeführt
    • Die Ausgabe wurde dateiweise gebündelt und Fehlerdateien wurden gespeichert
    • Sämtliche Compilerfehler der jeweiligen Crate wurden behoben
    • Zwei adversarielle Reviewer prüften die Änderungen
    • Ein Agent für Korrekturen übernahm die Review-Ergebnisse
  • Von Mitternacht bis 11:30 Uhr vormittags behoben die Agenten Compilerfehler ohne menschliches Eingreifen
  • Anschließend wurde in etwa zwei Tagen die große Test-Suite so weit gebracht, dass sie lokal ohne Compilerfehler lief; danach flossen noch mehrere Tage in das Beheben fehlschlagender Tests, bis CI erfolgreich war
  • Nachdem alle Tests bestanden und die Funktion bestätigt war, wurden die Änderungen gemergt; von der Planung bis zum Abschluss dauerte es insgesamt 11 Tage
    • Portierung von rund 550.000 Zeilen Code
    • 6.500 Commits
    • Einsatz von 64 Agenten

Kosten und Ergebnis im Vergleich zu manueller Arbeit

  • Nach Fable-API-Preisen beliefen sich die Gesamtkosten der Neuschreibung auf 165.000 US-Dollar
    • 5,9 Milliarden nicht gecachte Input-Token
    • 690 Millionen Output-Token
    • 72 Milliarden gelesene Cache-Input-Token
  • Anthropic verkauft API-Token mit Marge, daher dürften die tatsächlichen internen Kosten darunter liegen
  • Die API-Kosten entsprechen etwa dem jährlichen Grundgehalt eines Software-Ingenieurs auf mittlerem Niveau in den USA, doch ein einzelner Ingenieur in derselben Gehaltsklasse könnte das gleiche Ergebnis in 11 Tagen unmöglich erreichen
  • Das passt auch zu Mitchell Hashimotos Einschätzung, dass Fable besonders stark bei schwierigen, fokussierten Aufgaben mit klarer Reward Function ist
  • Bei manueller Arbeit wären voraussichtlich drei Ingenieure nötig gewesen, die die Codebasis vollständig kennen, und zwar für etwa ein Jahr
    • In dieser Zeit wären Verbesserungen der Node.js-Kompatibilität, Bug- und Security-Fixes sowie neue Features kaum vorangekommen
    • Die realistische Alternative wäre gewesen, nicht neu zu schreiben und stattdessen die bestehenden Memory Bugs weiter zu flicken

Voraussetzungen für den Einsatz in anderen Projekten

  • Wenn AI eine einjährige Neuschreibung oder Migration auf etwa eine Woche verkürzen kann, werden auch Projekte machbar, die zuvor kaum ernsthaft in Betracht kamen
  • Um Buns Workflow wiederzuverwenden, sind drei Bedingungen nötig
    • ein Ingenieur, der die Codebasis sehr gut kennt und den starken Willen zur Umsetzung hat
    • eine ausreichend starke Test-Suite, deren Bestehen als Nachweis für reales Funktionieren vertrauenswürdig ist
    • die Bereitschaft, erhebliche Token-Kosten zu investieren, obwohl der Erfolg im Voraus nicht sicher ist
  • Wiederholbare Arbeiten wie Code-Migrationen können LLMs vergleichsweise gut bearbeiten; mit guten Tests und einem Ingenieur, der das Problem strukturieren kann, stehen die Erfolgschancen hoch
  • Nicht jedes Projekt braucht 165.000 US-Dollar
    • Bei einfacheren Projekten können die Kosten geringer ausfallen
    • Für die High-Level-Planung kann das teuerste Modell verwendet werden, während für Coding und Reviews günstigere Modelle eingesetzt werden können
  • AI-basierte Migrationen werden schneller, aber Geschwindigkeiten wie bei Bun lassen sich nur in gut entwickelten Projekten erreichen

Noch keine Kommentare.

Noch keine Kommentare.