Mehr Produktivität für Rust-Entwickler mit Cursor

KI-gestütztes Programmieren hat sich von einer Neuheit zum Standard entwickelt. Bei ilert haben wir Mitte 2023 mit KI-gestützter Programmierung begonnen und schnell erkannt, dass der Erfolg stark vom richtigen Kontext und den richtigen Arbeitsabläufen abhängt. Dies gilt insbesondere für Rust. Obwohl die Sprache für unsere Backend-Infrastruktur von zentraler Bedeutung ist, machen es ihre strengen Compiler-Regeln und ausgeprägten idiomatischen Ansätze für moderne LLMs bekanntermaßen schwierig, sie zu beherrschen.
Daher haben wir viel Zeit in die Optimierung unserer AI-First-Entwicklungspraktiken investiert – eine Investition, die Entwicklungsprobleme erfolgreich beseitigt und unser Onboarding deutlich vereinfacht hat.
In diesem Artikel beschreiben wir unseren Weg von lokalen Code-Bearbeitungen zu einem strukturierten, kontextbasierten Workflow mit Cursor. Wir stellen die genauen Strategien, Rule-Files und Planungsworkflows vor, die die KI von einem Spielzeug zu einem zuverlässigen Mitwirkenden gemacht haben.
Unser Weg von Code-Snippets zu Multi-Agent-Workflows
Wir sind immer offen für neue Technologien und beobachten aktiv alle Trends, um die besten Lösungen in unsere Arbeitsprozesse zu integrieren. Die KI war keine Ausnahme. Zunächst betrachteten wir KI als „besseres Stack Overflow”. Anfänglich nutzten wir ChatGPT zum Schreiben von Code-Snippets. Wir erstellten mehrere Custom-GPTs zum Schreiben von Unit-Tests und Dokumentationen. Dann abonnierten wir GitHub Copilot für die intelligente Autovervollständigung. Und dann kam Cursor. Zunächst waren wir ziemlich skeptisch, da das Tool ziemlich viele Fehler hatte und das Ergebnis weit von dem entfernt war, was wir uns vorgestellt hatten. Aber seine Fähigkeit, den Index der Codebasis zu nutzen, war vielversprechend.

Phase 1: Isolierte Aufgaben
Anfangs haben wir Cursor für isolierte Aufgaben verwendet. Ein Entwickler beauftragte ChatGPT zum Beispiel damit, „einen POST-Endpunkt für die Incident-Entität zu implementieren”. Der Umfang der Aufgaben war gering und die Ergebnisse waren oft unzuverlässig. In Rust führte dies oft zu Code, der zwar funktionierte, aber nicht idiomatisch war oder unsere bestehende Architektur verletzte.
Phase 2: Lebendige Dokumentation und Rule files
Wir erkannten, dass die KI nur so gut war wie der Kontext, den sie „sehen“ konnte. Anstatt jedoch den Kontext in jeden Chat einzufügen, wählten wir einen anderen Ansatz: Wir behandelten Dokumentation und Regeln als erstklassige Code-Artefakte.
Wir führten zwei wichtige Praktiken ein:
.cursor/rules/: Projektspezifische Regeldateien (wie rust-coding.mdc), die Cursor automatisch in jede Interaktion lädt. Diese Regeln kodieren unsere technischen Standards – Fehlerbehandlungsmuster, Parallelitätsmodelle, bevorzugte Crates –, sodass die KI jede Aufgabe bereits mit dem „Wissen“ um unsere Konventionen beginnt.- Lebendige Dokumentation: Dateien wie
ARCHITECTURE.md, die Entscheidungen dokumentieren, nicht Implementierungsdetails.
Diese Phase brachte den Durchbruch, da der Kontext persistent verfügbar war und automatisch eingebunden wurde. Kein Kopieren und Einfügen mehr. Die KI übernahm einfach unsere Engineering-Kultur aus dem Repository selbst. Die genauen Regeldefinitionen und Dateistrukturen, die das ermöglichten, werden wir später in diesem Artikel vorstellen.
Phase 3: Plan Mode – Architektur vor Implementierung
Die Einführung von Plan Mode war der nächste Entwicklungsschritt in unserem Prozess und verlagerte unseren Workflow von „Code generieren und iterieren” zu „zuerst entwerfen, dann gezielt implementieren”.
Selbst mit geeigneten Regeln führt das sofortige Wechseln in die Code-Generierung oft zu Lösungen, die technisch korrekt, aber architektonisch fragwürdig sind – Tech Debt garantiert.
Um dem entgegenzuwirken, haben wir eine Strategie implementiert, die wir als „Dreierregel“ bezeichnen: Bei jeder wesentlichen Änderung beginnen wir mit Plan Mode und formulieren den Prompt wie folgt:
In Kombination mit unseren Rule Files stellt der Plan Mode sicher, dass die KI Code generiert, der mit unserer langfristigen Vision übereinstimmt. Die Spezifikation und die Implementierung bleiben im gleichen Kontext, sodass wir die Architektur überprüfen können, bevor auch nur eine einzige Zeile Code geschrieben wird.
Ein Hinweis zur Kontext-Entropie im Plan Mode: Wir haben eine bestimmte Einschränkung in der aktuellen Version von Cursor festgestellt: Wenn man einen generierten Plan zu oft iteriert, neigt das Modell dazu, Einschränkungen und nützliche Lösungen, die in der ersten Version festgelegt wurden, zu „vergessen”.
Um diese Kontextverschiebung zu verhindern, nutzen wir für komplexe Aufgaben zuerst den Ask Mode, bevor wir in Plan Mode wechseln. So können wir Anforderungen und Randfälle im Voraus klären, was zu einem robusten Anfangsplan führt, der weniger Nachbearbeitungen erfordert.
Phase 4: Multi-Agent-Orchestrierung
Die neueste Entwicklung geht über einen einzelnen KI-Assistenten hinaus und hin zu orchestrierten Multi-Agenten-Systemen. Anstatt dass ein einzelner Agent alles übernimmt, orchestrieren wir nun spezialisierte Unteragenten, die jeweils über spezifische Tools und Fachkenntnisse verfügen.
Das allgemeine Muster sieht wie folgt aus: Der Orchestrator-Agent auf oberster Ebene koordiniert die Sub-Agenten:
- Architekt-Agent: Betrachtet das Problem aus einer übergeordneten Perspektive, bewertet mehrere Lösungen und schlägt möglicherweise vor, einen POC zu erstellen, bevor eine Entscheidung getroffen wird.
- Implementierungs-Agenten: Die Entwickler, die die geplanten Änderungen ausführen.
- Review-Agenten: Qualitätsprüfer, die architektonische Standards, SOLID-Regeln, saubere Tests usw. sicherstellen.
Die Stärke liegt in der Parallelisierung und Spezialisierung, wodurch der Kontext und Fokus der LLMs effektiv verwaltet werden können. Unsere ersten Ergebnisse zeigen eine bis zu doppelt so hohe Iterationsgeschwindigkeit bei komplexen Aufgaben. Wir werden diesen Ansatz in zukünftigen Artikeln ausführlich erklären. Starten wir zunächst mit den Grundlagen der AI-First-Entwicklung.
Context Engineering: Warum Dokumentation der neue Code ist
Bevor es KI gab, war die Dokumentation oft das Letzte, was geschrieben wurde, und das Erste, was veraltet war. Ein menschlicher Entwickler konnte die Lücke zwischen einer veralteten README-Datei und dem tatsächlichen Code überbrücken. Der KI fehlt diese Intuition. Wenn Ihre Dokumentation Ihrem Code widerspricht, wird die KI eine Brücke zwischen beiden konstruieren, was zu Code führt, der korrekt erscheint, aber stillschweigend fehlschlägt.
Wir erkannten, dass wir, um Cursor effektiv zu machen, unsere Denkweise auf „AI-First-Dokumentation” umstellen mussten.
Das Kontextfenster sauber halten
Sobald man ein Repository in Cursor öffnet, indexiert es den Code, um den Projektkontext zu verstehen. Wenn dieser Index mit veralteten Architekturentscheidungen gefüllt ist, verschlechtert sich die Vorhersagequalität des Modells.
Um dem entgegenzuwirken, haben wir ein strenges Protokoll eingeführt: Dokumentation ist eine Compile-Time-Dependency.
- Die Datei
ARCHITECTURE.md: Jeder Dienst enthält diese Datei. Sie listet keine Endpunkte auf (die sich häufig ändern), sondern Entscheidungen. Dadurch erhalten die KI und neue Entwickler ein Verständnis für das „Warum” hinter dem Code. - Standardisierte Ordnerstruktur: Wir setzen ein einheitliches Layout für alle Rust-Dienste durch (
src/domain,src/infrastructure,src/api). Da jedes Projekt identisch aussieht, kann die KI mit nahezu hundertprozentiger Genauigkeit vorhersagen, wo eine neue Datei hingehört, sodass wir weniger Pfade in Eingabeaufforderungen angeben müssen.
Der „Fix the Rule“-Loop
Eine unserer effektivsten Produktivitätsänderungen betraf den Umgang mit KI-Fehlern. Wenn Cursor zuvor Code generierte, der gegen unsere Muster verstieß, haben wir den Code einfach mit Folgebefehlen umgeschrieben. Jetzt behandeln wir einen KI-Fehler als Dokumentationsfehler.
Wenn Cursor Code generiert, der Probleme mit dem Borrow Checker verursacht oder zu einem Deadlock führt, korrigieren wir nicht nur den Code, sondern patchen auch die Rule File oder andere Kontextdokumentationen. Wir fragen: „Welche Anweisung fehlte, die diesen Fehler ermöglicht hat?“ So führt jeder Fehler zu einer dauerhaften Verbesserung für das gesamte Team.
Der Erfolgsfaktor: unsere Rust-Regeln
Die Dokumentation liefert den Kontext, aber Rules liefern die Einschränkungen. Anfangs nutzten wir eine einzelne .cursorrules-Datei im Stammverzeichnis des Repositorys. Jetzt verwenden wir mehrere RULE-Files in .cursor/rules/:
- Sprachspezifische Regeln
- Allgemeine Best Practices für die Programmierung
- Refactoring-Regeln
- Regeln für die Sicherheitsanalyse
Die Trennung der Dateien erleichtert ihre Wartung, reduziert den LLM-Kontext und erleichtert ihre Wiederverwendung in verschiedenen Projekten. Für Rust verwenden wir eine spezielle Regeldatei rust-coding.mdc (siehe Anhang). Hier gehen wir auf einige wichtige Punkte ein.
Wichtige Einschränkungen, die wir durchsetzen

1. Modularität
- Die Regel:
main.rsso klein wie möglich halten – nurmain(), das die Konfiguration lädt undruntime.block_on(run(...))aufruft. Der asynchrone Einstiegspunkt soll in einer eigenen Dateirun.rsstehen. Inlib.rsundmod.rssollen nur Module aufgelistet werden. Module sollten nach Domänen gruppiert werden (z. B.src/http, src/config, src/use_case_xx). - Der Grund: Die schlanken Haupt- und Lib-Module erleichtern die Testbarkeit und die Lebenszyklusanalyse. Domänenordner und optionale umfangreiche Abhängigkeiten (z. B. Kafka) vereinfachen die Integrationsprüfung, ohne dass die gesamte Infrastruktur hochgefahren werden muss.
2. Das „Sync main”-Muster
Eine der größten Herausforderungen für Cursor mit Rust ist die Handhabung von Rust-Lifetimes in asynchronem Code. Dies führt dazu, dass viele unnötige Klone oder Mutexe erzeugt werden, was zu unbeabsichtigter Komplexität führt.
- Die Regel: „Starte
main()im Sync-Modus, konfiguriere die Anwendung und starte dann am Ende die Tokio-Laufzeitumgebung.” - Der Grund dafür: Dadurch wird die KI gezwungen, langlebige Ressourcen (wie Datenbankpools oder Konfigurationsobjekte) im Stack-Frame der
main-Funktion zuzuweisen, bevor die Tokio-Laufzeitumgebung gestartet wird. Cursor kann einen Trick mitBox::leak(Box::new(some_global))anwenden, um'staticReferenzen zu erhalten, was die Laufzeitverwaltung weiter vereinfacht.
3. Datenmodellierung und Konfiguration
- Die Regel: Newtype-IDs, serde für DTOs mit
camelCase,derive_builderfür komplexe Konstruktionen,validatorfür eingehende DTOs. Dieconfig-Crate mit YAML und Umgebungsüberschreibungen verwenden, damit alle Einstellungen beim Start validiert werden. - Der Grund: Eine konsistente DTO-Darstellung und -Validierung an der Grenze stärkt APIs, liefert klare Fehlermeldungen und sorgt dafür, dass die KI jedes Mal die gleichen Muster generiert.
4. Fehlerbehandlung
- Die Regel: „Definiere eine
thiserror-Enumeration für Businesslogik über alle Anwendungsfälle und verwendeanyhowfür generische Fehler.“ - Der Grund: Dies verhindert, dass die KI zu viele benutzerdefinierte Fehler-Enumerationen erstellt, und stellt gleichzeitig sicher, dass die Geschäftslogik von abgleichbaren Fehlern profitieren kann. Wir bevorzugen die
From-Trait-Implementierung gegenübermap_err()und verbietenunwrap()im Produktionscode, um sauberen und idiomatischen Rust-Code zu ermöglichen.
5. Verhindern von Async-Problemen
- Die Regel: „Das Halten von
std::sync::Mutexüber einen.awaithinweg ist strengstens verboten.“ - Der Grund: Dies ist ein klassischer Rust-Fehler, der die Tokio-Laufzeit blockiert. Syntaktisch sieht es korrekt aus und lässt sich kompilieren.
6. Beobachtbarkeit und externe Kommunikation
- Die Regel: Verwende
tracingmit strukturierten Feldern; verwendeimpl FromRequest for Claimsfür Actix-Authentifizierung; nutzereqwestmit Wiederholungsversuchen und Beobachtbarkeits-Middleware für ausgehende HTTP-Anfragen. - Der Grund: Manchmal entscheidet sich Cursor für die Verwendung von
awc::Client, aber er ist nichtSend, was beispielsweise die Übergabe antokio::spawnerschwert. Daher setzen wir einenreqwest-basierten Client zusammen mit seinen Middlewares für produktionstaugliche Fehlertoleranz und Beobachtbarkeit durch.
Die vollständige Rules-File finden Sie im Anhang am Ende dieses Artikels. Sie können sie in .cursor/rules/rust-coding.md ablegen und an Ihren Stack anpassen.
Experiment: Keine Regeln vs. Regeln vs. Planung
Um die jeweiligen Auswirkungen auf unseren Workflow bestimmen zu können, haben wir einen kontrollierten Versuch durchgeführt, indem wir Cursor in drei Konfigurationen denselben Befehl gaben:
- Naked: Keine Rule-Files.
- Geführt: Mit
rust-coding.mdc. - Architektonisch: Mit Rule-File + Plan Mode.
Hinweis zur Verzerrung: Wir mussten den „Naked”-Versuch auf einem neuen Cursor-Konto durchführen. Wir haben festgestellt, dass die in der Cloud gespeicherten Einbettungen von Cursor „hartnäckig” sind; auch ohne Regeldateien „erinnerte” es sich an unsere früheren Muster aus anderen Sitzungen. Ein neues Konto war notwendig, um die tatsächliche Basisleistung zu sehen. Und hier ist eine weitere Implikation: Wenn Cursor Code mit schlechten Mustern in Kontakt kommt, kann es sein, dass es diese in dem neuen Code wiederholt. Seien Sie also vorsichtig, womit Sie Cursor „füttern”.
Der Prompt ist absichtlich recht vage gehalten, um die Verzerrung in Cursor zu untersuchen:
Szenario Nr. 1: "Naked" Cursor (keine Rules-Datei)
Das generierte Projekt ließ sich nicht kompilieren. Wir stellten fest, dass der Kafka-Consumer mit tokio::spawn gestartet wurde, wobei ein gemeinsam genutzter awc::Client übergeben wurde. awc::Client implementiert das Trait Send nicht, da er auf den Single-Thread-Typen von Actix (z. B. Rc) basiert. tokio::spawn verlangt jedoch, dass das Future das Send implementiert. Daher lehnt der Compiler diese Variable ab.
Das problematische Snippet:
Der Code fördert weder Wartbarkeit noch Erweiterbarkeit:
- Die Module bestehen aus einer flachen Sammlung von Dateien im Verzeichnis
/srcohne domänenspezifische Gruppierung. - Viele Module vermischen unterschiedliche Verantwortlichkeiten, etwa Nachrichtenverarbeitung und HTTP-Aufrufe in
kafka.rsoder das Laden von Umgebungsvariablen und das Einrichten von Server-Routen inmain.rs.
Szenario Nr. 2: Mit einer Rule-Datei, kein Plan Mode
Mit aktivierter Rule-Datei kompiliert das Projekt erfolgreich. Cursor wählt einen Send-sicheren HTTP-Client auf Basis von reqwest, inklusive einer separaten Fassade für den HTTP-Client.
Allerdings konnten wir feststellen, dass die Modularity-Regeln nicht vollständig umgesetzt wurden. Es gab beispielsweise keine modulare Gruppierung nach Scope und Funktionalität; sämtliche Source-Files lagen in einem einzigen Ordner. Noch gravierender: Es gab zu viele Error-Enums – eines in kafka.rs, ein weiteres in config.rs usw. Offensichtlich hatte Cursor unsere Rule hier missverstanden.
Auf diese Weise erhält man zwar einen funktionierenden, kompilierbaren Service, architektonisch bleibt jedoch Optimierungspotenzial. In diesem Fall scheint Cursor kein projektweites Architekturdenken zu verfolgen. Und genau hier kommt der Plan Mode ins Spiel.
Szenario Nr. 3: Mit Rule-Datei und Plan Mode
Mit aktivierter Rule-Datei und Start im Plan Mode von Cursor folgt der generierte Service den meisten Regeln konsistent: Der HTTP-Client und die Konfiguration befinden sich in dedizierten Modulen, die modulare Struktur mit http/, forwarding/, server/ und shared/ ist klar umgesetzt – gut geeignet für Tests und Erweiterungen.
Die main.rs ist entsprechend schlank und übersichtlich:
Ergebnisse: Von Autoren zu Reviewern
Nach jahrelanger Optimierung unserer Cursor-Workflows hat sich der Einfluss auf unsere Engineering-Geschwindigkeit deutlich gezeigt:
1. Optimierte Einarbeitung
Der größte Überraschungseffekt einer strikten Rule-Datei und „AI-First Documentation“ zeigte sich beim Onboarding. Wenn ein neuer Engineer zu ilert kommt, muss er nicht zunächst alle unsere Coding-Guides auswendig lernen, bevor er produktiv beitragen kann. Cursor fungiert als Pair-Programmer, der unsere Konventionen bereits kennt.
2. Von Syntax zu Architektur
Unsere Engineers verbringen heute deutlich weniger Zeit mit Boilerplate-Code, mit dem Rust-Borrow-Checker oder mit dem Debugging schwer nachvollziehbarer Async-Runtime-Fehler. Die AI übernimmt das „Plumbing“. Dadurch gewinnt unser Team Freiraum, um sich stärker auf komplexe Business-Logik zu konzentrieren und mehr Aufmerksamkeit auf entscheidende Details zu legen.
Wir haben uns faktisch vom „Code Writer“ zum „Code Reviewer und Architekten“ entwickelt.
3. Vorhersagbarkeit im großen Maßstab
Indem wir Prompts und Regeln wie Code behandeln, haben wir ein Maß an Konsistenz erreicht, das in wachsenden Teams schwer aufrechtzuerhalten ist. Das Aufsetzen neuer Microservices und deren Integration in unsere Infrastruktur-Landschaft wurde zur Routine. Die Anzahl der Code-Review-Iterationen ist drastisch gesunken.
Fazit
Wenn Sie Rust-Entwickler oder Engineering Leader sind und Ihre Produktivität steigern möchten, sollten Sie KI nicht wie einen Chatbot behandeln. Betrachten Sie sie vielmehr wie einen Junior Engineer. Geben Sie ihr ein Handbuch (.cursor/rules/), liefern Sie Kontext (ARCHITECTURE.md) und zwingen Sie sie, erst zu denken, bevor sie Code schreibt.
Aus unserer Erfahrung ergibt sich folgende Checkliste für eine effektive Entwicklung mit Cursor:
1. Design iterieren, einmal implementieren:
Starten Sie größere Änderungen im Plan Mode und lassen Sie sich von der KI verschiedene Lösungsansätze vorschlagen. Nutzen Sie in komplexen Fällen zunächst den Ask Mode, bevor Sie in den Plan Mode wechseln.
2. Dokumentation als Dependency behandeln:
Pflegen Sie eine KI-optimierte Dokumentation (kompakt, strukturiert und widerspruchsfrei), die zentrale Entscheidungen und Constraints klar festhält.
3. Der „Fix-the-Rules“-Loop:
Wenn die KI einen Fehler macht, korrigieren Sie nicht nur den Code. Aktualisieren Sie Ihre Rules so, dass diese Fehlerklasse künftig systematisch vermieden wird.
4. Kontext bewusst steuern:
Achten Sie darauf, welche Inhalte Sie indexieren. Verwenden Sie .cursorignore, um irrelevante Informationen auszuschließen. Wenn Sie Cursor eine Legacy-Codebase mit schlechten Patterns geben, wird sie diese reproduzieren.
Die Tools sind bereit. Jetzt liegt es an uns, mit ihnen die Zukunft zu gestalten.
Anhang: Unsere Rust-Rules
Hier finden Sie unsere vollständige rust-coding.mdc. Sie können diese kopieren und an Ihre Bedürfnisse anpassen.


.avif)
