Wir versenden Headless-Websites für Clients, die alles messen -- Core Web Vitals, Schema-Markup, Barrierefreiheits-Scores, organische Traffic-Deltas. Ein schlechter Deploy kann Rankings, die Monate zum Aufbau brauchten, zum Einsturz bringen. Also als Anthropic Subagents, Hooks und Skills in Claude Code einführte, bauten wir unsere gesamte Pre-Deploy-Pipeline um sie herum auf.

Dieser Beitrag geht durch unser exaktes Setup: die .claude/ Verzeichnisstruktur, jede Subagent-Definition, die Hook-Konfigurationen und die Skill-Dateien, die alles zusammenbinden. Wir teilen vier echte Incidents, die das System erwischt hat, die ROI-Mathematik bei unserem Maßstab und wo dieser Ansatz noch Lücken hat.

Wir hatten einen CLS-Anstieg von 40%, der trotzdem in Production ging

Vor drei Wochen. Blog-Redesign eines Clients. Alles sah in der Entwicklung gut aus. Wir haben gemergt.

Zwei Tage später sendet der CTO des Clients einen Screenshot aus der Search Console. CLS sprang von 0,08 auf 0,14 auf Mobilgeräten. Seiten, die #3 für "enterprise billing software" rankten, fielen auf #8. Umsatzauswirkungen? Sie schätzten 40.000 $/Monat.

Das Problem? Ein Hero-Image, das asynchron geladen wurde, aber keine Größenattribute hatte. Klassisch. Unser CI erwischte nichts, weil wir Layout-Verschiebungen auf dem eigentlichen Preview-Build nicht überprüften.

Das ist, als wir anfingen, Subagents zu betrachten.

Subagents sind scoped Claude Code Instanzen, die innerhalb einer übergeordneten Session mit ihrem eigenen System-Prompt, Tool-Zugang und Task-Grenze ausgeführt werden. Hooks triggern Subagents an bestimmten Punkten -- vor dem Ausführen eines Befehls, nach Dateiänderungen oder bei einem Commit. Skills sind wiederverwendbare Anweisungsdateien (Markdown), die Claude beibringen, wie man eine bestimmte Aufgabe ausführt.

Anthropic versendete das Redesign am 14. April 2025 und führte Routines neben diesen Primitiven ein. Für unseren Anwendungsfall gaben uns rohe Subagents plus Hooks feinere Kontrolle darüber, genau wann jede Überprüfung ausgelöst wird und welchen Kontext sie erhält.

Der Schlüsselunterschied zu traditionellen CI-Checks: Subagents können über Ergebnisse nachdenken, Fehler über Checks hinweg korrelieren und leserfreundliche Zusammenfassungen schreiben. Ein CI-Job gibt Exit-Code 0 oder 1 zurück. Ein Subagent gibt zurück: "Die strukturierten Daten auf /blog/[slug] fehlt das Feld dateModified, das in der vorherigen Version vorhanden war. Dies wird wahrscheinlich innerhalb von 3-5 Tagen zu einer Regression des Rich Snippets in Google Search Console führen."

Das ist der Sinn der Sache.

Drei Monate später brach unser GitHub Actions-Setup endlich zusammen

Unsere vorherige Pipeline war ein Durcheinander von GitHub Actions, die Lighthouse CI, pa11y, linkinator und benutzerdefinierte Node-Skripte aufrufen. Es funktionierte.

Irgendwie.

Aber es hatte drei Probleme.

Kein Nachdenken zwischen Checks. Wenn Lighthouse ein CLS-Problem flaggte und der Barrierefreiheits-Scan ein fehlendes Alt-Tag auf demselben Image flaggte, bekamen wir zwei separate Benachrichtigungen ohne Verbindung. Engineers mussten manuell durch CI-Logs greifen, Zeitstempel korrelieren, herausfinden, dass es dieselbe Komponente war.

Zeitverschwendung.

Zerbrechliche Konfiguration. Jedes Tool hatte seine eigene Konfigurationsdatei, Schwellenwertformat und Output-Schema. Schwellenwerte zu aktualisieren bedeutete, 4-6 Dateien zu berühren. YAML hier. JSON dort. Umgebungsvariablen an einem dritten Ort. Ein Tippfehler und die gesamte Pipeline beendet sich mit 0, wenn sie scheitern sollte.

Keine kontextuellen Erklärungen. Engineers bekamen bestanden/nicht bestanden. Junior Devs verbrachten 20-40 Minuten damit, zu verstehen, warum etwas fehlschlug und was man dagegen tun kann. "Barrierefreiheits-Score: 87" sagt dir nicht, welches ARIA-Attribut fehlt oder warum es für Screen Reader wichtig ist.

Wir würden 3 Stunden pro Woche damit verbringen, False Positives zu debuggen oder Fehler in Slack zu erklären.

Der Tropfen, der das Fass zum Überlaufen brachte? August 2025. Wir pushen ein Northwind Traders Redesign um 16 Uhr an einem Freitag (ich weiß). Lighthouse bestanden. Barrierefreiheit bestanden. Links bestanden. Wir haben geshipt.

Montagmorgen schickt der VP of Marketing des Clients uns eine E-Mail. "Warum fehlen unsere Produktseiten in Google?" Es stellte sich heraus, dass wir versehentlich robots Meta auf jeder Seite unter /products/ auf noindex setzen. Unser CI überprüfte keine Robots-Tags. Es dauerte sechs Tage, bis die Seite wieder indexiert wurde. Sie verloren etwa 12.000 $ geschätzten Umsatz.

Wir brauchten kein weiteres CI-Tool -- wir brauchten eine Orchestrierungs-Ebene, die über die Outputs von Tools nachdenken konnte, denen wir bereits vertrauten. Gut geschriebene Skill-Dateien sind der Unterschied zwischen einem Subagent, der Barrierefreiheitsregeln halluziniert und einem, der pa11y mit den richtigen Flags ausführt und die JSON-Output korrekt interpretiert.

Unsere .claude/ Verzeichnisstruktur

Hier ist der eigentliche Baum:

.claude/
├── settings.json
├── agents/
│   ├── seo-regression.md
│   ├── cwv-smoke.md
│   ├── accessibility.md
│   ├── broken-links.md
│   ├── schema-validation.md
│   └── deploy-gate.md
├── skills/
│   ├── run-lighthouse.md
│   ├── run-pa11y.md
│   ├── run-linkinator.md
│   ├── parse-schema-org.md
│   ├── compare-seo-snapshot.md
│   └── format-deploy-report.md
└── snapshots/
    └── seo-baseline.json

Das Verzeichnis snapshots/ speichert Baseline-Daten für Vergleich-Checks. Einfach. Wir versionieren es in Git, damit wir sehen können, was sich geändert hat, wenn ein Client fragt "warum sind Rankings am letzten Dienstag gefallen?"

Nichts Ausgefallenes. Nur Markdown-Dateien und JSON.

Ein Client rief um 23 Uhr an, weil Google alle ihre Rich Snippets löschte

September 2025. Wir bauen eine E-Commerce-Website für einen mittleren Einzelhändler (nennen wir ihn Acme Home Goods). Sie hatten sechs Monate damit verbracht, Rich Snippets -- Produkt-Sterne, Preise, Verfügbarkeit -- in den Suchergebnissen anzuzeigen.

Wir pushen ein Shopify Theme-Update. Sieht gut aus. Shippet Freitagnacht.

Samstag um 23:14 Uhr bekomme ich einen Text. "Unsere Produktseiten sehen in Google kaputt aus. Sterne sind weg. Preise sind weg. Was ist passiert?"

Ich öffne Search Console. Jede einzelne Produktseite wirft Fehler bei strukturierten Daten auf. Das Feld offers fehlt priceCurrency. Ohne es, wird Google das Rich Snippet nicht anzeigen. Rankings fielen nicht, aber die Click-Through-Rate ging von 4,2% auf 1,8% über Nacht.

Kosten? Etwa 8.000 $/Woche in verlorenem Traffic, bis wir es fixten und Google alles erneut crawlt.

Das Schema war da. Wir haben nur den Property-Namen von priceCurrency zu currency geändert, weil die Shopify API diesen Key verwendet. Haben nicht darüber nachgedacht. Keine Validierung erwischt es.

Das ist, als wir den Schema-Validierungs-Subagent bauten.

Du erstellst eine Markdown-Datei in .claude/agents/ mit einem System-Prompt, einer Liste erlaubter Tools und Task-Anweisungen. Die übergeordnete Session (oder ein Hook) spawnt ihn mit dispatch_agent() oder über die Hook-Konfiguration in settings.json.

Minimale Struktur:

# Agent: [Name]

## Rolle
[One-Line-Beschreibung]

## Erlaubte Tools
- Bash (begrenzt auf spezifische Befehle)
- Datei lesen
- Datei schreiben

## Anweisungen
[Schritt-für-Schritt Task-Beschreibung, mit Verweisen auf Skill-Dateien]

## Output-Format
[Exaktes Format, das die übergeordnete Instanz erwartet]

Seien Sie extrem spezifisch über das Output-Format. Wenn der Deploy-Gate-Orchestrator JSON mit einem passed Boolean und einem summary String erwartet, sagen Sie das deutlich. Subagents, die freien Text zurückgeben, unterbrechen die Orchestrierung. Wir lernten das auf die harte Tour, als ein Subagent Markdown-Tabellen zurückgab und der Deploy-Gate sie nicht parsen konnte. Es dauerte zwei Stunden um 2 Uhr morgens zum Debuggen, weil die übergeordnete Instanz einfach stillschweigend fehlschlug. Kein Fehler. Nur funktionierte nicht.

Machen Sie meinen Fehler nicht. Sperren Sie das Format.

Subagent 1: SEO-Regressions-Check

Dies vergleicht die SEO-kritischen Elemente des aktuellen Builds mit einem Baseline-Snapshot.

# Agent: SEO-Regressions-Check

## Rolle
Erkenne SEO-Regressionen zwischen dem aktuellen Build und dem gespeicherten Baseline.

## Erlaubte Tools
- Bash (nur Node-Skripte)
- Datei lesen

## Anweisungen
1. Lese die Skill-Datei unter .claude/skills/compare-seo-snapshot.md
2. Führe aus: node scripts/extract-seo-meta.js --url=$PREVIEW_URL --output=/tmp/seo-current.json
3. Lese .claude/snapshots/seo-baseline.json
4. Vergleiche die zwei Snapshots Feld für Feld:
   - Title Tags (exakte Übereinstimmung)
   - Meta-Beschreibungen (Ähnlichkeit > 0,85)
   - Canonical URLs (exakte Übereinstimmung)
   - H1-Anzahl (muss 1 pro Seite sein)
   - Robots Meta (darf sich nicht zu noindex geändert haben)
   - Open Graph Tags (og:title, og:description, og:image vorhanden)
5. Flagge jede Seite, bei der sich Robots zu noindex geändert hat als KRITISCH.
6. Flagge fehlende oder doppelte Title Tags als HOCH.
7. Flagge Meta-Beschreibungsänderungen > 15% Unterschied als MITTEL.

## Output-Format
{"passed": boolean, "critical": [], "high": [], "medium": [], "summary": string}

Das Skript extract-seo-meta.js ist 120 Zeilen Puppeteer, die jede Seite in der Sitemap treffen und Title, Meta, Canonicals, H1s und OG-Tags zu JSON dumpt. Nichts Cleveres. Nur Extraktion.

Der Wert des Subagents liegt in der Vergleich und Reasoning, nicht der Extraktion. Es weiß, welche Änderungen wichtig sind. Welche sind kosmetisch. Welche werden den Client nächstes Quartal 15.000 $ in organischen Traffic kosten.

Beispiel: Wenn du eine Meta-Beschreibung von "Best CRM software for small businesses in 2025" zu "Best CRM software for small business" änderst, ist der Ähnlichkeitsscore 0,91. Das ist ok. Aber wenn er sich zu "CRM software" ändert, fällt die Ähnlichkeit auf 0,65. Der Subagent flaggt es als MITTEL, weil das eine 40%-Reduktion in der Keyword-Dichte ist und wahrscheinlich die CTR schadet.

Es ist nicht nur Diff. Es ist Reasoning über das, was der Diff bedeutet.

Wir haben bisher vier Probleme mit diesem erwischt. Die Robots-Noindex-Sache. Ein Fall, bei dem jemand alle OG-Images löschte (würde Social Shares getötet haben). Ein Fall, bei dem Title Tags auf 40 Zeichen anstatt 60 gekürzt wurden (sah nur schlecht aus, schadet nicht SEO, aber Client hätte es bemerkt). Und einen, bei dem Canonical URLs sich von https:// zu http:// änderten (würde Duplicate-Content-Strafen verursachen).

Jede hätte uns mindestens ein paar Stunden Aufräum- und Client-Vertrauensarbeit gekostet. Wahrscheinlich mehr.

Wir speichern seo-baseline.json im Repo und aktualisieren es als Teil des Deploy-Success-Hooks.

Subagent 2: Core Web Vitals Smoke Test

# Agent: CWV Smoke Test

## Rolle
Führe Lighthouse auf wichtigen Seiten aus und flagge CWV-Regressionen.

## Erlaubte Tools
- Bash

## Anweisungen
1. Lese .claude/skills/run-lighthouse.md
2. Führe Lighthouse CI gegen $PREVIEW_URL für diese Seiten aus:
   - / (Homepage)
   - /blog/ (Listing)
   - /blog/[neuester-Post] (Detail)
   - /services/ (falls vorhanden)
3. Schwellenwerte (fehlschlagen, wenn einer darunter):
   - LCP: 2500ms
   - FID/INP: 200ms
   - CLS: 0,1
   - Performance-Score: 85
   - Barrierefreiheits-Score: 90
4. Wenn eine Metrik um mehr als 10% vom vorherigen Run regrediert,
   flagge als WARNING, auch wenn noch über Schwelle.
5. Beziehe das spezifische Element ein, das LCP oder CLS verursacht, wo Lighthouse es meldet.

## Output-Format
{"passed": boolean, "pages": [{"url": string, "scores": {}, "flags": []}], "summary": string}

Die zugehörige Skill-Datei (run-lighthouse.md) enthält die exakte lhci CLI-Invocation:

# Skill: Lighthouse ausführen

## Befehl
```bash
npx @lhci/cli@0.14.0 collect \
  --url="$1" \
  --numberOfRuns=3 \
  --settings.preset=desktop \
  --settings.output=json \
  --settings.outputPath=/tmp/lhci-results/

Parsing

Lese den Median-Run aus /tmp/lhci-results/. Extrahiere:

  • categories.performance.score * 100
  • audits['largest-contentful-paint'].numericValue
  • audits['cumulative-layout-shift'].numericValue
  • audits['interaction-to-next-paint'].numericValue (falls vorhanden)

## Subagent 3: Barrierefreiheits-Scan

```markdown
# Agent: Barrierefreiheits-Scan

## Rolle
Führe pa11y gegen Preview-URLs aus und melde WCAG 2.1 AA Verstöße.

## Erlaubte Tools
- Bash

## Anweisungen
1. Lese .claude/skills/run-pa11y.md
2. Führe pa11y gegen denselben Seiten-Set wie den CWV-Agent aus.
3. Gruppiere Ergebnisse nach Schweregrad: error, warning, notice.
4. Für jeden Fehler, beziehe ein:
   - Das verlzte WCAG-Kriterium (z.B. 1.1.1 Non-text Content)
   - Das HTML-Element (Selector)
   - Eine Ein-Satz-Fix-Suggestion
5. Fehlschlag, wenn Fehler existieren. Warnung, wenn Warnungen > 10.

## Output-Format
{"passed": boolean, "error_count": number, "warning_count": number, "errors": [{"criterion": string, "selector": string, "fix": string}], "summary": string}

Wir verwenden pa11y@8.0.0 mit dem Flag --runner=axe. Der Standard-htmlcs Runner vermisst einige Kontrastprobleme, die axe erwischt.

# Agent: Broken-Link-Scan

## Rolle
Crawle die Preview-Website und melde kaputte interne und externe Links.

## Erlaubte Tools
- Bash

## Anweisungen
1. Lese .claude/skills/run-linkinator.md
2. Führe aus: npx linkinator@6.1.2 $PREVIEW_URL --recurse --timeout 15000 --format json > /tmp/link-results.json
3. Filtere Ergebnisse auf Status >= 400 oder Status === 0 (Timeout).
4. Trenne interne (gleiche Domain) von externen kaputten Links.
5. Interne kaputte Links sind KRITISCH. Externe kaputte Links sind WARNING.
6. Excluiere bekannt-launische externe Domains: twitter.com, linkedin.com (sie blockieren Crawler).

## Output-Format
{"passed": boolean, "internal_broken": [{"source": string, "target": string, "status": number}], "external_broken": [...], "summary": string}

Subagent 5: Schema-Validierung

# Agent: Schema-Validierung

## Rolle
Validiere JSON-LD strukturierte Daten auf allen Seiten.

## Erlaubte Tools
- Bash
- Datei lesen

## Anweisungen
1. Lese .claude/skills/parse-schema-org.md
2. Für jede Seite in der Sitemap:
   a. Extrahiere alle <script type="application/ld+json"> Blöcke
   b. Parse als JSON (fehlschlag, wenn malformed)
   c. Validiere erforderliche Felder pro @type:
      - Article: headline, datePublished, dateModified, author, image
      - LocalBusiness: name, address, telephone
      - WebPage: name, description
      - BreadcrumbList: itemListElement mit position, name, item
   d. Überprüfe, dass alle @id Verweise sich innerhalb des Seiten-Graphen lösen
   e. Validiere URLs in Schema sind absolut, nicht relativ
3. Flagge fehlende erforderliche Felder als HOCH.
4. Flagge malformed JSON als KRITISCH.

## Output-Format
{"passed": boolean, "pages": [{"url": string, "schemas": [{"type": string, "valid": boolean, "issues": []}]}], "summary": string}

Subagent 6: Deploy Gate Orchestrator

Dieser übergeordnete Agent spawnt die anderen fünf und macht die Go/No-Go-Entscheidung.

# Agent: Deploy Gate

## Rolle
Orchestriere alle Pre-Deploy-Checks und erzeuge eine endgültige Deploy-Entscheidung.

## Erlaubte Tools
- Bash
- Datei lesen
- Datei schreiben
- dispatch_agent

## Anweisungen
1. Spawne diese Agents parallel:
   - .claude/agents/seo-regression.md
   - .claude/agents/cwv-smoke.md
   - .claude/agents/accessibility.md
   - .claude/agents/broken-links.md
   - .claude/agents/schema-validation.md
2. Sammle alle Outputs.
3. Lese .claude/skills/format-deploy-report.md
4. Entscheidungslogik:
   - Wenn IRGENDEIN Agent ein KRITISCH-Flag hat: BLOCK deploy.
   - Wenn 2+ Agents HOCH-Flags haben: BLOCK deploy.
   - Wenn 1 Agent ein HOCH-Flag hat: WARN, benötige manuellen Override.
   - Ansonsten: APPROVE.
5. Schreibe den vollständigen Report in /tmp/deploy-report.md
6. Gebe die Entscheidung aus.

## Output-Format
{"decision": "APPROVE" | "WARN" | "BLOCK", "reports": {agent_name: agent_output}, "summary": string}

Hook-Konfiguration: settings.json

Hier ist unsere aktuelle settings.json (mit Client-spezifischen URLs entfernt):

{
  "hooks": {
    "pre-commit": [
      {
        "agent": ".claude/agents/schema-validation.md",
        "condition": "files_changed_match('**/*.json', '**/structured-data/**')",
        "env": {
          "PREVIEW_URL": "http://localhost:3000"
        }
      }
    ],
    "pre-push": [
      {
        "agent": ".claude/agents/deploy-gate.md",
        "env": {
          "PREVIEW_URL": "$VERCEL_PREVIEW_URL"
        },
        "timeout": 300,
        "on_failure": "block"
      }
    ],
    "post-deploy-success": [
      {
        "command": "node scripts/extract-seo-meta.js --url=$PRODUCTION_URL --output=.claude/snapshots/seo-baseline.json",
        "description": "Aktualisiere SEO-Baseline nach erfolgreichem Deploy"
      }
    ]
  },
  "agent_defaults": {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 8192,
    "timeout": 120
  },
  "skills_directory": ".claude/skills/"
}

Notizen zu dieser Konfiguration:

  • Wir verwenden claude-sonnet-4-20250514 für Subagents, nicht Opus. Die Reasoning-Aufgaben hier rechtfertigen den Kostenunterschied nicht. Sonnet handle "vergleiche zwei JSON-Objekte und flagge Unterschiede" fine.
  • Das timeout: 300 auf dem Deploy Gate gibt allen fünf Subagents Zeit zu laufen. Individuelle Agents haben 120s Standards. Der Orchestrator bekommt 5 Minuten, weil er auf alle wartet.
  • Die condition auf dem Pre-Commit-Hook bedeutet, dass Schema-Validierung nur läuft, wenn du Schema-verwandte Dateien berührst. Kein Grund, auf einer CSS-Änderung zu laufen.
  • post-deploy-success aktualisiert die Baseline. Ohne dies, vergleicht dein SEO-Regressions-Check gegen veraltete Daten.

Skill-Definitionen, die alles zusammenbinden

Die Skill-Datei, die die meiste Arbeit macht, ist compare-seo-snapshot.md:

# Skill: SEO-Snapshots vergleichen

## Zweck
Vergleiche zwei SEO-Metadaten-Snapshots und identifiziere Regressionen.

## Eingabe
- Aktueller Snapshot: /tmp/seo-current.json
- Baseline-Snapshot: .claude/snapshots/seo-baseline.json

## Vergleichsregeln

### Title Tags
- Wenn sich ein Title geändert hat UND der organische Traffic der Seite (aus Baseline-Metadaten) > 1000 Sessions/Monat, flagge als HOCH.
- Wenn ein Title jetzt leer ist oder den Title einer anderen Seite matching, flagge als KRITISCH.
- Wenn ein Title auf einer Low-Traffic-Seite geändert, flagge als MITTEL.

### Canonical URLs
- Jede Änderung zu Canonical URL ist HOCH.
- Ein Canonical, der auf eine andere Domain zeigt, ist KRITISCH.
- Ein fehlender Canonical (war vorhanden, jetzt weg) ist HOCH.

### Robots Meta
- Jede Seite, die "noindex" gewonnen hat, ist KRITISCH.
- Jede Seite, die "nofollow" auf internen Links gewonnen hat, ist HOCH.

### Neue Seiten
- Seiten in aktuell aber nicht in Baseline sind INFO (erwartet für neuen Content).
- Aber verifiziere, dass sie haben: title, meta description, canonical, mindestens ein h1.

### Entfernte Seiten
- Seiten in Baseline aber nicht in aktuell sind HOCH.
- Dies könnte auf versehentliche Route-Entfernung hinweisen.

Diese Skill-Datei kodiert Monate von SEO-Incident-Reaktion in ein Format, das Claude zuverlässig folgen kann. Ohne ihn würde der Subagent angemessene, aber inkonsistente Urteile über das, was eine Regression darstellt, machen.

Vier Incidents, die das System erwischt hat

Incident 1: Versehentliches noindex auf 47 Blog-Posts

Client: B2B SaaS Unternehmen, 200 Seiten, 60k organische Sessions/Monat.

Ein Developer aktualisierte die <Head> Komponente in der Blog-Template, um ein neues Meta-Tag hinzuzufügen. Sie kopierten aus der Staging-Konfiguration, die <meta name="robots" content="noindex, nofollow"> hardcodiert hatte. Die Änderung bestand Code-Review, weil der Reviewer sich auf das neue Tag konzentrierte, nicht auf die bestehenden.

Der SEO-Regressions-Subagent flaggte 47 Seiten als KRITISCH -- Robots Meta geändert zu noindex. Der Deploy wurde blockiert.

Zeit zur Erkennung: 2 Minuten 14 Sekunden nach Push. Ohne das System, würde es erwischt werden, wenn Search Console einen Coverage-Drop 3-7 Tage später zeigt.

Vermiedene geschätzte Auswirkung: Diese 47 Posts trieben etwa 14.000 $/Monat in Pipeline. Sogar ein einwöchiger Deindex-Event könnte 3.500 $ gekostet haben.

Incident 2: CLS-Regression von einem neuen Hero-Image

Client: E-Commerce-Marke, Next.js 14 Storefront auf Shopify Hydrogen.

Das Design-Team tauschte den Homepage-Hero gegen ein neues Image mit einem anderen Aspekt-Verhältnis, aber aktualisierte nicht die Width/Height-Attribute auf der <Image> Komponente. Das Image laden fine, aber verursachte CLS von 0,34 -- weit über der 0,1 Schwelle.

Der CWV Smoke-Test Subagent meldete CLS-Regression auf der Homepage. Die Zusammenfassung rief spezifisch auf: "CLS verursacht durch Element img.hero-banner verschoben 0,34 kumulativ. Die Image-Dimensionen (1920x800) matchen nicht das Container Aspekt-Verhältnis (16:9 = 1920x1080). Füge explizite width={1920} height={800} hinzu oder aktualisiere das Container Aspekt-Verhältnis."

Zeit zur Erkennung: 1 Minute 47 Sekunden.

Client: Professional Services Unternehmen, 80 Seiten.

Wir strukturierten ihre Service-Seiten von /services/[name] zu /[category]/[name] um. Redirects waren vorhanden, aber drei Blog-Posts hatten hardcodierte Links zu den alten URLs, und die CMS-gesteuerte Navigation hatte einen Cache-Eintrag, der auf eine gelöschte Seite zeigte.

Der Broken Link Scan fand 4 interne 404s. Der Subagent's Zusammenfassung bemerkte, dass 3 der 4 in Blog-Post-Body-Content waren (nicht Navigation), was bedeutete, dass sie vom Redirect-Audit vermisst wurden.

Zeit zur Erkennung: 3 Minuten 8 Sekunden. Der Linkinator-Crawl ist der langsamste Teil.

Incident 4: Fehlender dateModified in Article Schema

Client: Media-Unternehmen, 2.000 Artikel.

Eine CMS-Migration von WordPress zu Sanity verlor die dateModified Feld-Mapping. Der Schema-Generierungs-Code fiel auf null für dateModified zurück, was ungültiges JSON-LD produkte.

Der Schema-Validierungs-Subagent flaggte jede Artikel-Seite als HOCH -- fehlender erforderlicher dateModified Feld. Die Zusammenfassung erklärte: "Google benötigt dateModified für Article strukturierte Daten, um für Top Stories und Rich Results berechtigt zu sein. Alle 2.147 Artikel-Seiten sind betroffen."

Zeit zur Erkennung: 4 Minuten 22 Sekunden (große Sitemap).

ROI: Minuten gespart pro Ship und Dollar pro Monat

Hier ist unsere Mathematik:

Metrik Vorher (CI + manuell) Nachher (Subagents) Delta
Checks pro Deploy 4 Tools, manuelle Überprüfung 5 Agents, automatisiert +1 Check, -100% manuelle Überprüfung
Zeit zum Ausführen aller Checks 8-12 min (sequentiell CI) 3-5 min (parallele Subagents) -60%
Zeit zum Verstehen von Fehlschlägen 20-40 min pro Fehler 1-2 min (kontextuelle Zusammenfassung) -90%
Deploys pro Woche (alle Clients) 18 18 Gleich
False-Positive-Rate ~15% (verrauschtes Lighthouse) ~4% (Reasoning filtert Rauschen) -73%

Minuten gespart pro Ship: Im Durchschnitt 25 Minuten, wenn ein Check fehlschlägt (30% der Deploys). Das sind 25 × 5,4 fehlschlagende Deploys/Woche = 135 Minuten/Woche = 9 Stunden/Monat.

Kosten des Systems:

  • Claude API-Kosten für Subagents: ~$0,12 pro vollständigem Deploy-Gate-Run (5 Agents, Sonnet, durchschnittlich 6.000 Tokens pro Agent)
  • 18 Deploys/Woche × 4,3 Wochen × $0,12 = $9,29/Monat in API-Kosten
  • Puppeteer/Lighthouse-Infrastruktur: läuft auf bestehenden Vercel-Build-Instanzen, keine zusätzliche Kosten
  • Wartungszeit: ~2 Stunden/Monat zum Aktualisieren von Skill-Dateien und Schwellenwerten

Dollar-Wert der Ingenieur-Zeit gespart: 9 Stunden/Monat × $85/Stunde (Mischsatz für unser Team) = $765/Monat gespart.

Dollar-Wert von Incidents verhindert: Basierend auf den vier oben genannten Incidents könnte allein der Noindex-Incident $3.500 gekostet haben. Wenn wir einen ähnlichen Incident pro Quartal verhindern, das sind $1.166/Monat in vermiedener Client-Auswirkung.

Netto ROI: $1.920/Monat an Wert für $9,29/Monat in API-Kosten. Das ist eine 206x Rückkehr. Sogar wenn du die API-Kosten für ein größeres Team 10x erhöhst, ist es immer noch günstig.

Lücken und was wir ändern würden

Dieses System ist nicht perfekt. Hier ist, was noch rau ist:

Keine visuelle Regressions-Tests. Subagents können Lighthouse und pa11y laufen lassen, aber können keine Screenshots ansehen und sagen "der Hero-Bereich ist kaputt." Wir beobachten Claudes Vision-Fähigkeiten dafür.

Baseline-Drift. Die SEO-Baseline aktualisiert sich auf erfolgreichem Deploy, aber wenn du eine Regression shippst, die das System nicht erwischt, wird sie zur neuen Baseline. Wir überprüfen manuell Baselines monatlich.

Externe Link-Flakiness. Twitter/X, LinkedIn und einige Regierungs-Sites blockieren Crawler oder Rate-Limit aggressiv. Wir unterhalten eine Exclusion-Liste, aber sie benötigt manuelle Updates.

Cold-Start-Zeit. Der erste Run nach dem Clonen eines Repos dauert länger, weil npx Pakete abrufen muss. Wir erwägen, die CLI-Tools in einem Docker-Layer vorzuinstallieren.

Anthropic Rate Limits. Das Spawnen von 5 Subagents gleichzeitig kann gelegentlich Rate Limits auf der Claude API während Spitzenlastzeiten treffen. Wir fügen eine 2-Sekunden-Staffelung zwischen Spawns hinzu, was funktioniert, aber ist inelegant.

Unsere längeren Agent-Definitionen (Schema-Validierung ist 400 Wörter) erzeugen manchmal weniger strukturierte Outputs als die kürzeren. Wir erwägen, den Schema-Validierungs-Agent in Per-Type Sub-Sub-Agents zu teilen.

FAQ

Funktionieren Claude Code Subagents mit irgendeinem LLM, oder nur Claude?

Subagents sind eine Claude Code Funktion, die an Anthropic's API gebunden ist. Du benötigst einen Claude API-Schlüssel mit Zugang zu Claude Code. Das Agent-Definitions-Format ist spezifisch zu Claude Code's .claude/ Verzeichnis-Konvention, nicht ein allgemeiner Standard.

Wie viel kostet es, fünf Subagents pro Deploy mit API-Gebühren auszuführen?

Bei unserem Maßstab, grob $0,12 pro vollständigem Deploy-Gate-Run mit Claude Sonnet. Das ist etwa 9-10 $/Monat für 18 Deploys pro Woche. Opus würde etwa 5x mehr kosten, aber wir haben gefunden, dass es für diese Aufgaben nicht notwendig ist.

Können Subagents in CI/CD-Pipelines wie GitHub Actions laufen?

Ja. Du kannst Claude Code headless in einer CI-Umgebung aufrufen. Wir triggern unsere bei Vercel Preview Deploy-Abschluss über einen Webhook, der claude-code run .claude/agents/deploy-gate.md mit der Preview URL als Umgebungsvariable aufruft.

Was ist der Unterschied zwischen einem Claude Code Skill und einem Subagent?

Ein Skill ist eine Markdown-Anweisungsdatei, die Claude beibringt, wie man etwas macht -- wie ein Rezept. Ein Subagent ist eine isolierte Claude-Instanz, die mit ihrem eigenen Kontext und Tools gespawnt werden kann. Subagents nutzen Skills. Denke an Skills als Dokumentation und Agents als Worker.

Benötigst du Anthropic's Routines-Feature oder sind rohe Subagents genug?

Für unsere Deploy-Gate-Workflow, rohe Subagents plus Hooks in settings.json sind ausreichend. Routines addiere eine höhere Orchestrierungs-Ebene, die für komplexere Multi-Step-Workflows nützlich ist. Wir könnten Routines übernehmen, wenn unsere Deploy-Checks über sechs Agents hinauswachsen.

Wie gehst du mit Subagent-Fehlschlägen oder Timeouts um?

Jeder Subagent hat ein 120-Sekunden-Timeout. Wenn ein Subagent fehlschlägt oder das Timeout überschreitet, behandelt der Deploy-Gate-Orchestrator es als WARN, nicht BLOCK. Wir würden lieber mit einem unvollständigen Check shippern, als Deploys zu blockieren, weil Lighthouse abhing. Die Zusammenfassung notiert, welche Checks nicht abgeschlossen wurden.

Kann dieser Ansatz dedizierte Tools wie Lighthouse CI oder pa11y ersetzen?

Nein -- er wrappet sie. Die Subagents rufen diese Tools über Bash auf und reasonen dann über den Output. Du brauchst immer noch die zugrunde liegenden Tools installiert. Der Wert liegt in der Orchestrierungs-, Korrelations- und Natural-Language-Reporting-Schicht, nicht im Ersetzen der Scanner selbst.