Skill
Keyword Cluster & Negative-Keyword-Skill
--- name: keyword-cluster-negative-analyzer description: Erstellt Keyword-Cluster/Audience-Signal-Begriffe für neue Golf-Kampagnentypen und -Templates, und analysiert laufende Goog
SKILL.md
---
name: keyword-cluster-negative-analyzer
description: Erstellt Keyword-Cluster/Audience-Signal-Begriffe für neue Golf-Kampagnentypen und -Templates, und analysiert laufende Google-Ads-Suchbegriffe auf Streuverluste (negative Keywords). Nutze diesen Skill wenn ein neues Kampagnentyp-Template (Search oder PMax) mit Keywords befüllt werden muss, oder wenn ein Suchbegriffe-Bericht eines laufenden Golfclub-Kontos auf Verschwendung geprüft werden soll.
---
# Keyword Cluster & Negative-Keyword-Skill
Zwei getrennte Skill-Definitionen unter einem fachlichen Dach.
## Skill-Definitionen
| Feld | `keyword_cluster_builder` | `search_term_waste_analyzer` |
|---|---|---|
| **key** | `keyword_cluster_builder` | `search_term_waste_analyzer` |
| **Plattform** | google_ads (search + performance_max) | google_ads (search) |
| **Kategorie** | `planner` | `analysis` |
| **Eingabe** | Kampagnentyp, Angebot, Zielgruppe, Ort/Region, Ad-Format (search/performance_max) | `client_id`, Zeitraum, optional bereits bekannte Negative-Listen |
| **Erlaubte Provider-Tools** | keine (reine Textgenerierung, kein Provider-Call) | keine — liest den 30-Tage-Bestand aus `analytics.daily_search_term_metric` |
| **LLM-Einsatz** | Ja — Cluster-Vorschläge und Themen-Gruppierung | Ja nur für Kategorisierung/Begründungstext; Waste-Erkennung selbst ist regelbasiert |
| **Berechtigung** | `manage_campaign_types` oder `draft` | `view` für den betroffenen Client |
| **Bestätigungspflicht** | Ja — Ergebnis ist ein Vorschlag für eine Template-Version, kein Autosave als `active` | Ja — Ergebnis mündet in einen `change_request` (keyword/create), keine direkte Mutation |
| **Ausgabeschema** | `keyword_clusters[]` (Search) bzw. `audience_signal_terms[]` (PMax) + `negative_keywords[]`, je mit Begründung | `recommendations[]` (Term, Match Type, Level, Confidence, Kategorie, Begründung) |
---
## Teil A: `keyword_cluster_builder` — Neue Templates befüllen
### Wann einsetzen
Beim Anlegen oder Überarbeiten eines Kampagnentyp-Templates — z. B. neues Template "Platzreife – Search" oder "Schnupper – Performance Max".
Für Search-Templates werden lokale Suchbegriffe ausschließlich über `{{city}}` modelliert. Der Skill darf im Template-Modus keine echte Stadt oder Clubbezeichnung erfinden; die Auflösung erfolgt erst im konkreten Kampagnenplaner.
### Pflicht-Input
- Kampagnentyp-Schlüssel (z. B. `platzreife_kampagne`)
- Angebot in einem Satz (was wird konkret verkauft/beworben)
- Ad-Format: `search` oder `performance_max` — **die Begriffslogik unterscheidet sich fundamental:**
- **Search:** Keywords sind hartes Targeting (Match Type entscheidet, worauf geboten wird)
- **PMax:** Begriffe sind nur **Signal** für die Google-KI (`audience_signal_terms`), kein Targeting — eigenes Feld, nicht mit `keyword_clusters` vermischen, damit niemand die beiden verwechselt
- Region/Zielort des Golfclubs (für lokale Modifikatoren)
### Methodik
1. **Grundcluster nach Funnel-Stufe** bilden: transaktional (z. B. "platzreife kurs buchen"), kommerziell-prüfend ("platzreife kurs kosten"), informational ("was ist platzreife golf") — bei kleinem Budget (~400 €/Monat je Club) überwiegend auf **transaktional + kommerziell-prüfend** fokussieren, informational nur sparsam.
2. **Lokale Modifikatoren immer mit aufnehmen** (Ort, "in der Nähe", Postleitzahlregion) — bei kleinem Budget ist lokale Präzision wichtiger als Reichweite.
3. **Negative-Keywords von Anfang an mitliefern**, nicht erst nachträglich: universelle Ausschlüsse (Jobs, DIY/"wie lerne ich golf selbst", Gebrauchtgeräte-Suchen wie "golfschläger gebraucht" — Golf hat ein eigenes Ausrüstungs-Suchvolumen, das nichts mit Kursbuchung zu tun hat) plus Cross-Kampagnentyp-Schutz (z. B. "Platzreife"-Template negativiert "Greenfee"/"Mitglied werden", damit eigene Kampagnentypen sich nicht gegenseitig die Auktion streitig machen — Prinzip: **ein Suchbegriff, ein kanonischer Besitzer**, entschieden nach 1. Intent-Fit, 2. Landingpage-Passung, 3. Präzision, 4. Performance nur als Tiebreaker).
4. Bei **PMax**: zusätzlich zu den Signalbegriffen eine kurze Notiz, welche **Suchthemen NICHT** als Signal genutzt werden sollen (z. B. Markenbegriffe anderer Golfclubs — Wettbewerbsnamen niemals als Signal, nur ggf. als bewusste, einzeln freigegebene Ausnahme).
### Persistenz
- Ergebnis wird **nicht** automatisch in die aktive Template-Version geschrieben. Es entsteht ein **Entwurf**, den ein Mensch prüft und erst dann als neue Version speichert (`status: draft` → `active`).
- Gespeicherte Felder (jsonb):
- Search: `{"keyword_clusters": [{"theme": "...", "terms": [...], "match_type": "phrase|exact"}], "negative_keywords": [...]}`
- PMax: `{"audience_signal_terms": [...], "excluded_signal_notes": "..."}`
- Der Skill-Lauf wird protokolliert (Input, Modellversion, Zeitpunkt, Bezug zur Template-Version), damit später nachvollziehbar ist, welches Cluster woher kam.
---
## Teil B: `search_term_waste_analyzer` — laufende Konten prüfen
### Wann einsetzen
Regelmäßig (alle 2-4 Wochen je aktivem Golfclub-Konto) oder ad hoc, wenn der Daily-Check-Skill ungewöhnlich hohe Kosten ohne Conversions meldet.
### Pflicht-Input
- Lokal synchronisierter Suchbegriffe-Bericht des betreffenden Kontos, mindestens 30 Tage — kein zusätzlicher Provider-Call
- Primäre Servicebegriffe des Kampagnentyps + Markenname des Clubs (werden nie negativiert)
Der Daily Check 1.2 nutzt diesen Bestand bereits für eine konservative Vorauswahl: mindestens 50 Klicks und 20 € ohne Conversion werden als Waste-Prüfung markiert; nicht hinzugefügte Suchanfragen mit mindestens drei Conversions als Chance. Die semantische Einordnung in Alignment-/Audience-/Performance-Waste sowie die menschliche Auswahl für einen Change Request bleiben Aufgabe dieses vertieften Skills.
### Drei Waste-Typen
1. **Alignment-Waste**: Absicht kann durch das Angebot nie erfüllt werden (z. B. "golf lernen kostenlos" bei einem kostenpflichtigen Platzreifekurs, "golftrainer jobs")
2. **Audience-Waste**: richtiger Service, falsche Zielgruppe (z. B. Profi-Turnier-Suchen bei einem Einsteigerangebot)
3. **Performance-Waste**: konvertiert grundsätzlich, aber Kosten stehen in keinem Verhältnis (nur bei ≥50 Klicks pro Begriff bewerten, sonst zu wenig Daten für eine belastbare Aussage)
**Geschützt, niemals automatisch negativieren:** Markenname des Clubs + Varianten, Vergleichs-/Kaufabsichts-Suchen ("bester golfkurs in der nähe", "platzreife vs schnupperkurs"), primäre Servicebegriffe inkl. Tippfehlervarianten.
### Ausgabeformat
Tabelle: Begriff | Klicks | Kosten | Kategorie | empfohlener Match Type | Ebene (Konto/Kampagne/Anzeigengruppe) | Konfidenz | Begründung.
### Persistenz
- Empfehlungen werden **nicht** automatisch als Google-Ads-Negative gesetzt. Ein Mensch wählt Zeilen aus → daraus entsteht pro ausgewähltem Begriff (oder gebündelt) ein `change_request` mit `entity_type: keyword`, `action: create` (negativ), der über den Freigabe-Workflow läuft und erst nach Freigabe ausgeführt wird.
- Kein Skill-Lauf schreibt direkt in Google Ads — die Trennung "Analyse liefert Vorschlag, Freigabe löst Ausführung aus" bleibt durchgängig erhalten.
## Guardrails
- Niemals Markenbegriffe oder geschützte Muster (siehe oben) automatisch als "empfohlen negativieren" ausgeben — nur als "geprüft, unauffällig" führen.
- Bei PMax: niemals `audience_signal_terms` mit hartem Such-Targeting-Vokabular (Match-Type-Angaben) vermischen — das Feld existiert bewusst getrennt von `keyword_clusters`.
- Unter 50 Klicks: nur Muster-basierte Einschätzung, keine performance-basierte Entscheidung.
## Technische Ausführungsroute
### `keyword_cluster_builder`
1. Im Search-Template-Editor startet der Button **„Mit KI überarbeiten“** einen serverseitigen Skill-Lauf mit der aktuellen, noch nicht gespeicherten Editor-Fassung, Kampagnentyp, Format und lokalen Eingaben.
2. Der Lauf liest keine Live-Daten und schreibt nichts direkt. Er liefert einen validierten Vorschlag für `keyword_clusters` und `negative_keywords` bzw. bei PMax für `audience_signal_terms` zurück an den Browser.
3. Der Nutzer übernimmt einzelne oder alle Vorschläge in den Editor. Erst der vorhandene Button **„Vorlage speichern“** erzeugt die neue Template-Version. In diesem Kontext entsteht ausdrücklich kein `change_request`, weil noch keine konkrete Kampagne verändert wird.
4. Der Lauf wird als `skill_run` mit Template-/Version-Referenz, Input, Modell, Output und Kosten protokolliert.
### `search_term_waste_analyzer`
1. Der Skill startet aus einer konkreten Kampagnenakte oder Daily-Check-Empfehlung und lädt nur lokal gespeicherte Suchbegriff-Snapshots des gewählten Zeitraums. Search-Term-Status und Match Type kommen aus demselben Snapshot; Search-Impression-Share wird nicht erfunden, weil Google diesen Wert auf `search_term_view` nicht liefert.
2. Er erstellt Vorschläge, speichert aber keine Negative. Erst die explizit ausgewählten Zeilen erzeugen gebündelte `change_request`-Zeilen für negative Keywords.
3. Nach bestätigter Ausführung folgt ein lokaler Inventur-Refresh; der Skill selbst ruft keine schreibenden Provider-Tools auf.
