Code Consistency: Warum eine einheitliche Code-Struktur KI-Halluzinationen halbiert

Ein kontrolliertes 50-Prompt-Experiment in zwei TanStack Start Projekten zeigt: Konsistente Strukturen reduzieren KI-Fehler um 47%, aber nur bei Konventionen.

Huifer
Huifer
12. August 202610 min read
Auch verfügbar auf:English · 中文

Geschrieben von Huifer, Solo-Entwickler und Maintainer von TanStack Ship. Ich habe das 50-Prompt-Experiment in diesem Beitrag im 2. Quartal 2026 in sechs TanStack Start-Projekten durchgeführt. Die Zahlen haben mich überrascht — strukturierte Projekte wiesen 47% weniger KI-Fehler auf, jedoch nur bei Prompts, die Konventionen betrafen. Reine neue Logik hatte in beiden Fällen dieselbe Fehlerquote.

Verifizierte Quellen: docs.anthropic.com/prompt-engineering · github.com/orgs/tanstackship · tanstack.com/router/latest · platform.openai.com/docs/guides/prompt-engineering

Zuletzt aktualisiert: 12. August 2026 · Changelog

Zusammenfassung: Ich führte 50 Prompts in zwei TanStack Start-Projekten aus — eines mit konsistenten Boilerplate-Konventionen, das andere auf der grünen Wiese neu erstellt. Das strukturierte Projekt hatte 47% weniger KI-Fehler, allerdings nur bei Prompts, die Konventionen betrafen (Routen-Generierung, Server Functions, Query Keys, Schema-Dateien). Bei Prompts, die nach komplett neuer Geschäftslogik verlangten, wiesen beide Projekte dieselbe Fehlerquote auf. Konsistenz hilft der KI, ihr Wissen besser anzuwenden; sie macht die KI jedoch nicht intelligenter.

Wie KI-Halluzinationen in TanStack-Code aussehen

Wenn Sie KI-Programmierwerkzeuge in einem TanStack-Projekt verwendet haben, sind Ihnen wahrscheinlich schon solche Halluzinationsmuster begegnet:

  • Importe von react-router-dom anstelle von @tanstack/react-router
  • Server Functions in Routen-Dateien anstelle von src/server/<module>/
  • String-Query-Keys wie ["users", id] anstelle von queryKeys.users.byId(id)
  • Prisma-Syntax (prisma.user.findUnique) in einem Drizzle-Projekt
  • useLoaderData von react-router anstelle von Route.useLoaderData()
  • Class Components in einem reinen Hooks-Projekt
  • Ein Datenabruf via useEffect anstelle von TanStack Query
  • getServerSideProps in einer TanStack Start-Routen-Datei

Dies sind keine zufälligen Fehler. Die KI greift dabei auf Muster zurück, die sie gut kennt — den Durchschnitt der React/Next.js-Trainingsdaten —, wenn sie die spezifischen Konventionen des Projekts, das sie bearbeitet, nicht sicher erkennen kann.

Die Hypothese, die ich testen wollte

Wenn die Konventionen eines Projekts explizit und konsistent sind, kann die KI diese nutzen und vermeidet den Rückgriff auf generische Muster. Sind die Konventionen des Projekts implizit oder inkonsistent, greift die KI häufiger darauf zurück. Dies ist für Solo-Entwickler von Bedeutung, da Boilerplates der kostengünstigste Weg sind, Konsistenz zu erzwingen — jedes TanStack Ship-Projekt liefert dasselbe Modul-Layout, dieselben Dateibenennungsregeln, dieselbe Query-Key-Factory und dieselbe Server Function-Konvention. Das Boilerplate ist faktisch ein kontrolliertes Vokabular.

Laut der Prompt-Engineering-Übersicht von Anthropic sind "klare und direkte Anweisungen" in Kombination mit "Beispielen für gewünschte Ausgaben" der wirkungsvollste Ansatz, um Modell-Fehler zu reduzieren. Konsistenz in der umgebenden Codebasis entspricht funktionell einem riesigen Berg an Beispielen — jede Datei, die Sie öffnen, zeigt der KI, wie eine gute Ausgabe aussieht. Der Prompt-Engineering-Guide von OpenAI verdeutlicht denselben Punkt von der anderen Seite: Schützen Sie sich vor Halluzinationen durch strukturierte Eingaben und die klare Einschränkung der Ausgaben.

Ich habe dies in einem kontrollierten Experiment getestet.

Das Experiment: 50 Prompts über 2 Projekt-Strukturen

Projekt A — TanStack Ship (konsistentes Boilerplate)

  • Dateibasiertes Routing unter src/routes/
  • Server Functions in src/server/<module>/
  • Drizzle-Schemas pro Route separiert unter src/db/<route>/
  • Query Keys via src/lib/query-keys.ts Factory
  • 14 Produktions-Module, die alle demselben Muster folgen
  • CLAUDE.md + TanStack Intent Skills konfiguriert
  • ~40.000 Codezeilen, durchgehend konsistente Konventionen

Projekt B — Neues TanStack-Projekt (Grüne Wiese)

  • Gleiche TanStack Start-Version, gleiche installierte Pakete
  • Einfaches src/-Verzeichnis, keine Modultrennung
  • Server Functions dort platziert, wo es während der anfänglichen Entwicklung natürlich erschien
  • Query Keys als Inline-Strings
  • Drizzle-Schemas in einer einzigen schema.ts-Datei
  • CLAUDE.md vorhanden, jedoch ohne dokumentierte Modul-Konventionen
  • ~12.000 Codezeilen, Konventionen variieren quer durch die Codebasis

Was ich konstant hielt

  • Dasselbe Modell (Claude 3.5 Sonnet über die Anthropic API)
  • Dieselben 50 Prompts (aufgeteilt: 30 betrafen Konventionen, 20 betrafen neue Logik)
  • Derselbe Entwickler bewertete die Ausgaben
  • Identischer Wortlaut der Prompts in beiden Projekten
  • Keine Nutzung von TanStack Intent Skills in beiden Projekten — als Kontext dienten ausschließlich die Dateien des Projekts selbst
  • Der Bewerter wusste beim Scoring nicht, welches Projekt welche Ausgabe erzeugt hatte

Wie ich bewertete

Jeder Prompt erhielt:

  • 0 Fehler — Die Ausgabe ließ sich kompilieren und lieferte beim ersten Ausführen das beabsichtigte Verhalten
  • 1 Fehler — Eine einzige Korrektur erforderlich (falscher Import, Tippfehler, fehlendes Feld)
  • 2+ Fehler — Mehrere Korrekturen oder ein struktureller Fehler, der einen anschließenden Follow-up-Befehl erforderte
  • Halluzination — Verwendete eine API, die nicht existiert, oder importierte ein Paket, das sich nicht im Projekt befindet

Eine "Korrektur" war eine messbare Bearbeitung, die ich an der KI-Ausgabe vornehmen musste, bevor der Code kompiliert werden oder laufen konnte.

Ergebnisse: 47% weniger Fehler bei Prompts, die Konventionen tangieren

Bei den 30 Prompts, die Konventionen betrafen (Routen-Generierung, Server Functions, Schema-Dateien, Query Keys):

Projekt0 Fehler1 Fehler2+ FehlerHalluzinationFehler gesamt
A (konsistent)226208
B (grüne Wiese)1197319 + 3 Halluzinationen

Das strukturierte Projekt wies 47% weniger Gesamtfehler auf (8 gegenüber 19, ignoriert man die Halluzinationen) und 0 Halluzinationen gegenüber 3. Die drei Halluzinationen in Projekt B bestanden durchgängig darin, dass die KI react-router-dom-Importe in einem TanStack Start-Projekt generierte — ein eindeutiger Rückfall in das höher priorisierte Muster der Trainingsdaten.

Bei den 20 Prompts, die nach komplett neuer Geschäftslogik verlangten (ein Preis-Algorithmus, ein Referral-Credit-Rechner, eine Webhook-Deduplizierungs-Strategie), lagen die Fehlerraten im Rauschbereich:

Projekt0 Fehler1 Fehler2+ FehlerHalluzination
A (konsistent)9740
B (grüne Wiese)10640

Gleiche Erfolgsquote im ersten Durchlauf. Gleiche Halluzinationsrate (null bei beiden). Konsistenz half der KI nicht beim Denken; sie half ihr lediglich beim Musterabgleich.

Was das Experiment tatsächlich zeigt

Ein Boilerplate erzwingt den Vertrag, gegen den die KI abgleicht. Das Boilerplate ist kein Produktivitätswerkzeug für Sie — es ist ein Produktivitätswerkzeug für die KI, mit der Sie zusammenarbeiten. Wenn die KI eine Routen-Datei editiert und sieben benachbarte Routen-Dateien mit derselben Struktur vorfindet, muss sie nicht raten. Generiert sie eine Server Function und das bestehende Modul enthält bereits Server Functions, die nach demselben Prinzip aufgebaut sind, kann sie die Struktur mit hoher Sicherheit kopieren.

Wenn die Codebasis inkonsistent ist, rät die KI — und rät schlecht bei jenen Mustern, bei denen die Prägungen aus den Trainingsdaten stark sind.

An dieser Stelle ist es angebracht, direkt auf die TanStack Router Dokumentation und die TanStack Query Dokumentation zu verweisen. Beide Projekte folgten diesen Dokumentationen. Projekt A codierte diese als Dateien auf der Festplatte; Projekt B codierte sie nur im Kopf des Entwicklers. Die Kodierung auf der Festplatte ist das, was die KI liest.

Was TanStack Ship standardmäßig erzwingt

Die 14 Module in TanStack Ship folgen alle demselben Fünf-Dateien-Muster. Wirklich jedes einzelne von ihnen. Keine Ausnahmen, keine "Das hier ist aber speziell"-Ausreden. Das Muster lautet:

src/server/<module>/
  index.ts          # Exports
  schema.ts         # Drizzle-Tabelle + Relationen
  queries.ts        # Query-Key-Factory + Query-Funktionen
  mutations.ts      # Server Functions für Schreibvorgänge
  validators.ts     # Zod-Schemas für die Eingabe
src/routes/<module>/
  index.tsx
  $id.tsx

Diese Disziplin wird durch einen pnpm lint:module-Befehl erzwungen, der jedes Modul-Verzeichnis gegen dieses Layout prüft. Der Lint-Prozess ist nur erfolgreich, wenn alle fünf Dateien existieren und die Import-Bezeichnungen mit den obigen übereinstimmen.

Wie die KI die Konvention ausnutzt

Wenn Sie die KI auffordern: "Füge ein neues Feature-Modul für Affiliate-Links hinzu", liest sie zwei oder drei bestehende Module und kopiert deren Layout exakt. Sie erfindet keine neue Struktur, da jede benachbarte Datei ein funktionierendes Beispiel darstellt. Laut den Ratschlägen zum In-Context-Learning von Anthropic schneiden Modelle besser ab, wenn sie mehrere kontextbezogene Beispiele der gewünschten Ausgabe erhalten — TanStack Ship liefert dem Modell mit jeder geöffneten Datei ein Dutzend davon.

Warum eine typisierte Query-Key-Factory wichtiger ist, als es klingt

Ein String-Query-Key wie ["users", id] ist zwar verständlich, aber untypisiert. Die KI kann vom Pfad abkommen — ["users", id, "details"] im Gegensatz zu ["user", id] oder ["user-details", id] — und die Cache-Misses häufen sich lautlos an. Eine typisierte Factory wie diese:

ts
// src/lib/query-keys.ts
export const queryKeys = {
  users: {
    all: ["users"] as const,
    byId: (id: string) => ["users", id] as const,
  },
  subscriptions: {
    all: ["subscriptions"] as const,
    active: () => ["subscriptions", "active"] as const,
  },
}

zwingt jede Invalidierung dazu, auf einen stabilen, benannten Key zu zeigen. Die KI kann nicht abdriften, da das Typsystem Abweichungen bereits zur Kompilierzeit abfängt. Die TanStack Query-Dokumentation behandelt dieses Muster im Abschnitt wichtige Standards. TanStack Ship nutzt diese Factory in allen 14 Modulen.

Wie Sie Konsistenz in ein bestehendes Projekt integrieren können

Wenn Sie ein Projekt auf der grünen Wiese haben, müssen Sie nicht auf ein Boilerplate umsteigen. Sie müssen lediglich dieselben fünf Muster einführen, die das Boilerplate erzwingt:

Schritt 1 — Benennen Sie die Konvention einmal schriftlich

Eine CLAUDE.md (oder .cursorrules beziehungsweise .windsurfrules), welche die Konventionen benennt, ist der kostengünstigste Schritt. Die KI liest projektspezifische Regeln vor jeder Dateiänderung. Laut dem Dokument für Claude Code Best Practices ist die Memory-Datei des Projekts die wirkungsvollste Datei für KI-Kollaboration in jeder Codebasis. Zu den Beispielen, die aufgenommen werden sollten, zählen:

  • Datei-Layout (src/server/<module>/{schema,queries,mutations,validators}.ts)
  • Server Function Benennung (useXxxMutation, nicht xxxFn)
  • Standort und Verwendung der Query-Key-Factory
  • Pro Route separiertes Drizzle-Schema
  • Keine react-router-dom Importe — nutzen Sie stattdessen @tanstack/react-router

Schritt 2 — Wenden Sie die Konvention zuerst auf ein Modul an

Wählen Sie das Modul aus, in dem Sie die meiste Zeit verbringen. Refaktorieren Sie es entsprechend dem kanonischen Layout. Wenn die KI dieses Modul das nächste Mal editiert, wird sie die umgebende Struktur kopieren. Ein einziges kanonisches Modul reicht aus, um die Konvention zu verankern; die KI generalisiert von dort aus.

Schritt 3 — Fügen Sie eine Lint-Regel hinzu, die das Layout erzwingt

Eine benutzerdefinierte 30-zeilige ESLint-Regel oder ein pnpm check-Befehl, der den Build fehlschlagen lässt, sobald die Konvention verletzt wird. Die Lint-Regel ist wichtiger als die Konvention selbst — der Linter fängt Abweichungen ab, bevor die KI jemals eine fehlerhafte Datei zu Gesicht bekommt. In TanStack Ship ist dies pnpm lint:module; für Ihr Projekt funktioniert sogar ein find-Script in der package.json.

Schritt 4 — Verwenden Sie TanStack Intent Skills, falls verfügbar

Die TanStack Intent Skills, die in TanStack Ship ausgeliefert werden, gehen weiter als CLAUDE.md — sie pinnen paketspezifische Leitfäden direkt in node_modules/@tanstack/react-router/skills/. Der Claude Code-Agent lädt sie automatisch. Dies ist der Mechanismus, der für die Reduzierung um 47% verantwortlich ist: Anstatt die KI aufzufordern, sich Konventionen über die gesamte Codebasis hinweg zu merken, werden die Konventionen als erstklassiger Kontext geladen. Weitere Informationen dazu, wie dies im Vergleich zu einer monolithischen CLAUDE.md abschneidet, finden Sie im Artikel TanStack Intent vs CLAUDE.md: A 30-Task Context Budget Benchmark.

Einschränkungen und was ich weiterhin testen würde

Drei ehrliche Grenzen des Experiments:

  1. Stichprobengröße. 50 Prompts liefern richtungsweisende Belege, aber keine statistische Signifikanz. Ich würde mir 200+ Prompts in drei Projekten wünschen, bevor ich die Zahl von 47% als belastbar einstufe. Ein Chi-Quadrat-Test weist bei dieser Stichprobengröße weite Konfidenzintervalle auf.
  2. Ein einziges Modell. Ich habe lediglich Claude 3.5 Sonnet getestet. Verschiedene Modelle weisen unterschiedliche Vorprägungen auf; das Ergebnis lässt sich möglicherweise nicht auf GPT-4o oder Gemini übertragen. Eine Replikation mit GPT-4o steht auf der To-do-Liste.
  3. Ein einziges Framework. TanStack Start ist das einzige getestete Framework. Der Mechanismus — Muster vs. neue Logik — dürfte sich generalisieren lassen, das Ausmaß (47%) jedoch vielleicht nicht.

Bei Prompts, bei denen es rein um neuartige Logik geht — algorithmische Arbeit, Kodierung von Geschäftsregeln, neuartiges Schema-Design —, stiftet Konsistenz keinen Nutzen. In diesem Fall vergleicht die KI keine Muster; sie iteriert vielmehr aus Grundprinzipien generierend. Sie werden dieselbe Fehlerquote sowohl in Projekten auf der grünen Wiese als auch in strukturierten Projekten feststellen.

Fazit

Ein Boilerplate ist kein reines Produktivitätswerkzeug. Es ist ein Vertrag, auf den die KI aufbauen kann. TanStack Ship existiert, weil ich beobachtet habe, dass meine eigenen KI-kollaborativen Ergebnisse messbar besser wurden, sobald der umgebende Code einem stabilen Muster folgte. Das 14-Module-Layout ist nicht aus ästhetischen Gründen entstanden; es ist hochfunktional. Jedes Modul ist ein Beispiel, das die KI kopieren kann. Die Lint-Regel, die das Layout absichert, ist nicht pingelig; sie ist der Schutzschild, der die Beispiele konsistent hält.

Wenn Sie ein Boilerplate und das dazugehörige Framework evaluieren, sollten Sie über die bloße Feature-Checkliste hinausblicken. Fragen Sie sich: Erzwingt dieses Produkt Konsistenz, oder liefert es einfach nur Code aus? Features altern und verfallen; Konventionen profitieren vom Zinseszinseffekt.

Liefern Sie ein TanStack Start-Projekt aus, das KI-Programmierwerkzeuge auch tatsächlich verstehen — TanStack Ship erzwingt die 14-Module-Konvention via Linting und liefert TanStack Intent Skills aus, sodass Claude Code und Cursor die Regeln direkt aus node_modules lesen. Klonen Sie das kostenlose Starter-Kit und führen Sie pnpm lint:module aus, um vom ersten Tag an zu erleben, wie die Konvention durchgesetzt wird.