Gute Regeln schreiben: Der KI Grenzen setzen

Serie: KI in der Softwareentwicklung
Teil 2 von 7 — Gute Regeln schreiben: der KI Grenzen setzen

Eine KI ohne Regeln ist wie ein Praktikant ohne Styleguide: technisch fähig, aber stilistisch unberechenbar. Sie schreibt Code, der funktioniert — aber nicht zu deinem Projekt passt. Regeln sind keine Einschränkung, sie sind die Leitplanken, die den Unterschied zwischen brauchbarem und unbrauchbarem Output machen.

Was gehört in die Regeln?

Regeln beschreiben wie in deinem Projekt Code geschrieben wird. Nicht im Sinne von Dokumentation, sondern als verbindliche Vorgaben, an die sich jeder hält — Mensch wie Maschine. Dazu gehören Code-Style-Entscheidungen: Strict Types in jeder PHP-Datei, finale Klassen als Standard, Methodennamen in camelCase, Properties mit Typ-Deklaration. Das klingt selbstverständlich, aber ohne explizite Regel entscheidet die KI nach statistischer Häufigkeit in ihren Trainingsdaten — und die weicht von deinem Projekt ab.

Dann die verbotenen Patterns. Kein var_dump(), kein die(), kein exit(), kein // TODO ohne konkreten Inhalt. Keine auskommentierten Codeblöcke — wenn Code nicht gebraucht wird, wird er gelöscht, nicht auskommentiert. Das Git-Log ist dein Archiv. Dazu kommen Architektur-Constraints: saubere Schichtentrennung, Dependency Injection statt statischer Aufrufe, keine Geschäftslogik in Controllern, keine SQL-Queries außerhalb von Repositories.

Testing-Anforderungen gehören ebenfalls in die Regeln — welche Art von Tests du erwartest, ob Mocks erlaubt sind oder ob du auf Integration-Tests setzt, welche Coverage-Ziele gelten. Und die Kommentarsprache: In meinen Projekten schreibe ich deutsche Kommentare, die das Warum erklären, nie das Was. Das muss die KI wissen, sonst liefert sie englische Romane über offensichtlichen Code. Ein // Increment counter über $counter++ ist nutzlos — ein // Retry-Counter für transiente API-Fehler erklärt den Kontext.

Warum Regeln den Unterschied machen

Ohne Regeln passiert Folgendes: Du arbeitest an einem WordPress-Theme, das bewusst auf jQuery verzichtet. Die KI kennt diese Entscheidung nicht und bindet fröhlich jQuery ein, weil WordPress es mitliefert und die meisten Tutorials darauf aufbauen. Das ist kein Fehler der KI — es ist die statistisch wahrscheinlichste Lösung. Oder du pflegst ein Projekt mit strikt deutschen Kommentaren, und die KI schreibt plötzlich // This function handles the user input, weil ihre Trainingsdaten überwiegend englisch sind.

Mit einer einzigen Regel — Kein jQuery. Vanilla JS only. — ist das Problem gelöst. Die KI hält sich daran, weil sie Regeln als harte Constraints behandelt, nicht als Vorschläge. Das funktioniert erstaunlich zuverlässig. Nicht perfekt — gelegentlich schleicht sich trotzdem ein $.ajax() ein — aber gut genug, dass du nicht jede Zeile auf jQuery-Imports prüfen musst. Und wenn es doch passiert, ist es ein einzelner Fix statt eines systematischen Problems.

Hier ein konkretes Vorher-Nachher. Ohne Regel fragt man: „Erstelle eine Klasse für den Warenkorb.“ Die KI liefert eine 200-Zeilen-Klasse mit Error-Handling für Szenarien, die nie eintreten, drei Abstraktionsebenen und einem Observer-Pattern für Preis-Updates. Du wolltest eine einfache Klasse — du bekommst ein Framework. Mit der Regel „Keine Abstraktionen ohne konkreten zweiten Anwendungsfall“ bekommst du eine schlanke Klasse, die genau das tut, was du brauchst. Nicht mehr, nicht weniger.

Technologiespezifische Regeln — ausführbar, nicht nur dokumentiert

Die besten Regeln sind die, die nicht nur in einer Markdown-Datei stehen, sondern von der CI/CD-Pipeline erzwungen werden. Eine PHPStan-Konfiguration ist eine ausführbare Regel. Eine PHP-CS-Fixer-Config ist eine ausführbare Regel. Ein Pre-Commit-Hook, der Tests ausführt, ist eine ausführbare Regel. Die KI kann diese Dateien lesen und versteht daraus, welches Qualitätsniveau erwartet wird.

# phpstan.neon — Level 9, keine Ausnahmen
parameters:
    level: 9
    paths:
        - src
    treatPhpDocTypesAsCertain: false
    reportUnmatchedIgnoredErrors: true

Wenn die KI diese Datei sieht, weiß sie: Level 9, keine Tricks, keine ignorierten Fehler. Das beeinflusst den generierten Code direkt — sie schreibt sauberere Typen, prüft Nullable-Werte, vermeidet Mixed-Types. Ohne die Datei wäre der Code vielleicht syntaktisch korrekt, aber bei der ersten PHPStan-Analyse fallen 30 Fehler auf, die du manuell fixen musst.

Dasselbe gilt für eine PHP-CS-Fixer-Config, die Coding-Standards erzwingt: Die KI hält sich an den Style, weil sie weiß, dass der Fixer sonst Änderungen vornimmt. Für unterschiedliche Technologien brauchst du unterschiedliche Regelsets. Ein WordPress-Projekt hat andere Conventions als ein Symfony-Projekt. Ein .NET-Projekt andere als PHP. Technologiespezifische Regeln gehören in technologiespezifische Dateien, nicht in eine universelle Regeldatei, die alles abdecken will und dabei nichts richtig abdeckt.

Regeln als lesbares Dokument vs. ausführbare Konfiguration

Beide Formen ergänzen sich. Die Markdown-Datei in .ai/rules/ beschreibt die Absicht hinter den Regeln — warum finale Klassen der Standard sind, warum du Dependency Injection erzwingst, warum Kommentare deutsch sein müssen. Die Konfigurationsdateien (phpstan.neon, .php-cs-fixer.php, .editorconfig) sind die maschinenlesbare Umsetzung dieser Absichten. Die KI liest beide und versteht den Zusammenhang.

Ein Beispiel: Deine Regel sagt „Alle Methoden müssen Return-Types haben“. Die PHPStan-Config erzwingt das auf Level 9. Die KI sieht beides und generiert Code mit Return-Types — nicht weil sie die Regel gelesen hat, sondern weil sie beide Quellen kombiniert. Redundanz ist hier kein Problem, sondern Absicherung. Wenn eine Quelle fehlt oder unklar ist, kompensiert die andere.

Die wichtigste Regel von allen

Wenn du nur eine einzige Regel definierst, dann diese: „Keine Features über den Auftrag hinaus.“ Die KI liebt es, über-zu-liefern. Du fragst nach einer einfachen Validierung, und sie baut dir ein komplettes Validation-Framework mit Custom-Exception-Klassen, einem ValidationResult-Objekt und einem ValidationPipeline-Pattern. Du wolltest drei Zeilen — du bekommst dreißig.

Das ist kein Qualitätsmerkmal, das ist ein Problem. Jede Zeile Code, die du nicht angefordert hast, ist eine Zeile, die du reviewen, testen und langfristig warten musst. Unerwünschte Abstraktionen sind technische Schulden vom ersten Tag an. Sie machen den Code komplexer, ohne einen Mehrwert zu liefern, und verwirren jeden Entwickler, der den Code später liest und sich fragt, warum hier ein Pattern existiert, das nirgendwo sonst im Projekt vorkommt.

In meiner CLAUDE.md steht deshalb explizit: Nur das umsetzen, was beauftragt wurde. Keine zusätzlichen Abstraktionen, keine vorausschauende Architektur, kein Refactoring von Code, der nicht Teil der Aufgabe ist. Seit diese Regel existiert, hat sich die Qualität des KI-Outputs spürbar verbessert — nicht weil der Code technisch besser ist, sondern weil er zum Projekt passt statt zum KI-eigenen Idealbild von sauberem Code.

Regeln pflegen, nicht vergessen

Regeln sind kein einmaliges Setup. Sie wachsen mit dem Projekt. Wenn du feststellst, dass die KI wiederholt den gleichen Fehler macht — etwa immer wieder array statt einer typisierte Collection verwendet — füge eine Regel hinzu. Wenn eine Regel obsolet wird, weil sich der Stack geändert hat, entferne sie. Tote Regeln sind wie toter Code: Sie verwirren und kosten Aufmerksamkeit.

Regeln schreiben kostet eine halbe Stunde. Regeln nicht schreiben kostet Wochen an Korrekturen. Die Rechnung ist einfach. Und sobald du einmal ein gutes Regelset für deine Technologie hast, kannst du es als Template für das nächste Projekt wiederverwenden. Die initiale Investition zahlt sich über alle folgenden Projekte aus.

Negative Regeln sind mächtiger als positive

Eine Beobachtung aus der Praxis: Verbote wirken stärker als Gebote. „Keine statischen Methoden außer Factory-Methods“ hält die KI zuverlässiger ein als „Bevorzuge Instanzmethoden“. „Keine Klasse über 200 Zeilen“ funktioniert besser als „Halte Klassen kurz“. Das liegt daran, wie die KI Constraints verarbeitet — ein klares Verbot ist eine harte Grenze, eine Empfehlung ist ein weiches Signal, das gegen die Trainingsdata-Gewohnheiten ankämpft.

Mein Regelset besteht deshalb zu zwei Dritteln aus Verboten. Kein @-Error-Suppression-Operator. Keine phpstan-ignore-Kommentare. Keine Magic Numbers ohne Konstante. Kein auskommentierter Code. Keine else-Blöcke nach return. Das klingt restriktiv, aber es eliminiert genau die Patterns, die erfahrungsgemäß zu Problemen führen — und die KI hält sich daran, weil die Grenzen eindeutig sind.

Ein konkretes Beispiel: Die Regel Kein auskommentierter Code — Git ist das Archiv verhindert, dass die KI alte Implementierungen als Kommentare stehen lässt. Ohne diese Regel kommentiert die KI die alte Version aus und schreibt die neue darunter — „für den Fall, dass du die alte Version noch brauchst“. Nett gemeint, aber Gift für die Codequalität. Mit der Regel löscht sie den alten Code konsequent, und du nutzt git log, wenn du den alten Stand sehen willst.

Alle Teile dieser Serie

Teil 1: Projekt vorbereiten — Dateien, Struktur, Kontext
Teil 2: Gute Regeln schreiben — der KI Grenzen setzen
Teil 3: Saubere Prompts — präzise formulieren, Token sparen
Teil 4: Modelle und Tools — Stärken, Schwächen, Einsatzgebiete
Teil 5: Sicherheit — was nicht in den Prompt gehört
Teil 6: Reviews — warum der Mensch das letzte Wort haben muss
Teil 7: Wann KI nicht nutzen — die Grenzen kennen
Glossar: Begriffe für Entwickler

Die gezeigten Code-Beispiele dienen zur Veranschaulichung. Nutzung auf eigene Verantwortung. Mehr dazu