Veröffentlicht am: 8. Juli 2026

8 Minuten Lesezeit

Wie ein GitLab-Team das Rate-Limiting mit KI-Agenten migrierte

Ein dreiköpfiges Team migrierte GitLabs Rate-Limiting mit der Duo Agent Platform. Was funktionierte und was der Ablauf übersah.

Ein kleines Team bei GitLab hat in den vergangenen Wochen ein Experiment durchgeführt: Lässt sich ein Teil unseres gewachsenen Rate-Limiting-Systems mit KI-Agenten migrieren, ohne dabei Abstriche bei der Sicherheit zu machen?

Kurze Antwort: ja. KI-Agenten funktionieren. Sie können allerdings auch offenlegen, wo die eigenen Arbeitsweisen Schwächen haben. Wichtiger als die Agenten waren das Team, der Ablauf und die Beobachtbarkeit. Im Folgenden beschreiben wir, wie wir die Arbeit mit GitLab, der GitLab Duo Agent Platform und weiteren Werkzeugen strukturiert haben: was funktioniert hat, worin der Ablauf besteht und wo er Lücken hatte – und wie sich das Vorgehen übertragen lässt.

Aufbau

Bei GitLab laufen seit Jahren zwei Rate-Limiting-Pfade in der Produktion: ein anwendungsseitiger Gitlab::ApplicationRateLimiter mit 121 Schlüsseln und ein separates System auf Rack-Ebene. Ziel war es, beide auf einer einzigen Implementierung in labkit-ruby zusammenzuführen – beobachtbar, testbar und überall gleich betrieben. Jede Anfrage an den Monolithen berührt dieses System, weshalb seine Fehlerzustände sichtbar und umkehrbar sein müssen.

Das Team bestand aus drei GitLab-Mitarbeitenden und einer Handvoll KI-Agenten. Max Woolf, Staff Backend Engineer im API-Platform-Team, übernahm die Monolith-Seite und führte die meisten Rollouts durch. Bob Van Landuyt, der im Bereich Scalability arbeitet, betreute das Gem und prägte die Architektur. Ich verantwortete den Scope und schrieb einen Teil des frühen labkit-Codes. Ein paar weitere Engineers kamen zeitweise dazu, um Kontext aufzunehmen sowie Code und Reviews beizusteuern.

Die Agenten lasen Kontext ein, entwarfen Spezifikationen, setzten abgegrenzte Änderungen um, schrieben Tests und prüften Merge Requests vor. GitLab Duo Code Review hielt die Codequalität in den Merge Requests hoch. Die Menschen verantworteten Scope, Architektur, Rollout und finale Review.

Wir folgten einem strikten Ablauf: Epic lesen, Spezifikation schreiben, die Spezifikation einer adversarialen Review unterziehen, erst nach dem Ausräumen der Blocker implementieren, mit belegbaren Nachweisen verifizieren, den Merge Request einer adversarialen Review unterziehen, an die menschliche Review eskalieren, mergen. Bei der adversarialen Review wird die Arbeit bewusst auf Schwachstellen abgeklopft; sie war auf zwei Auflösungsrunden begrenzt, bevor ein Mensch eingreifen musste. Über das gesamte Projekt hinweg lieferten wir 14 nummerierte Spezifikationen und etwas mehr als 30 Merge Requests in labkit-ruby aus. In der Praxis lief der Ablauf je nach Person enger oder lockerer. Bob durchlief oft mehrere Spezifikations- und Review-Zyklen für sich, bevor ein gemeinsames Artefakt entstand.

Diagramm des Ablaufs

Dieser Ablauf klingt nach viel. Bei gewachsenem Code ist es ein Ablauf, dessen Ausführung ich einem Agenten zutraue.

Was funktioniert hat

Kohorte 1 war der Test mit dem höchsten Einsatz: fünf stark frequentierte Schlüssel, darunter pipelines_create, notes_create und user_sign_in. Wir rollten sie am 4. Mai 2026 in Stufen von 1 % über 10 % auf 50 % aus, am 5. Mai 2026 dann auf 100 %. Bobs laufender Kommentar von diesem Tag ist das Betriebsmodell im Kleinen:

„Alle Rollouts abgeschlossen. Bislang stimmen sämtliche Rate Limits aus dem applimiter und der labkit-Implementierung überein. Ich vermute allerdings, dass das nur daran liegt, dass dort nicht viel Traffic anfällt. Ich schaue jetzt, ob ich Traffic erzeugen kann, der das Limit überschreitet.“

So sieht ein guter Rollout aus, und es ist genau die Art von Urteilsvermögen, die kein Agent für einen übernehmen sollte. Dass das neue System mit dem alten übereinstimmt, ist noch kein Erfolg. Es kann schlicht bedeuten, dass nichts ausgelöst hat.

Kohorte 2 fasste die nächsten 95 Aufrufstellen (83 im Monolithen und 12 in der Enterprise Edition, EE) unter einem einzigen Feature-Flag-Paar zusammen. Ohne diese Konsolidierung hätte der Rollout rund 95 einzelne Flag-Umschaltungen und etwa 190 YAML-Änderungen bedeutet. Bei dieser Art mechanischer Massenänderungen quer durch eine Codebasis sind Agenten sehr stark. Menschen sind darin sehr schwach.

Lücken im Ablauf

Der Ablauf übersah einige Dinge.

Der erste Punkt betraf den Shadow-Mode, bei dem die neue Logik nur mitläuft, ohne bereits durchzugreifen. Kohorte 2 lief seit Tagen in diesem Modus und stimmte dabei mit der alten Implementierung überein. Die Umstellung von Beobachten auf Erzwingen hätte unspektakulär verlaufen sollen. Es gab einen kleinen Haken.

Der neue Adapter ließ auf einem nicht authentifizierten Codepfad stillschweigend einen Identifier fallen. Drei String-Werte wurden in zwei primitive Slots gepresst, wobei der falsche Wert den Identifier überschrieb. Ein sehr kleiner Teil der Nutzenden sah für kurze Zeit einen generischen Fehler.

Der Shadow-Vergleich hatte diesen Schlüssel tatsächlich als abweichend markiert. Wir hatten unser Label-Set nur nicht so aufgebaut, dass es eine strukturelle Kollision von einer normalen Abweichung unterscheidet, sodass das Signal im Dashboard liegen blieb, während wir auf 100 % hochfuhren.

Wir schalteten das Enforcement-Flag sofort ab. Bob brachte das strukturelle Problem in einem Satz auf den Punkt:

„Ich denke, wir sollten das verbessern, sobald wir dieses Durcheinander aufgeräumt haben, und den ApplicationLimiter nur noch mit benannten Merkmalen aufrufen – keine Array-Scopes mehr.“

Der unmittelbare Fix ging zwei Tage später live. Die strukturelle Bereinigung steht auf der Liste für den nächsten Durchgang.

Der Fehler durchlief jeden Schritt des Ablaufs: Spezifikation, adversariale Review, Implementierung, GitLab Duo Code Review, schrittweiser Rollout. Der Ablauf erkannte ihn und erkannte ihn zugleich nicht. Die Lehre lautete nicht „Agenten sind gefährlich“. Sie lautete: Wir hatten Beobachtbarkeit – aber keine, die zwischen den Fehlerzuständen unterschied, auf die es ankam.

Am 15. Mai ließ Max ein Audit gegen master laufen, meldete sich bei mir in Slack und eröffnete Kohorte 6:

„Ich habe der Migration eine Kohorte 6 hinzugefügt: Kleinkram, der übersehen wurde.“

Geplant hatten wir fünf Kohorten. Gebraucht haben wir sechs.

Die Diagnose folgte wenige Tage später: Claude hatte eine Handvoll EE-spezifischer Rate Limits übersehen – notification_emails, einige EE-Registry-Einträge, drei Webhook-Schlüssel, drei partner_*-Schlüssel im Sekundenbruchteil-Bereich und ein paar verwaiste Adapter-Zeilen. 17 von 121 Schlüsseln waren an den früheren Kohorten vorbeigelaufen. Jeder hatte einen Grund, warum er in keine davon sauber passte. Keiner hatte einen Grund, unsichtbar zu sein.

Wir hatten weder die Agenten noch uns selbst dazu angehalten, laufend gegen das vollständige Schlüssel-Inventar zu zählen.

Ein weiterer Punkt war Redis. Der Dienst redis-cluster-ratelimiting läuft als Cluster mit vier Shards. Bobs Einschätzung zu Beginn war ehrlich: „Es gibt Spielraum, aber nicht genug, um die Auslastung vollständig zu verdoppeln.“

Anfang Mai kehrte die Einschränkung zurück, auf die wir schon früher gestoßen waren:

„Der Engpass, auf den wir vorher gestoßen sind und der für dieses Projekt nicht neu war, ist ein echter Engpass. Das heißt, wir brauchen eine Infrastruktur-Änderung, um ihn zu umgehen.“

Wir erhöhten maxclients schrittweise und stoppten bei 75.000 Verbindungen statt bei 100.000, sobald klar war, dass weitere Verbindungen die CPU der Primaries in die Sättigung treiben würden. Ein Primary pro Shard, ein Kern für die Befehlsausführung. Kein vertikaler Hebel, der sich noch ziehen ließ.

Was die Agenten tatsächlich verändert haben

Diagramm des durch die Agenten verschobenen Engpasses

Sie verschoben den Engpass. Da die Agenten innerhalb eines engen Ablaufs Spezifikationen entwarfen und implementierten, war die Codegenerierung nicht länger der langsame Teil. Zum langsamen Teil wurden nun die Review-Kapazität, das Urteilsvermögen beim Rollout und die Aufmerksamkeit der Betreibenden. Das ist ein deutlich angenehmeres Problem, es bindet aber nach wie vor menschliche Kapazität.

Angenehm war es nicht immer. Mitten im Projekt schrieb Max:

„Durchwachsen – ich habe mich mit einem Agenten im Kreis gedreht. Einer dieser Momente nach dem Muster ‚das hätte ich selbst schneller hinbekommen‘, was ärgerlich war.“

Einige Wochen zuvor hatte er das Projekt als „definitiv eine meiner steileren Lernkurven bei GitLab“ bezeichnet. Die Arbeit mit Agenten ist eine Fähigkeit, und der Preis dafür, sie aufzubauen, sind Tage, an denen allein mehr Fortschritt möglich gewesen wäre.

Die zweite Verschiebung bestand darin, ehrlich zu sein, was „fertig“ eigentlich bedeutet. Bobs Notiz am Ende von Kohorte 1 – „ein Feature-Flag pro Rate Limit ist überzogen, das sollten wir bei den nächsten Migrationen nicht mehr machen“ – ist ein kleines Beispiel für die Art von Urteilsvermögen, die kein Agent für einen übernimmt. Sie generieren bereitwillig 95 Flag-Umschaltungen, wenn man sie darum bittet. Das menschliche Urteil bestand darin, es nicht zu tun.

Stand heute

Mitte Juni stehen alle sechs Kohorten bei 100 %. Sämtliche 121 Schlüssel im ApplicationRateLimiter laufen über das neue Framework, ein Audit bestätigte, dass der alte Pfad auf nahezu null zurückgegangen ist, und wir haben einen Schutzmechanismus ergänzt, damit künftig kein Rate Limit das System stillschweigend umgehen kann.

Damit ist die Migration auf Anwendungsebene abgeschlossen. Als Nächstes folgt RackAttack, die Schicht mit dem höheren Volumen bei rund 4 Milliarden Anfragen pro Tag. Die zugehörige Shadow-and-Enforce-Middleware ist in Entwicklung; der erste Merge Request ist freigegeben und für den Merge eingereiht.

Wer das nachbauen möchte, kann die GitLab Duo Agent Platform zum Schreiben der Spezifikationen einsetzen, Duo Developer zum Umsetzen der Issues und Duo Code Review als Unterstützung beim Mergen der Merge Requests. Das ist aber der einfache Teil. Die eigentliche Frage lautet: Gibt es einen Bob? Jemanden, der das neue System bei 1 % bewusst zu brechen versucht, bevor er es bei 50 % laufen lässt. Und gibt es einen Max? Jemanden, der ein Audit anstößt, wenn alle anderen die Migration für erledigt halten. Der Ablauf ist wichtig, die Menschen sind es mehr. Wer das am eigenen gewachsenen Code ausprobieren möchte, kann noch heute damit starten.

KI-Agenten funktionieren. Ebenso funktioniert es, die Art zu verändern, wie wir an ihrer Seite arbeiten.

Feedback erwünscht

Hat dir dieser Blogbeitrag gefallen? Hast du Fragen oder Feedback? Erstelle ein neues Diskussionsthema im GitLab-Community-Forum und lass andere an deinen Eindrücken teilhaben.

Feedback teilen

Beginne noch heute, schneller zu entwickeln

Entdecke, was dein Team mit der intelligenten Orchestrierungsplattform für DevSecOps erreichen kann.