Was macht Karpathy-Richtlinien für Hermes?
Verhaltensrichtlinien zur Reduzierung häufiger LLM-Codierungsfehler, abgeleitet von Andrej Karpathys Beobachtungen zu LLM-Coding-Fallstricken.
Tradeoff: Diese Richtlinien bevorzugen Vorsicht gegenüber Geschwindigkeit. Bei trivialen Aufgaben (Tippfehler-Korrekturen, offensichtliche Einzeiler) das eigene Urteilsvermögen einsetzen – nicht jede Änderung benötigt volle Strenge.
Wann dieser Skill geladen werden sollte
Immer aktiv bei:
- Schreiben von neuem Code
- Bearbeiten vorhandenen Codes
- Überprüfen von Code
- Refactoring von Code
- Planen von Codeänderungen
Nur überspringen, wenn:
- Der Benutzer explizit sagt „mach es einfach schnell“
- Reine Konfigurationsdateien (YAML, JSON, env)
- Wegwerf-Prototypen, die der Benutzer als solche bestätigt hat
Die vier Prinzipien
1. Denken vor dem Codieren
Nicht annehmen. Verwirrung nicht verbergen. Tradeoffs offenlegen.
Bevor IRGENDETWAS implementiert wird:
- Annahmen explizit nennen. Bei Unsicherheit nachfragen.
- Mehrere Interpretationen? Sie präsentieren – nicht stillschweigend eine auswählen.
- Gibt es einen einfacheren Ansatz? Sag es. Zurückhaltung anmelden, wenn angebracht.
- Etwas unklar? Anhalten. Nennen, was verwirrt. Nachfragen.
Schlecht:
„Ich werde jetzt die Exportfunktion implementieren.“ [fährt mit Annahmen fort]
Gut:
„Vor der Implementierung muss ich klären:
- Alle Benutzer exportieren oder gefiltert? (Datenschutzimplikationen)
- Dateidownload, API-Endpunkt oder Hintergrundjob?
- Welche Felder? Einige könnten sensibel sein. Was ist Ihre Präferenz?“
Der Test: Wenn Sie kurz davor sind, Code zu schreiben, und Ihre Annahmen nicht genannt haben, machen Sie es falsch.
2. Einfachheit zuerst
Minimaler Code, der das Problem löst. Nichts Spekulatives.
Regeln:
- Keine Funktionen über das Geforderte hinaus
- Keine Abstraktionen für einmalig verwendeten Code
- Keine „Flexibilität“ oder „Konfigurierbarkeit“, die nicht angefragt wurde
- Keine Fehlerbehandlung für unmögliche Szenarien
- Wenn Sie 200 Zeilen schreiben und es könnten 50 sein, schreiben Sie es neu
Fragen Sie sich: „Würde ein Senior Engineer sagen, das ist überkompliziert?“ Wenn ja, vereinfachen.
Schlecht:
# Strategy Pattern, abstrakte Basisklasse, Konfigurationssystem...
# für eine einzelne Rabattberechnung
class DiscountStrategy(ABC):
@abstractmethod
def calculate(self, amount: float) -> float: pass
class PercentageDiscount(DiscountStrategy):
# 50+ Zeilen
Gut:
def calculate_discount(amount: float, percent: float) -> float:
return amount * (percent / 100)
Wann Komplexität hinzufügen: Nur wenn Sie sie tatsächlich brauchen. Später umgestalten, wenn Anforderungen entstehen.
3. Chirurgische Änderungen
Nur das berühren, was nötig ist. Nur das eigene Chaos aufräumen.
Beim Bearbeiten vorhandenen Codes:
- Nicht angrenzenden Code, Kommentare oder Formatierung „verbessern“
- Nicht Dinge umgestalten, die nicht kaputt sind
- Vorhandenen Stil beibehalten, auch wenn man es selbst anders machen würde
- Wenn man unabhängigen toten Code bemerkt, erwähnen – nicht löschen
Wenn eigene Änderungen Waisen erzeugen:
- Imports/Variablen/Funktionen entfernen, die durch DIE EIGENEN Änderungen ungenutzt wurden
- Vorhandenen toten Code nicht entfernen, es sei denn, es wird darum gebeten
Der Test: Jede geänderte Zeile sollte direkt auf die Benutzeranfrage zurückgehen.
Schlecht:
- def upload_file(file_path, destination):
+ def upload_file(file_path: str, destination: str) -> bool:
+ """Upload file to destination with logging."""
+ logger.info(f"Uploading {file_path} to {destination}")
try:
- with open(file_path, 'rb') as f:
+ with open(file_path, "rb") as f:
[Typannotationen, Docstring, geänderter Anführungsstil hinzugefügt – nichts davon wurde angefragt]
Gut:
+ import logging
+ logger = logging.getLogger(__name__)
+
def upload_file(file_path, destination):
+ logger.info(f'Starting upload: {file_path}')
try:
with open(file_path, 'rb') as f:
[Nur das angefragte Logging hinzugefügt. Vorhandenen Stil beibehalten.]
4. Zielorientierte Ausführung
Erfolgskriterien definieren. Schleife bis zur Verifikation.
Imperative Aufgaben in überprüfbare Ziele umwandeln:
| Statt... | Umwandeln in... |
|---|---|
| „Validierung hinzufügen“ | „Tests für ungültige Eingaben schreiben, dann bestehen lassen“ |
| „Fehler beheben“ | „Test schreiben, der ihn reproduziert, dann bestehen lassen“ |
| „X umgestalten“ | „Sicherstellen, dass Tests vorher und nachher bestehen“ |
| „Zum Laufen bringen“ | „Definieren, was 'läuft' bedeutet, Test schreiben, überprüfen“ |
Bei mehrschrittigen Aufgaben einen kurzen Plan nennen:
1. [Schritt] → überprüfen: [Prüfung]
2. [Schritt] → überprüfen: [Prüfung]
3. [Schritt] → überprüfen: [Prüfung]
Starke Erfolgskriterien ermöglichen unabhängige Schleifen. Schwache Kriterien („zum Laufen bringen“) erfordern ständige Klärung.
Schlecht:
„Ich werde den Authentifizierungscode überprüfen und Verbesserungen vornehmen.“ [Ändert Dinge ohne klare Kriterien]
Gut:
„Um die Authentifizierung zu beheben, brauche ich Erfolgskriterien. Problem: Benutzer bleiben nach Passwortänderung eingeloggt. Plan:
- Test schreiben: Passwort ändern → alte Sitzung ungültig
- Fix implementieren
- Überprüfen, dass Test besteht + keine Regressionen Starte mit Schritt 1.“
Integration mit Hermes
Dieser Skill arbeitet zusammen mit anderen Hermes-Skills:
- [[test-driven-development]] – Kombinieren mit Prinzip 4 (Zielorientiert). TDD ist die Verifikationsschleife.
- [[systematic-debugging]] – Kombinieren mit Prinzip 1 (Denken vor dem Codieren). Erst debuggen, dann fixen.
- [[writing-plans]] – Kombinieren mit Prinzip 4. Mehrschrittige Aufgaben brauchen Pläne mit Überprüfung.
- [[requesting-code-review]] – Alle vier Prinzipien gelten während der Überprüfung.
Anti-Patterns Kurzreferenz
| Prinzip | Anti-Pattern | Lösung |
|---|---|---|
| Denken vor dem Codieren | Nimmt stillschweigend Format, Felder, Umfang an | Annahmen auflisten, um Klärung bitten |
| Einfachheit zuerst | Strategy Pattern für eine einzelne Funktion | Eine Funktion, bis Komplexität nötig ist |
| Chirurgische Änderungen | Formatiert Anführungszeichen um, während ein Fehler behoben wird | Nur Zeilen ändern, die das Problem beheben |
| Zielorientiert | „Ich werde überprüfen und verbessern“ | „Test schreiben → fixen → überprüfen“ |
Wichtige Erkenntnis
Von Karpathy:
„LLMs sind außergewöhnlich gut darin, zu loopen, bis sie bestimmte Ziele erreichen... Sag ihm nicht, was es tun soll, gib ihm Erfolgskriterien und sieh zu, wie es loslegt.“
Guter Code löst das heutige Problem einfach, nicht das morgige Problem voreilig.
Woran man erkennt, dass es funktioniert
Diese Richtlinien funktionieren, wenn man sieht:
- Weniger unnötige Änderungen in Diffs – Nur angeforderte Änderungen erscheinen
- Weniger Neuschreibungen aufgrund von Überkomplexität – Code ist von Anfang an einfach
- Klärungsfragen kommen vor der Implementierung – Nicht nach Fehlern
- Saubere, minimale PRs – Keine Vorbeiflug-Umgestaltungen oder „Verbesserungen“
Vollständige Beispiele
Siehe references/EXAMPLES.md für detaillierte Vorher-Nachher-Beispiele zu jedem Prinzip.