ilert stellt mithilfe unserer vorgefertigten Integrationen oder per E-Mail eine nahtlose Verbindung zu Ihren Tools her. Ilert lässt sich in Überwachungs-, Ticketing-, Chat- und Kollaborationstools integrieren.
So erreichen führende Unternehmen mit ilert eine Uptime von 99,9 %
Unternehmen weltweit vertrauen auf ilert, um ihr Incident-Management zu optimieren, die Zuverlässigkeit zu steigern und Ausfallzeiten zu minimieren. Lesen Sie, was unsere Kunden über ihre Erfahrungen mit unserer Plattform sagen.
ilert unterstützt ab sofort eine native WhaTap-Integration, die KI-native Observability mit KI-basiertem Incident Management in einem nahtlosen Workflow verbindet. Diese Integration ermöglicht es DevOps-, SRE- und IT-Teams, sofort von der Fehlererkennung zur Fehlerbehebung überzugehen – wodurch Alarmstörungen vermieden, die Koordination verbessert und die MTTR selbst in den komplexesten IT-Umgebungen drastisch reduziert werden.
Was ist WhaTap?
WhaTap ist eine KI-native Observability-Plattform, die eine einheitliche Überwachung von Servern, Anwendungen, Datenbanken und Kubernetes in einer einzigen SaaS-Plattform ermöglicht. Dank fortschrittlicher Datenintegrations- und Korrelationsanalysetechnologien erhalten Teams Echtzeit-Einblick in Systemprobleme und können die Ursachen schnell identifizieren. Derzeit bedient WhaTap über 1.200 Kunden auf nationalen und internationalen Märkten und expandiert weltweit, darunter in Japan, Südostasien und den Vereinigten Staaten.
Warum WhaTap mit ilert verbinden?
Die ilert-WhaTap-Integration verwandelt umfassende Observabilität in sofortige Handlungsfähigkeit. Durch die Verknüpfung der einheitlichen Überwachung von WhaTap mit der KI-gestützten Incident-Management-Plattform von ilert können DevOps- und IT-Betriebsteams ihre Incident-Reaktion vollständig automatisieren. Sobald WhaTap Anomalien oder Leistungsprobleme in Kubernetes-Umgebungen oder Datenbanken erkennt, benachrichtigt ilert sofort den zuständigen Bereitschaftsingenieur per Sprach-, SMS- oder mobiler Push-Benachrichtigung.
Das Ergebnis ist ein nahtloser Übergang von der Erkennung zur Lösung. ilert erweitert die WhaTap-Alarme um Dienstpläne, automatisierte Eskalationen und KI-gestützte Kommunikation bei Incidents. Somit eine schnellere Koordination und klarere Zuordnung von Verantwortlichkeiten ermöglicht. Zusammen helfen die umfassende Beobachtbarkeit von WhaTap und die leistungsstarke Response-Engine von ilert SREs und IT-Teams dabei, Downtimes zu reduzieren, die Zusammenarbeit zu verbessern und die MTTR selbst in hochkomplexen IT-Umgebungen drastisch zu senken.
So richten Sie die Integration ein:
Befolgen Sie diese einfachen Schritte, um WhaTap mit ilert zu verbinden::
In ilert:
Zu „Alarmquellen“ gehen → neue Alarmquelle für WhaTap erstellen
Namen festlegen, Teams zuweisen, Eskalationsrichtlinie auswählen, und Alarmgruppierung bestimmen
Einrichtung abschließen, um eine Webhook-URL zu generieren
In WhaTap:
Das Projekt für Alarme öffnen → Alarm auswählen → Benachritigungen
Plug-in eines Drittanbieters hinzufügenn → Webhook JSON auswählen
ilert Webhook-URL einfügen und Webhook registrieren
Alarm-empfang starten:
WhaTap-Ereignisse werden nun direkt an ilert weitergeleitet und lösen automatisierte Incident-Workflows aus.
Eine vollständige Schritt-für-Schritt-Anleitung finden Sie unter docs.ilert.com. Bei Problemen hilft Ihnen unser Support-Team gerne weiter unter support@ilert.com.
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:
Goal: Implement JWT middleware for the HTTP service.
1. Scan ARCHITECTURE.md and README.md for related parts of the service
2. Scan the codebase to fill gaps in understanding
3. Propose 3 distinct architectural approaches
4. For each, list pros/cons and impact on maintainability and performance
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 Rulesliefern 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.rs so klein wie möglich halten – nur main(), das die Konfiguration lädt und runtime.block_on(run(...)) aufruft. Der asynchrone Einstiegspunkt soll in einer eigenen Datei run.rs stehen. In lib.rs und mod.rs sollen 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 mit Box::leak(Box::new(some_global)) anwenden, um 'static Referenzen zu erhalten, was die Laufzeitverwaltung weiter vereinfacht.
3. Datenmodellierung und Konfiguration
Die Regel: Newtype-IDs, serde für DTOs mit camelCase, derive_builder für komplexe Konstruktionen, validator für eingehende DTOs. Die config-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 verwende anyhow fü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über map_err() und verbieten unwrap() 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 .await hinweg 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 tracing mit strukturierten Feldern; verwende impl FromRequest for Claims für Actix-Authentifizierung; nutze reqwest mit 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 nicht Send, was beispielsweise die Übergabe an tokio::spawn erschwert. Daher setzen wir einen reqwest-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:
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:
Implement the service in Rust:
- HTTP server based on Actix with JWT authentication
- Consume each Kafka topic defined in the YAML configuration
- On each message, make a POST call to /forward on the downstream service with hostname configured via environment variable
- Expose Kafka producer statistics at /stats
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:
pub fn spawn_consumers(config: Config, stats: SharedStats, client: awc::Client, downstream_host: String) {
for topic in config.topics {
let client = client.clone();
tokio::spawn(async move {
if let Err(e) = run_topic_consumer(..., client, ...).await {
// handle error
}
});
}
}
Der Code fördert weder Wartbarkeit noch Erweiterbarkeit:
Die Module bestehen aus einer flachen Sammlung von Dateien im Verzeichnis /src ohne domänenspezifische Gruppierung.
Viele Module vermischen unterschiedliche Verantwortlichkeiten, etwa Nachrichtenverarbeitung und HTTP-Aufrufe in kafka.rs oder das Laden von Umgebungsvariablen und das Einrichten von Server-Routen in main.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:
fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
let config_path = std::env::var("CONFIG_PATH").unwrap_or_else(|_| "config.yaml".into());
let path = PathBuf::from(&config_path);
let config = AppConfig::load(&path).context("load config")?;
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.context("create runtime")?;
runtime.block_on(run(config))?;
Ok(())
}
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.
---
description: "ilert's Rust coding rules"
globs: ["src/**/*.rs"]
alwaysApply: true
---
# Modularity
- Group modules by business functionality: `src/payments`, users. Common utilities go into `src/shared`
- In lib.rs or mod.rs only list modules
- Keep main.rs concise: it should contain only main() that calls configuration functions from other modules and launches the runtime
- Define run.rs with run() that is the entry point of the async runtime
- Heavy dependencies like Kafka producers should be optional, optimized for testing
- Separate boundaries under facades like Client classes for downstream HTTP services
# Data Modeling
- Newtype Pattern: Wrap primitive types for entity IDs (e.g., `#[derive(PartialEq, Eq, Hash, Copy, Clone)] struct UserId(u64);`)
- Annotate DTO structs for JSON requests and responses with `#[derive(Debug, Clone, Deserialize, Serialize)]`, `#[serde(rename_all = "camelCase")]`
- Annotate enums with `#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]` and `#[derive(Clone, Display, Debug)]`, `#[serde(rename_all = "SCREAMING_SNAKE_CASE")]`
- For complex object construction, utilize `derive_builder` with `#[builder(setter(into))]`
- Use `validator` (`#[derive(Validate)]`) on incoming DTOs
## Concurrency
- Start the main() in sync mode (no #[actix_web::main]), configure the application, then launch the async runtime at the end with `runtime.block_on(run(...))`
- Pass complex variables initialized in main() as 'static obtaining the reference with `Box::leak(Box::new(something))`
- Wrap shared writable state with `tokio::sync::RwLock` (`Arc<RwLock>`), locking for the shortest period of time
- If the shared writable state requires change notification, use `tokio::sync::watch`
- Strictly forbid holding `std::sync::Mutex` or `std::sync::RwLock` across an `.await` point
- Handle graceful job cancellation and timeouts using `tokio::select!`
- For long-term async background jobs, like message consumers, use `&'static self` and initialize the instance before the launch of the async runtime
# Error Handling
- Use descriptive error types using `thiserror` v2, preserving source via `#[from]` or `#[source]`. Fall back to `anyhow` for short-scoped generic errors that are later mapped to `thiserror`; use `.context()`
- Avoid `map_err()` — instead, implement the `From` trait for the target error type
- Strictly avoid unwrap() in production code. But `.context()` for critical errors during application launch is fine
# Observability
- Use `tracing` for logging and tracing, attaching key-value pairs with important context
- Check the log level before dumping complex debug data with `if tracing::enabled!(tracing::Level::DEBUG)`
# External Communication
- For authentication in Actix use `impl FromRequest for Claims`
- Use middlewares for observability (`reqwest-tracing` for clients, custom for servers)
- Utilize timeouts and retries with backoff for outgoing requests (`reqwest-retry`)
# Config and Utilities
- Use `config` v0.15 and YAML configurations, with flexible environment overrides by `.add_source(Environment::default()).set_override_option("some.deep.key", std::env::var("CUSTOM_VAR").ok())`
- Use `itertools` to ease iterator transformations (`use itertools::Itertools; iter.join(", "); iter.chunks(10); iter.unique()`)
- Avoid adding comments, keep existing
Alle wollen autonome Reaktionen auf Incidents, aber die meisten gehen dabei falsch vor.
Das ultimative Ziel der Autonomie in SRE und DevOps ist die Fähigkeit eines Systems, Incidents nicht nur zu erkennen, sondern sie auch unabhängig durch intelligente Selbstregulierung zu beheben. Wahre Autonomie entsteht jedoch nicht durch die Automatisierung zufälliger, isolierter Aufgaben. Sie erfordert eine stabile Grundlage: eine Referenzarchitektur.
Dieser Entwurf dient als „Immunsystem“ Ihrer Infrastruktur und stellt sicher, dass Selbstheilungsprozesse nicht unberechenbar ablaufen, sondern innerhalb klar definierter Grenzen funktionieren. Ohne diese Grundsätze ist Autonomie ein Risiko, wie ein selbstfahrendes Auto ohne Sensoren zur Überwachung der Straße.
Die Realität ist einfach: Wenn Ihre Autonomiestrategie auf Skripten, Runbooks und reaktiver Automatisierung basiert, haben Sie keine Autonomie, sondern nur schnellere Ausfälle.
In diesem Artikel erklären wir, wie Sie die Lücke zwischen manuellem Scripting und einer wirklich agentenbasierten Strategie schließen können. Wir zeigen Ihnen, warum eine solide Architektur die wesentliche Voraussetzung dafür ist, dass KI-gesteuerte Ansätze sicher und effektiv funktionieren können.
Die Kernprinzipien: Welche theoretischen Grundlagen jede Referenzarchitektur stützen.
Bausteine der Autonomie: Auf welche Komponenten diese Prinzipien angewendet werden müssen, um Sicherheit zu gewährleisten.
Incident Response: Warum die Reaktion auf Vorfälle fest in der Architektur verankert sein muss.
Cloud-Native & Skalierung: Welchen Unterschied moderne Cloud-Technologien bei der Umsetzung machen.
Grundprinzipien der Referenzarchitektur
Eine Referenzarchitektur ist weit mehr als eine bloße Empfehlung oder ein statisches Diagramm. Sie ist das destillierte Wissen aus unzähligen Fehlermodi und Best Practices. Betrachten Sie sie als eine Art „Verfassung“ für Ihre Infrastruktur: Sie schreibt vor, wie sich Komponenten verhalten müssen, damit das Gesamtsystem auch unter extremer Belastung autonom funktionsfähig bleibt.
Ohne diese Prinzipien wird Autonomie von Natur aus unsicher, da sie zwar schnelle Reaktionen ermöglicht, aber nicht die notwendigen Einschränkungen vorsieht, um systemische Schäden zu verhindern.
Hier sind die Säulen, auf denen Ihre autonome Strategie beruhen muss:
1. Modularität: Isolieren statt Eskalieren
Autonomie funktioniert nur, wenn Probleme lokal begrenzt bleiben. Durch die Zerlegung komplexer Monolithen in unabhängige, modular aufgebaute Komponenten stellen Sie sicher, dass ein autonomer Heilungsprozess in einem Bereich nicht versehentlich das gesamte System instabil macht. Modularität ist die Brandschutzmauer Ihrer Autonomie.
2. Observability: Mehr als nur Monitoring
Ein System kann sich nur selbst regulieren, wenn es seinen eigenen Zustand versteht. Dies geht weit über einfache Dashboards oder isolierte Signale hinaus. Echte Beobachtbarkeit entsteht durch die Korrelation von Protokollen, Metriken und Traces, um ein vollständiges Echtzeitbild der Vorgänge im gesamten System zu erstellen. So können autonome Agenten über Verhalten, Abhängigkeiten und Auswirkungen nachdenken, anstatt blind auf oberflächliche Signale zu reagieren.
3. Resilienz: Design für den Misserfolg
In einer autonomen Welt ist ein Fehler kein Ausnahmezustand, sondern eine statistische Gewissheit. Eine gute Referenzarchitektur antizipiert Ausfälle durch Redundanz und Failover-Mechanismen. Das Ziel ist Graceful Degradation: Das System lernt, bei Teildefekten kontrolliert "einen Gang zurückzuschalten", anstatt komplett zu versagen.
4. Skalierbarkeit: Elastizität als Reflex
Wahre Autonomie bedeutet, dass das System auf Lastspitzen reagiert, bevor der Nutzer eine Verzögerung bemerkt. Die Architektur muss so gestaltet sein, dass Ressourcen elastisch und ohne manuelles Zutun geatmet werden können – ein reflexartiges Ausdehnen und Zusammenziehen je nach Bedarf.
Diese Prinzipien bilden die Leitplanken, von denen wir in der Einleitung gesprochen haben. Sie sorgen dafür, dass die "Intelligenz" Ihres Systems eine solide Datenbasis hat und ihre Korrekturen sicher ausführen kann.
Im nächsten Schritt schauen wir uns an, mit welchen konkreten technischen Bausteinen Sie diese Theorie in die Praxis umsetzen.
Architekturmuster für sichere Autonomie
Damit ein System eigenständig Entscheidungen treffen kann, muss die Architektur so gebaut sein, dass sie Feedbackschleifen unterstützt und Fehler isoliert. Diese Muster bilden das mechanische Skelett Ihrer autonomen Operationen.
1. Deklarative Infrastruktur (GitOps & IaC)
In einer autonomen Welt ist Code die „Single Source of Truth“. Bei GitOp beschreiben Sie nicht, wie etwas getan werden soll, sondern was der Zielzustand ist.
Ein autonomer Controller vergleicht permanent diesen Soll-Zustand mit der Realität. Weicht das System ab (Configuration Drift), korrigiert es sich von selbst. GitOps ist quasi das Gedächtnis Ihres Systems, das dafür sorgt, dass es immer wieder zu seinem gesunden Ursprung zurückfindet.
2. Service Meshes: Das intelligente Nervensystem
Microservices allein sind komplex zu verwalten. Ein Service Me Service Mesh legt eine Steuerungsebene über Ihre Dienste.
Es ermöglicht „Traffic Shifting“ ohne Code-Änderungen. Wenn eine neue Version eines Dienstes Fehler produziert, kann das System den Datenverkehr autonom und in Millisekunden auf die alte, stabile Version zurückrollen. Es fungiert als Reflexzentrum, das sofort reagiert, wenn die Kommunikation zwischen Diensten schmerzt.
3. Leistungsschalter & Bulkheads: Die Notfall-Sicherungen
Diese Muster stammen aus der Elektrotechnik und dem Schiffbau. Ein Leistungsschalter kappt die Verbindung zu einem überlasteten Dienst, während Bulkheads Ressourcen so isolieren, dass ein Leck in einem Bereich nicht das gesamte Schiff versenkt.
Sie verhindern kaskadierende Ausfälle. Ein autonomer Agent kann innerhalb eines "Schotts" Experimente zur Heilung durchführen, ohne zu riskieren, dass ein kleiner Fehler das gesamte Rechenzentrum lahmlegt.
4. Automatisierte Rollbacks & Canar-Deployments
Das Risiko bei Änderungen wird durch schrittweise Einführung minimiert. Ein Canary Deployment rollt Updates erst für 1% der Nutzer aus.
Das System übernimmt die Rolle des Qualitätsprüfers. Es analysiert die Fehlerrate der neuen Version im Vergleich zur alten. Sind die Werte schlecht, bricht das System das Deployment autonom ab. Die Autonomie schützt hier das System vor menschlichen Fehlern beim Release.
Diese Muster sind die Werkzeuge, die Sie benötigen, um die Kontrolle sicher abzugeben. Doch ein Werkzeug ist nur so gut wie der Plan für den Ernstfall.
Die Lücke schließen: Von statischer Verteidigung zu aktiver Reaktion
Diese Architekturmuster sind unverzichtbare Werkzeuge für die Stabilität, aber für sich genommen bleiben sie reaktiv. Ein Leistungsschalter kann verhindern, dass ein „Brand“ um sich greift, und ein Service Mesh kann den Datenverkehr umleiten – aber sie lösen nicht zwangsläufig die zugrunde liegende Krise. Um von einem System, das Fehler lediglich überlebt, zu einem System zu gelangen, das sie aktiv löst, müssen wir unsere Sicht auf den Incident-Lifecycle grundlegend ändern.
Hier findet der Übergang zu echter Autonomie statt: Incident Response darf kein manuelles Handbuch mehr sein, das verstaubt im Regal liegt; sie muss fest in die Architektur selbst „hardcoded“ werden.
In die Architektur eingebettetes Incident Management
Incident Response darf kein isolierter operativer Prozess sein; sie muss als integraler Bestandteil der Architektur selbst behandelt werden. Autonomie ist letztlich nur so verlässlich wie die Mechanismen, die im Ernstfall Fehler erkennen und darauf reagieren. Indem Erkennung, Alarmierung und Behebung direkt in die Referenzarchitektur eingebettet werden, stellen Unternehmen sicher, dass die Fehlerbehandlung über alle Dienste hinweg konsistent bleibt. Das verschiebt den Fokus weg von der manuellen Brandbekämpfung hin zu einem System, das seinen eigenen Zustand versteht und aktiv verwaltet.
In der Praxis bedeutet dies, Paging-Plattformen und automatisierte Hooks für die Alarmierung direkt in die Deployment-Manifeste zu integrieren. Moderne Architekturen nutzen automatisierte Runbooks – oft als Code definiert –, die durch spezifische Systemereignisse ausgelöst werden können. So lassen sich Routineprobleme wie Memory Leaks oder Speicherengpässe beheben, ohne dass ein Mensch eingreifen muss. Darüber hinaus ermöglicht die Integration von Chaos Engineering in den Architektur-Lebenszyklus, gezielt Fehler zu provozieren. Dies validiert, ob die automatisierten Reaktionsmechanismen unter realen Stress wie erwartet funktionieren, und stellt sicher, dass ein einzelner Vorfall isoliert bleibt und nicht zu einem systemweiten Ausfall eskaliert.
Von lokaler Reaktion zu globaler Skalierung: Der Cloud-Native-Shift
Während das Einbetten von Runbooks in einzelne Dienste für kleine Umgebungen funktioniert, erfordert echte Autonomie eine Plattform, die diese Reaktionen über tausende von Knoten hinweg koordiniert. Hier entwickelt sich der Blueprint von einer Sammlung von Mustern hin zu einem lebendigen, atmenden Ökosystem.
Skalierung von Autonomie mit Cloud-Native-Architekturen
Der Aufstieg von Cloud-Native-Technologien hat den Bauplan für skalierbare Autonomie grundlegend verändert. Kubernetes und das dazugehörige Ökosystem nehmen Teams durch Controller und Abgleich-Schleifen zwar erheblichen operativen Aufwand ab – sie bilden das „Gehirn“, das das System permanent in den gewünschten Soll-Zustand steuert. Gleichzeitig führen sie jedoch neue Komplexitätsebenen bei der Koordination und Sicherheit ein. Um Autonomie in großem Maßstab zu erreichen, reicht es nicht aus, nur Container bereitzustellen; es bedarf einer gehärteten Infrastrukturebene, die ihren eigenen Zustand in verteilten Umgebungen eigenständig verwalten kann.
Eine robuste Cloud-Native-Referenzarchitektur konzentriert sich stark auf die Grenzen der Autonomie. Dazu gehört die Implementierung feingranularer rollenbasierter Zugriffskontrollen (RBAC) und Admission Controller, um genau zu definieren, was automatisierte Agenten innerhalb des Clusters tun dürfen. Policy-Enforcement-Layer wie OPA oder Kyverno stellen sicher, dass das System auch bei Selbstreparatur stets konform bleibt. Schließlich ruht die Zuverlässigkeit dieser autonomen Systeme auf einem Fundament aus verteiltem Konsens unter Nutzung von Tools wie etcd als „Source of Truth“ – sowie skalierbaren Speicherlösungen, die es Anwendungen ermöglichen, nahtlos über verschiedene Verfügbarkeitszonen hinweg wiederhergestellt zu werden.
Fazit: Das Fundament für Agentic SRE schaffen
Eine Referenzarchitektur ist mehr als nur ein statisches Diagramm – sie definiert, wie sich Ihre Infrastruktur unter Belastung verhalten darf. Indem Sie Modularität, Ausfallsicherheit und Skalierbarkeit in Ihrem Kerndesign festschreiben, schließen Sie die Lücke zwischen manuellen Skripten und einer wirklich agentenbasierten Strategie. Die Architektur ist jedoch nur das Fundament. Um ein „Lights-out”-Betriebsmodell vollständig zu realisieren, müssen Sie die darauf aufbauende Intelligenz orchestrieren.
Überlassen Sie die Autonomie Ihres Systems nicht dem Zufall. Sind Sie bereit, Ihren Architekturentwurf in eine aktive Verteidigung umzusetzen? Laden Sie ilert’s Agentic Incident Management Guide herunter, um zu erfahren, wie Architektur und KI zusammenwirken, um eine sichere, skalierbare und betriebsbereite Incident Response zu schaffen.
Hoppla! Beim Absenden des Formulars ist etwas schief gelaufen.
Unsere Cookie-Richtlinie
Wir verwenden Cookies, um Ihre Erfahrung zu verbessern, den Seitenverkehr zu verbessern und für Marketingzwecke. Erfahren Sie mehr in unserem Datenschutzrichtlinie.