Bencher entwickeln im Jahr 2026: Open Source, eigenfinanziert und voll auf Agenten-Kurs

Everett Pompeii

Everett Pompeii


Dieser Essay wurde ursprünglich am 4. Oktober 2026 bei The Pragmatic Engineer’s How Software Engineering is Changing Essay Challenge eingereicht.

Dieses Jahr hat die Art und Weise, wie ich Software baue, radikal verändert. Ich bin Staff Software Engineer. In den letzten sechs Jahren habe ich beruflich mit Rust gearbeitet, sowohl für ein von YC und a16z finanziertes Unicorn als auch für ein Fortune-500-Unternehmen. Als trockener C++-Entwickler fühlte ich mich von der Tiefe und dem Können angezogen, die Rust verlangte. Ich war zu einem meisterhaften Handwerker geworden, der Echtzeit-Systemsoftware von Hand meißelte. In den letzten zehn Monaten musste ich diese Identität zu Grabe tragen. Auch wenn in meinem Jobtitel immer noch „Software Engineer“ steht, ist mein Job jetzt der eines „Context Engineers“.

In den letzten vier Jahren habe ich meine Abende und Wochenenden damit verbracht, ein eigenfinanziertes Open-Source-Unternehmen aufzubauen: Bencher. Bencher ist eine Plattform für kontinuierliches Benchmarking, die Systemsoftware-Entwicklern hilft, Leistungsregressionen abzufangen, bevor sie gemergt werden. Dafür braucht es eine ganze Reihe von Werkzeugen: eine CLI, einen API-Server und eine Web-Konsole als Frontend. Jede dieser Komponenten wurde, bis auf einen Rundungsfehler, von mir geschrieben. Ich hatte im Laufe der Jahre ein paar namhafte Open-Source-Mitwirkende, aber der weitaus größte Teil von Bencher als Open-Source-Projekt und 100 % von Bencher als Unternehmen wurden von mir selbst entworfen und umgesetzt.

In diesen vier Jahren habe ich nicht nur im stillen Kämmerlein gesessen. Ich habe mich verlobt, geheiratet und mein erstes Kind bekommen. Es dauerte Wochen und manchmal Monate, bis ich ein großes Feature fertig implementiert und ausgerollt hatte. Ich musste Entwicklung und Support unter einen Hut bringen. Bencher hatte bereits viele Nutzer, also verbrachte ich ziemlich viel Zeit damit, Fragen zu beantworten und den gelegentlichen Bug zu beheben.

Damals im Jahr 2022 bestand meine Nutzung von LLMs aus der kostenlosen Rust-Version von TabNine, einem Entwicklerwerkzeug zur Autovervollständigung per Tab-Taste, gebaut von einem Studenten, der früh als Praktikant bei OpenAI an diesem putzigen kleinen Projekt namens Codex arbeitete. Als GitHub Copilot startete und inoffiziell Rust-Unterstützung bekam, habe ich die 10 $/Monat für eine persönliche Lizenz berappt.

Es war holprig. Aber es fühlte sich trotzdem ein bisschen wie Magie an. Ich weiß noch, wie beeindruckt ich war, kurz nachdem der Chat zur GitHub Copilot VSCode-Erweiterung hinzugekommen war, wie gut er Rust-prozedurale Makros erstellen konnte. Normalerweise musste ich die Ausgabe noch etwas anpassen, aber ein paar Mal hat er es tatsächlich auf Anhieb hinbekommen. Der Wahnsinn! Das war cool und hat wahrscheinlich etwas Zeit gespart, aber im Großen und Ganzen arbeitete ich immer noch genauso wie vorher.

Von da an hatte ich die Vorstellung, dass Microsoft mit GitHub Copilot an der Spitze stand. Selbst wenn diese neumodischen Labs irgendwelche „Agenten“ in die Welt warfen, konnte ich mich darauf verlassen, dass GitHub Copilot mithalten würde, falls etwas Brauchbares dabei war. Ich hörte Leute wie Dan Shipper im Lenny’s Podcast, und ihre Schilderung der Fähigkeiten der Modelle passte einfach nicht zu meiner Erfahrung oder zu meinen Qualitätsansprüchen.

Anfang letzten Jahres schrieb ich einen Beitrag, in dem ich auf drei Jahre Bencher-Entwicklung zurückblickte: Ingenieurbericht: Ausgabe 2025. Darin ging ich auf all meine wichtigen technischen Entscheidungen beim Aufbau von Bencher ein, quer durch Frontend, Backend, Entwicklungsumgebung, CI und so weiter. Einen ganzen Absatz lang ließ ich Dampf darüber ab, wie schwer es mir zwei Jahre zuvor gefallen war, mich in CUE lang hineinzudenken. Und doch findet sich in diesem 3.500 Wörter langen Text nicht eine einzige Erwähnung von KI, LLMs oder auch nur Copilot.

Spulen wir vor zu weniger als einem Jahr später, und ich trauere mit We mourn our craft.

Claude hilft, Weihnachten zu retten

Wie viele andere hatte ich über die Feiertage im Winter 2025 die Gelegenheit, Claude Opus 4.5 so richtig zu nutzen. Ich war mit meiner Frau und meinem Kind in London bei der Familie meiner Schwester zu Besuch. Meine Schwester hatte gerade Zwillinge bekommen, also sollte ich eigentlich dort sein, um zu helfen. Stattdessen hatte ich mich oben verschanzt und versuchte, E-Mail-Spam und DDoS-Angriffe auf Bencher abzuwehren. Claude war super hilfreich dabei, zu diagnostizieren, was da vor sich ging, und mögliche Lösungen zu entwickeln.

Am Ende habe ich Bencher hinter Cloudflare migriert und reCAPTCHA eingerichtet. Den Großteil der Arbeit habe immer noch ich gemacht, aber Opus 4.5 war ein spürbarer Fortschritt in seiner Fähigkeit, Probleme über viele konkurrierende Designvorgaben hinweg zu lösen. Allerdings schlug er mir auch eine Änderung vor, die das Komfort-Skript zur Installation der Bencher CLI für einen halben Tag lahmlegte. Hoppla.

Neues Jahr, neuer Harness

Bis zum Januar dieses Jahres hatte ich schon monatelang gehört, wie beeindruckend Claude Code sei. Ich hatte es vorher nicht ausprobiert, weil Opus 4 meine Qualitätsansprüche einfach nicht erfüllte, um seiner Arbeit zu vertrauen. Jetzt, da Opus 4.5 diese Hürde genommen hatte, wollte ich auch Claude Code eine Chance geben. Der Fortschritt, den ich beim Wechsel von Copilot als Harness zu Claude Code sah, war ein genauso großer Sprung wie der Wechsel von Opus 4/GPT-5.2/Gemini 2.5 Pro als Modell zu Opus 4.5.

Gleich an meinem allerersten Wochenende mit Claude Code habe ich einen nicht ganz so kontrollierten Vergleichstest gegen Copilot gemacht. Ich wollte, dass Copilot aus einem PDF ein Hörbuch macht. Selbst im „Agent Mode“ kam Copilot fünf oder sechs Schritte weit und blieb dann einfach stehen, bis ich ihn wieder anstupste. Zur selben Zeit legte Claude Code nach einem gründlichen Durchlauf im Plan mode richtig los und versuchte, einen eigenen Hypervisor zu bauen. Ich war felsenfest davon überzeugt, dass die Abstraktionsebene vom Modell zum Harness aufgestiegen war und dass Copilot nie wieder aufholen würde.

Der Traum von Bencher Bare Metal

Schon seit den allerersten Tagen von Bencher hatte ich davon geträumt, eine Bare-Metal-Flotte für Benchmarks aufzubauen. Herkömmliche CI-Runner sind, weil sie virtuelle Maschinen sind, zu verrauscht, um konsistente Benchmark-Ergebnisse zu liefern. Einen Anstieg der Latenz um, sagen wir, 200 % könnten Sie erkennen, aber einen Anstieg um 20 % würden Sie nie zuverlässig erkennen. Instruktionszahlen sind eine Möglichkeit für Benchmarks in CI. Diese sind weitgehend deterministisch. Allerdings sind Instruktionszahlen nur ein Stellvertreter für das, was Sie eigentlich interessiert: die Wanduhrzeit. Alles, was in einer „CPU-Simulation“ läuft und Instruktionszahlen ausspuckt, kann nur mit der Geschwindigkeit korrelieren. Das Problem ist, dass Sie nie wissen, wie stark oder wie wenig es danebenliegt, solange Sie nicht tatsächlich auf Bare Metal messen.

Einer der allerersten Nutzer von Bencher war das Rustls-Projekt. Ich habe an deren Rustls Bench Runner mitgewirkt. Allerdings war das keine gute Grundlage, um darauf eine Bare-Metal-Flotte für Benchmarks aufzubauen. Er lief auf einem einzigen Host und behandelte alle Benchmark-Workloads als vertrauenswürdig. Das heißt: keine PRs aus Forks und keine Multi-Tenancy. Außerdem wollen die meisten Teams keine 100 $+ pro Monat für jeden Bare-Metal-Server für Benchmarks zahlen.

Ich hatte überlegt, GitHub Actions für die Orchestrierungsebene zu nutzen, aber dieser Ansatz hatte ein paar grundlegende Schwächen. Zunächst einmal ist der GitHub Actions Runner in C# geschrieben. Das bedeutet, dass sein Garbage Collector mitten in Ihrem Lauf anspringen und Ihre Benchmark-Ergebnisse verfälschen könnte. Ach ja, und denken Sie daran, den automatischen Updater abzuschalten, damit er nicht mitten im Lauf anspringt, aber vergessen Sie ihn auch nicht zu lange, sonst laufen Ihre Jobs irgendwann nicht mehr!

Selbst wenn der GitHub Actions Runner ein nettes, leises Rust-Binary gewesen wäre, bestand das grundlegendere Problem darin, dass er an GitHub Actions gebunden war. Bencher ist von Anfang an CLI-first. Ob gut oder schlecht, ich wollte Bencher nie zu eng an einen einzelnen CI-Anbieter binden. Es gibt eine Bencher CLI GitHub Action, aber die installiert nur die CLI für Sie. Ich wollte, dass Bencher Bare Metal überall funktioniert, wo auch die CLI funktioniert, nicht nur in GitHub Actions.

Die Idee, auf die ich kam, war, OCI-Images zu verwenden, um den Benchmark-Workload zu bündeln, und eine optionale, sehr kleine Sandbox, um immer nur einen Job zur Zeit auf einem bestimmten Bare-Metal-Host auszuführen. Die Aussicht, das alles allein an Abenden und Wochenenden aufzubauen, war entmutigend. Mit einem Hauptjob und einer Familie hätte es mindestens ein Jahr gedauert, mich allein Stück für Stück durchzuarbeiten.

Bencher Bare Metal bauen

Mit Opus 4.5 und Claude Code in der Hand hatte ich im Januar dieses Jahres das Gefühl, endlich einen gangbaren Weg zu sehen, um Bencher Bare Metal aufzubauen. Ich habe erneut tief in die Tasche gegriffen, diesmal stolze 200 $/Monat für den Claude Max 20x Plan. Wahrscheinlich die beste Geschäftsausgabe aller Zeiten.

Ich legte richtig los und gab mein Bestes, mein Claude-Kontingent jede Woche voll auszuschöpfen. Ich hörte auf, Code von Hand zu schreiben, sowohl bei Bencher als auch in meinem Hauptjob. Zu diesem Zeitpunkt iterierte ich noch in ziemlich engen Schleifen, nutzte den Plan mode, las die gesamte Ausgabe und arbeitete im Modus Accept edits. Ich traute dem Agenten zu diesem Zeitpunkt noch nicht zu, git/jj anzufassen, also kümmerte ich mich um die gesamte Versionskontrolle selbst. Ich sah mich selbst als eine Ralph Loop mit Human in the Loop. Bei etwa fünf parallel laufenden Agenten fing mein Gehirn an zu schmelzen.

Ein Tipp, den ich gehört hatte, war, die Implementierung und das Review von getrennten Agenten erledigen zu lassen, also fing ich an, separate adversariale Reviews zu machen. Diese adversarialen Reviews schienen die Qualität der Ausgabe wirklich zu verbessern. Ich baute meinen eigenen Review-Bot für GitHub Actions, der den API-Schlüssel meines Claude-Code-Abos nutzte. Dann ließ ich meinen lokalen Agenten mit diesem CI-Reviewer iterieren, um Rechenzyklen auf meinem lokalen Rechner zu sparen.

Irgendwann zwischendurch dachte ich, ich würde Claude einen eigenen Hypervisor für die Benchmark-Sandbox bauen lassen. Dann bat ich Claude, als Linus Torvalds ein adversariales Review des Plans zu machen, und er sagte mir, ich sei dumm und das sei eine sehr, sehr, sehr dämliche Idee. Keine Speichelleckerei, wenn Linus in Ihrem Kontext ist! Also verwarf ich diesen Plan und entschied mich für Firecracker.

Der Feind guter Benchmarks ist die Varianz, nicht die Geschwindigkeit an sich. Auch wenn Firecracker als Hypervisor Overhead hinzufügt, ist es also ein sehr konsistenter Overhead, besonders wenn immer nur eine einzige microVM gleichzeitig läuft. Dadurch können gemeinsam genutzte Bencher Bare Metal Runner sowohl Multi-Tenancy als auch sehr konsistente Benchmark-Ergebnisse bieten. Außerdem habe ich mit Claude im Plan mode das Design so angelegt, dass die Sandbox optional ist. Wenn ein Nutzer auf seinem eigenen dedizierten Server laufen möchte, auf dem er jedem Workload vertraut, dann kann er ohne Firecracker mit nahezu null Overhead laufen.

Die Entwicklung des Bare Metal runner war für mich eine große Lektion darin, wie wichtig eine enge Feedbackschleife für Agenten ist. Selbst nachdem Opus 4.6 herausgekommen war, schien Claude Mühe zu haben, alles zuverlässig zum Laufen zu bringen. Sobald ich ihm Zugang zu einer Entwicklungsumgebung mit aktiviertem KVM gab (was nötig ist, um Firecracker auszuführen), machte es wirklich Klick. Diese Agenten sind nicht allwissend, sie sind einfach unglaublich hartnäckig.

Wie genau ich Claudes Arbeit unter die Lupe nahm, hing davon ab, in welchem Teil der Codebasis er gerade arbeitete. Den Code, der rein für Bare Metal war, etwa die OCI-Registry und das runner-Binary, habe ich nur oberflächlich gereviewt. Solange er das adversariale Review bestand, die End-to-End-Tests durchliefen und die Sache nicht allzu schlimm aussah, habe ich ihn gemergt. Beim Code, der den bestehenden Kern berührte, also Job-Queuing und Report-Verarbeitung, war ich so pingelig wie eh und je.

Ende März dieses Jahres habe ich Bencher Bare Metal als Teil von v0.6.0 veröffentlicht. Für die öffentliche Bare-Metal-Flotte hatte ich überlegt, AWS EC2 Bare Metal zu nutzen. Allerdings sind diese Maschinen sowohl gewaltig als auch nur mit ARM erhältlich. Um den meisten realen Workloads zu entsprechen, wollte ich bodenständige Intel-x86-Maschinen. Ich recherchierte mit Claude, um das beste Zuhause für die Flotte zu finden, das die Designvorgaben erfüllt. Am Ende konnten wir auf Bencher Cloud die intel-v1 Spec anbieten, die Nutzern 4 vCPUs, 48 GB Arbeitsspeicher und 128 GB Festplatte bietet, minutengenau abgerechnet. Bei gut strukturierten Benchmarks erreichte ich durchweg <2% Varianz zwischen den Läufen über die gesamte Flotte hinweg.

Authentifizierung für Agenten

Bis zu Bencher Bare Metal lief die gesamte Authentifizierung über JWTs. Große, schöne, unverständliche JWTs. Die Authentifizierung für Bare Metal Runner war ein API-Schlüssel mit Namenspräfix, z. B. bencher_runner_abc123....

Auf der Client-Seite wollte ich Agenten etwas anderes an die Hand geben als das eigene API-Token-JWT eines Nutzers. Der Mittelweg, den ich fand, war, endlich ein lang gewünschtes Feature umzusetzen: projektbezogene Authentifizierung. Claude half mir, sichere, projektbezogene API-Schlüssel mit Präfix zu erstellen. Diese API-Schlüssel sind auf die Berechtigungen beschränkt, die dem entsprechen, was der CLI-Befehl bencher run ausführt: projektbezogene Lesezugriffe und nicht destruktive Schreibzugriffe. Das macht diese API-Schlüssel auch zu einer natürlichen Wahl für Workflows für kontinuierliches Benchmarking in CI.

Als ich später den Bencher MCP hinzufügte, wurden diese projektbezogenen API-Schlüssel auch dort für die Authentifizierung verwendet. Der MCP-Standard nennt OAuth 2.1, das allerdings noch ein Entwurf ist, also wollte ich es noch nicht implementieren. Ehrlich gesagt bin ich ein bisschen ein MCP-Skeptiker. Ich denke immer noch, dass eine gute CLI + Skills ein effektiverer und portablerer Weg ist, einen Dienst für einen Agenten bereitzustellen. Das größte Problem von CLIs ist allerdings, dass ihnen ein standardisierter Authentifizierungsmechanismus fehlt. Auch wenn OAuth 2.1 also noch ein Entwurf ist, hat MCP das wenigstens abgedeckt. Und eine gute Antwort auf die Authentifizierungsfrage ist für Unternehmenskunden wirklich wichtig.

Claude, der Polyglotte

Im Jahr 2023 beschloss ich, dass die Bencher-Dokumentation in 9 Sprachen verfügbar sein sollte: Englisch, Chinesisch, Spanisch, brasilianisches Portugiesisch, Russisch, Japanisch, Französisch, Deutsch und Koreanisch. Wie habe ich diese neun Sprachen ausgewählt? Das sind die Sprachen, in denen die GitHub-Dokumentation verfügbar war, also dachte ich mir, das sei eine ausreichend gute Annäherung. Das einzige Problem: Ich spreche nur Englisch fließend. Also ließ ich GPT-4 die Dokumentation für mich übersetzen. Damals hatte GPT-4 nur ein Kontextfenster von 8k Tokens. Das bedeutete, dass ich alle meine Dokumentationsseiten in „Chunks“ mit weniger als 8k Tokens aufteilen musste. Dann musste ich ein CLI-Tool bauen, um das Übersetzen und sehr oft das erneute Übersetzen von Chunks zu übernehmen, nachdem diese aktualisiert worden waren.

Das war ein sehr mühsamer und fehleranfälliger Prozess. Ich musste die übersetzten Dateien von Hand nachbearbeiten, denn selbst mit sehr expliziten Anweisungen im System-Prompt verhunzte das Modell noch Importpfade oder packte alles in eine weitere Ebene eines Markdown-Blocks, aus irgendeinem Grund besonders auf Japanisch.

Als ich anfing, Claude Code mit Opus 4.5 zu nutzen, war das alles vorbei. Jetzt macht der Agent es einfach. Die Konvention dafür, was einen Chunk ausmacht, steht in der Codebasis, und Claude hält sich einfach daran. Als ich die technische Dokumentation für Bencher Bare Metal schrieb, kümmerte sich Claude einfach um das Aufteilen in Chunks und die Orchestrierung der Übersetzungen. Auch wenn die Kontextgröße inzwischen mehr als groß genug für eine ganze Seite ist, mag ich die Chunks. Die Chunks helfen, Änderungen isoliert zu halten, sodass bei einer Überarbeitung nur die relevanten Abschnitte einer Seite neu übersetzt werden.

Wer hat 2026 keinen Harness gebaut?

Während ich Bencher Bare Metal baute, ließ ich Claude auch Werkzeuge für sich selbst erstellen, um die Flotte zu verwalten. Das bestand aus zwei Teilen: einer CLI im bencher-Repo für Routineaufgaben und einem neuen Meta-Repository (Meta-Repo). Dieses Meta-Repo enthält die gesamte Dokumentation und den gesamten Kontext zu Bencher als Produkt. Jedes andere Repo in der GitHub-Organisation bencherdev ist ein Submodul in diesem Meta-Repo. Das Meta-Repo ermöglicht es dem Agenten, problemlos an einer Aufgabe zu arbeiten, die sich über mehrere Repositories erstrecken kann, und Dokumente zu schreiben, die ich lieber nicht öffentlich hätte (Produktstrategie, Incident-Berichte usw.).

Ich wollte meinen eigenen Agenten auf Basis der Claude Code CLI bauen, der dieses Meta-Repo von einem bloßen Artefakt zu einem proaktiven Teil des Entwicklungszyklus machen würde. Als Fable 5 verfügbar wurde, steckte ich einen Großteil meiner Energie in den Bau dieses Agenten. Ich wollte diesem Agenten vertrauen können, autonom zu laufen. Ein großer Teil davon war Sicherheit (also die Abwehr von Prompt Injections). Ich habe es so entworfen, dass Worker-Agenten niemals irgendwelche Secrets besitzen. Alle Secrets werden von einem Netzwerk-Proxy injiziert und sind auf freigegebene Endpunkte beschränkt. Die Agenten selbst liefen in noch einer weiteren Firecracker microVM, diesmal parallel. Die Steuerungsmaschine für die Agenten und der Netzwerk-Proxy + Sandboxes liefen auf völlig unterschiedlichen Hosts.

Meine große Vision war, dass die Oberfläche eine Warteschlange ist, sortiert nach Priorität der Aufgaben. Das heißt, das Ziel dieses Agenten wäre es, mir in jedem Moment die wichtigste Aufgabe zu zeigen. Während die Feeds von Facebook/Instagram/Twitter/X/TikTok auf Engagement optimiert sind, wäre dieser Feed darauf optimiert, was für mich wichtig ist.

Ich wollte das Werkzeug erschaffen, das mich selbst unter die API stellen würde. Ich hatte festgestellt, dass ich die meiste Zeit mit Kontextwechseln und dem Springen zwischen Threads verbrachte. Meine Hoffnung war, dass der Agent dieses Jonglieren erleichtern könnte, indem er die Dinge für mich in eine Rangfolge bringt. Mit einem Upvote/Downvote-System wie bei Reddit könnte ich dem Agenten beibringen zu erkennen, ob diese neue Slack-Nachricht wirklich das Wichtigste ist, dem ich meine Aufmerksamkeit schenken sollte.

Ich habe außerdem festgestellt, dass ein großer Teil meines Jobs jetzt darin besteht, der Rubeus Hagrid meines Agenten zu sein, sein „Hüter der Schlüssel“. Die Injektion auf Ebene des Netzwerk-Proxys mit einer eingeschränkten Allowlist für Endpunkte war der beste Weg, den Claude und ich finden konnten, um den Agenten einerseits niemals an ein Secret herankommen zu lassen und ihm andererseits trotzdem zu ermöglichen, Werkzeuge wie die gh CLI direkt zu nutzen.

Das andere große Ziel war, die Agenten-Oberfläche niemals zu verlassen. Vom Agenten wegzunavigieren, aus welchem Grund auch immer, gilt als Versagen des Harness. Ich habe ein prozedurales UI-Komponentensystem gebaut, damit der Agent, der an einer Aufgabe arbeitet, spontan eine neuartige Oberfläche bauen oder je nach Aufgabe eine der vorhandenen Komponenten aus der Bibliothek auswählen kann. Code, E-Mail, Slack, Kalender, Telemetriedaten aus der Produktion, Fehlerüberwachung, alles in einer Oberfläche, alles in einer priorisierten Warteschlange.

Eine minimale Version von alldem habe ich zum Laufen gebracht. Allerdings gibt es noch viele Ecken und Kanten. Derzeit bin ich deutlich produktiver, wenn ich einfach die Claude Desktop-App nutze. Und im Moment brauche ich so viel unmittelbare Produktivität wie möglich, um mit der Nachfrage Schritt zu halten.

Was passiert, wenn sich die Zahl der Entwickler verhundertfacht?

Im Jahr 2022 war ich auf der Suche nach einem neuen Nebenprojekt. Mein vorheriges Möchtegern-Gründer-Abenteuer hatte ich 2020 eingestellt. Profi-Tipp: Hören Sie auf Jason Cohen und versuchen Sie nicht, einen Marktplatz eigenfinanziert aufzubauen.

In meinem Hauptjob baute ich einen statischen Bash-Parser und -Analyzer in Rust, und ich stellte fest, dass ich eine Tabellenkalkulation benutzen musste, um meine Benchmark-Ergebnisse zu verfolgen. Das Rust-Projekt hat rustc-perf, um die Leistung des Compilers selbst zu verfolgen. Doch für meinen eigenen Code gab es kein gutes Werkzeug dafür.

Ich habe sehr viel zum Stand der Technik in diesem Bereich recherchiert. Im Laufe einiger Monate führte ich Gespräche mit mehreren Entwicklern, die Werkzeuge für kontinuierliches Benchmarking entweder gebaut oder sich für deren Bau eingesetzt hatten. Alle erfanden das Rad neu. Ich dachte, ich hätte ein schönes, ruhiges Plätzchen im Gewässer des Marktes gefunden. Es gab einen offensichtlichen, anhaltenden Bedarf. Viele Teams zahlten bereits mehr als 100 $/Monat für ihre eigenen Bare-Metal-Runner. Es gab also Zahlungsbereitschaft. Doch der Anwendungsfall war eine Nische. Die meiste moderne Software wird als Dienst bereitgestellt, daher hatte es für die meisten Teams keine hohe Priorität, Performance-Tests nach links zu verschieben. Die Teams richteten einfach nach dem Deployment Alerts in Grafana ein und fingen post hoc alles ab, was durchgerutscht war.

Mit dem Aufkommen hochleistungsfähiger Agenten haben jedoch zwei Faktoren die Nutzung von Bencher stark ansteigen lassen:

  1. Die Notwendigkeit, Best Practices der Softwareentwicklung zu übernehmen, um die Ausgabe von Agenten deterministisch zu testen
  2. Die Leichtigkeit, mit der sich Best Practices der Softwareentwicklung mit Hilfe von Agenten übernehmen lassen

LLMs und damit auch Agenten sind nichtdeterministische, stochastische Systeme. Wie menschliche Entwickler brauchen sie Leitplanken, um sicherzustellen, dass sie die Codequalität aufrechterhalten. Die Mittel dafür sind nicht neu: ein robustes Typsystem, ein Standard-Formatter, ein Linter, der auf 11 aufgedreht ist, Tests, Tests und noch mehr Tests. Alles läuft in CI. Bei leistungskritischen Workloads gehören zu diesen Tests auch Benchmarks, die verfolgt werden. Wenn Sie die Leistung von Software über die Zeit verfolgen, können Sie Leistungsregressionen in CI abfangen. Das nennt man kontinuierliches Benchmarking. Kontinuierliches Benchmarking einzuführen war schon immer ein bisschen lästig. Nur Teams, denen Leistung wirklich, wirklich wichtig war, haben es gemacht, und sie waren großartige Bencher-Nutzer!

Mit dem Aufkommen von Agenten ist der Aufwand, kontinuierliches Benchmarking mit Bencher in Ihren Workflow einzubauen, jedoch auf einen kurzen Prompt geschrumpft. Es ist schwer, das vollständig nachzuverfolgen, aber ich würde wetten, dass die große Mehrheit der eingehenden Anmeldungen bei Bencher inzwischen auf die Empfehlung eines Agenten zurückgeht oder darauf, dass ein Agent es gleich selbst erledigt. Das wird mit der Zeit nur noch mehr zutreffen, je mehr Entwickler Agenten einsetzen und sie mit Agentic Commerce ausstatten. Ob es nun das x402-Protokoll wird oder nicht, ich glaube, dass künftig ein Großteil der Ausgaben für Entwicklerwerkzeuge über Agenten abgewickelt wird. Ich empfehle Ihnen, Ihre Cloudflare Wallet und Ihre Stripe Wallet zu reservieren, falls Sie das noch nicht getan haben.

Fast alle Entwicklerwerkzeuge werden im Zeitalter der Agenten auf nutzungsbasierte Preise umsteigen müssen. Preise pro Arbeitsplatz ergeben keinen Sinn, wenn es Agenten sind, die Ihren Dienst nutzen. Bencher hatte schon immer nutzungsbasierte Preise. Mit Hilfe von Claude habe ich das Preismodell jedoch kürzlich überarbeitet, um es noch agentenfreundlicher zu machen. Bisher hat Bencher pro Metrik abgerechnet. Eine Metrik ist ein einzelnes, zeitpunktbezogenes Benchmark-Ergebnis. Wenn Sie zum Beispiel 1 Benchmark haben und ihn 5-mal ausführen, entstehen dabei 5 Metriken. Claude half mir, Nutzerfeedback und Nutzungsmuster zu analysieren. Ich kam zu dem Schluss, dass sich die Einheit ändern musste, die wir für unser nutzungsbasiertes Preismodell verwendeten. Jetzt rechnet Bencher pro Benchmark-Serie ab. Eine Benchmark-Serie ist ein Benchmark, der über die Zeit verfolgt wird. Zurück zu unserem Beispiel: Wenn Sie 1 Benchmark haben und ihn 5-mal ausführen, ist das 1 Benchmark-Serie. Dieses neue Preismodell gibt Nutzern deutlich mehr Planbarkeit. Sie können einem Agenten ein Optimierungsproblem geben, und er kann per Hill Climbing auf Ihren historischen Benchmarks optimieren, ohne dass zusätzliche Kosten anfallen.

Eine Sache, bei der ich im vergangenen Jahr keine Veränderung gesehen habe, sind Open-Source-Beiträge. Bencher hat ein paar KI-Slop-PRs bekommen. Das Hauptproblem bei diesen PRs war, dass sie zufällige, nicht zusammenhängende Bugs behoben, über die sie unterwegs zufällig gestolpert waren. Es waren aber trotzdem echte Bugs! Also habe ich einfach mit den Schultern gezuckt und die PRs gemergt, nachdem natürlich mein eigener Agent sie gereviewt hatte. Es ist ein bisschen traurig, aber ich sehe keinen großen Nutzen mehr darin, um Open-Source-Mitwirkende zu werben. Ob es ihre Tokens sind oder meine, ich muss trotzdem genauso viel Aufwand in das Review des Codes stecken. Inzwischen kostet es viel mehr Energie, den PR eines Mitwirkenden zu reviewen, als selbst mit Claude zu iterieren.

Wie sieht die Zukunft des kontinuierlichen Benchmarkings aus?

Wenn man versucht vorherzusagen, was die Zukunft bringt, scheint das Muster zu sein, dass wir uns ansehen sollten, was die Frontier Labs selbst tun. In sechs bis zwölf Monaten werden wir alle dort sein, so scheint es. Inside OpenAI’s agentic software factory von The Pragmatic Engineer wirft dazu aus der Perspektive des kontinuierlichen Benchmarkings ein interessantes Licht:

Neu: ein „Perf-Harness“: Der Agent nutzt außerdem einen Perf-Harness, um problematische PRs an das Synthetics-A/B-Framework zu schicken, das die Auswirkungen auf die Leistung bewertet. Wie oben erwähnt, ist die Last auf CI-Systemen in den letzten sechs Monaten stark gestiegen.

OpenAIs „Perf-Harness“ scheint der etablierten Praxis des relativen kontinuierlichen Benchmarkings sehr ähnlich zu sein. Das neuartige KI-Element ist der synthetische Teil des A/B-Frameworks. Synthetische Testdaten sind nicht neu. Aber diese synthetischen Daten autonom so zu gestalten, dass sie die Leistung des jeweiligen Changesets bewerten, ist definitiv neu! Entwickler dazu zu bringen, die Benchmarks tatsächlich zu schreiben, war schon immer der Knackpunkt. Jetzt ist das automatisiert. So wie Agenten die Testabdeckung für Features drastisch erhöht haben, ermöglichen sie es uns auch, die Abdeckung durch Performance-Tests drastisch zu erhöhen.

OpenAI ist mit diesem Vorhaben nicht allein. Kurz darauf veröffentlichte Anthropic How we made claude.ai 3x faster in two weeks. Darin beschreiben auch sie, wie sie Benchmarks spontan erstellen. Ein wesentlicher Unterschied war, dass Anthropic deterministische Zählwerte gefunden hat, die mit der Leistung korrelieren: Instruktionen, Commits pro Interaktion, Funktionsaufrufe, Style-Neuberechnungen und DOM-Mutationen. Claude optimierte dann diese Zählwerte per Hill Climbing, um die Leistung ihrer App zu verbessern. Am Ende des Optimierungsdurchlaufs prüften sie, ob ihre zählwertbasierten Optimierungen tatsächlich zu echten Verbesserungen der Wanduhrzeit geführt hatten.

Diese Methoden decken sich mit dem, was ich selbst bei der Arbeit an Bencher erlebe. Allerdings liefen meine A/B-Performance-Tests alle lokal oder auf dem Arbeitsrechner eines Agenten, nicht in einer CI-Schleife. Immer wenn ich kurz davor bin, eine große Änderung an einer Abfrage oder eine bedeutende Schema-Migration vorzunehmen, lasse ich Claude eine erschöpfende Leistungsbewertung der Änderung durchführen. Dazu gehört immer die Wanduhrzeit und gelegentlich einige ergänzende deterministische Zählwerte (z. B. SQLite-VM-Instruktionen).

Wegen Noisy-Neighbor-Problemen hatten diese von Agenten geführten Optimierungsdurchläufe ziemlich große Fehlerbalken. Ich plane, Bencher Bare Metal um Fixtures (zusätzliche Benchmark-Eingaben) und Artefakte (zusätzliche Benchmark-Ausgaben) zu erweitern, damit mein Agent diese Optimierungsaufgaben mit höherer Zuverlässigkeit ausführen kann. Der Agent wird den Großteil seiner Optimierungsarbeit weiterhin lokal erledigen und so gut es geht per Hill Climbing auf Wanduhrzeit oder deterministische Zählwerte optimieren. Dann wird er Bencher Bare Metal nutzen, um seine Arbeit zu überprüfen, als eine Art Messschieber für die Wanduhrzeit.

Auch wenn ich glaube, dass die meisten „Nutzer“ von Bencher in etwa einem Jahr Agenten sein werden, denke ich trotzdem, dass die meisten Menschen eine visuelle Oberfläche haben wollen, wenn sie mal reinschauen. Ich stecke gerade bis zum Hals in einer kompletten Neugestaltung der Bencher-UI mit Hilfe von Claude. Als Rust-Entwickler, der zu Zeiten der Tab-Autovervollständigung von GitHub Copilot Anyscript schrieb, lässt die aktuelle UI einiges zu wünschen übrig. Die Neuentwicklung der UI wartet allerdings auf eine andere, noch ehrgeizigere Überarbeitung: eine neue Version des Bencher Metric Format (BMF).

BMF ist das zentrale Format, auf das Benchmark-Ergebnisse innerhalb von Bencher normalisiert werden. Es zieht sich durch alles. Diese neue Version von BMF wird es ermöglichen, Benchmarks zu parametrisieren. Sie werden my_benchmark mit den Parametern size: 16 MB und size: 32 MB angeben können, statt zwei separate Benchmarks zu haben, my_benchmark_16_mb und my_benchmark_32_mb. Die neue Version von BMF wird außerdem beliebige Metriknamen erlauben. Sie werden die Metriken mean, p95 und p99 für Ihre Latency-Maße angeben können, statt nur mean zu haben oder Latency (mean), Latency (p95) und Latency (p99) als separate Maße anlegen zu müssen.

Die Unterstützung dieser neuen BMF-Version ist eine gewaltige Überarbeitung des Kerns von Bencher. Mit irgendetwas vor Fable 5 hätte ich mich bei dieser Arbeit nicht wohlgefühlt. Wie oben besprochen, lag der Großteil der Bare-Metal-Arbeit orthogonal zum Kern von Bencher: der Verfolgung der Leistung über die Zeit und dem Alarmieren bei Regressionen. BMF ist zentral für dieses Kernversprechen. Mein Vertrauen in Fable 5 und noch mehr in Fable 5.1 und Opus 5.5 hat es mir wieder einmal ermöglicht, ein Projekt anzugehen, für das ich sonst Jahre an Abenden und Wochenenden gebraucht hätte. Früher musste ich ziemlich viel Zeit damit verbringen, SQLite für Bencher zu optimieren. Jetzt bitte ich Claude jedes Mal, wenn ich das Modell weiterentwickle, einfach einen Agenten zu starten, der eine gründliche Leistungsuntersuchung durchführt, um sicherzustellen, dass alles weiterhin performant ist. In Zukunft glaube ich nicht einmal, dass ich noch fragen muss.

Wie ich heute programmiere

Als ich noch GitHub Copilot benutzte, war das eine Erweiterung in VSCode. Als ich zum ersten Mal zu Claude Code wechselte, nutzte ich die CLI. Ich hatte drei Terminalfenster, jedes in seinem eigenen macOS Space. Jedes Terminalfenster hatte zwei Tabs. Ein Tab war für Claude, der andere für Jujutsu (jj). Ich verwaltete die Versionskontrolle und die jj-Workspaces noch selbst.

Heutzutage nutze ich einfach die Claude Code Desktop-App. Jede neue Session starte ich aus meinem Meta-Repo mit aktivierter worktree-Checkbox. Den Plan mode nutze ich seit ein paar Monaten nicht mehr. Matt Pococks /grill-me-Skill habe ich nie installiert. Ich bitte Claude im Prompt einfach, mich „zu allen Designentscheidungen zu grillen“, und inzwischen weiß das Modell, was zu tun ist. Meine CLAUDE.md AGENTS.md ist ziemlich gut darauf abgestimmt, wie sich das Modell verhalten soll.

Meinen Claude Review CI-Workflow habe ich so gut wie stillgelegt. Der Agent startet jetzt lokal einen adversarialen Reviewer, ohne dass ich überhaupt fragen muss. Dann iterieren die beiden, bis sie sich einig sind, manchmal bis zu einem halben Dutzend Runden. Ich habe angefangen damit zu experimentieren, Entwicklungsarbeit auf externe Arbeitsrechner auszulagern und meinen lokalen Rechner nur noch als Orchestrator zu nutzen.

Die Versionskontrolle fasse ich nur noch selbst an, wenn ich einen Build auschecken will, um selbst etwas zu testen, oder wenn ich ein getaggtes, versioniertes Release von Bencher erstelle. Das passiert etwa einmal pro Woche bzw. einmal pro Monat. Ansonsten überlasse ich das inzwischen einfach Claude. Ich nutze ausgiebig Draft-PRs und, jetzt wo sie auf GitHub verfügbar sind, auch Stacked PRs. Den Code sehe ich mir erst an, wenn der PR offen ist. Beim Code für Bencher scrolle ich zwar immer noch durch, aber das ist inzwischen eher ein Plausibilitätscheck als ein echtes Code-Review.


Wenn ich in einem Jahr zurückblicke und noch einmal lese, was ich hier geschrieben habe, werde ich dann wieder einen „Du hast KI nicht einmal erwähnt‽“-Moment haben? Die eine Hälfte von mir findet, wie großartig das wäre. Die andere Hälfte hat eine Heidenangst davor.


Bencher: Kontinuierliches Benchmarking

Bencher ist eine Suite von Tools für kontinuierliches Benchmarking. Hatten Sie jemals eine Performance Regression, die Ihre Nutzer beeinflusste? Bencher hätte das verhindern können. Bencher ermöglicht es Ihnen, Leistungsregressionen zu erkennen und zu verhindern, bevor sie gemergt werden.

  • Ausführen: Führen Sie Ihre Benchmarks lokal oder in CI mit exakt denselben Bare-Metal-Runnern und Ihren bevorzugten Benchmarking-Tools aus. Das bencher CLI orchestriert die Ausführung Ihrer Benchmarks auf Bare Metal und speichert die Ergebnisse.
  • Verfolgen: Verfolgen Sie die Ergebnisse Ihrer Benchmarks im Laufe der Zeit. Überwachen, abfragen und grafisch darstellen der Ergebnisse mit der Bencher Web Konsole auf Basis des Quellzweigs, Testbetts und Maßnahme.
  • Auffangen: Fangen Sie Leistungsregressionen lokal oder in CI mit exakt derselben Bare-Metal-Hardware ab. Bencher verwendet modernste, anpassbare Analysen, um Leistungsregressionen zu erkennen, bevor sie gemergt werden.

Aus denselben Gründen, warum Unit Tests laufen, um Feature Regressionen zu verhindern, sollten Benchmarks mit Bencher ausgeführt werden, um Leistungsregressionen zu verhindern. Performance-Bugs sind Fehler!

Beginnen Sie damit, Leistungsregressionen aufzufangen - probieren Sie Bencher Cloud kostenlos aus.

🤖 Dieses Dokument wurde automatisch von KI übersetzt. Es ist möglicherweise nicht korrekt und kann Fehler enthalten. Wenn Sie Fehler finden, öffnen Sie bitte ein Problem auf GitHub.