CommunityCodierung & Entwicklunggithub.com

keinsaasforever/gtm-pipeline-skills

B2B-Vertriebs-Skill für Claude (Demo-Version)

Was ist gtm-pipeline-skills?

Dieser Skill ermöglicht es einem AI-Agenten (wie Claude), einen vollständigen B2B-Go-to-Market-Demo-Workflow auszuführen. Ausgelöst durch ein Webhook-Formular generiert er eine maßgeschneiderte Liste von ~10 angereicherten Kontakten inklusive personalisierter Nachrichtenbeispiele. Der Prozess umfasst die ICP-Definition (Ideal Customer Profile), die Personensuche über verschiedene Datenquellen wie FullEnrich und BetterContact, die Kontaktfilterung und -anreicherung (nur E-Mail) sowie die optionale Kaufsignal-Suche. Abschließend werden 2–4 Nachrichten nach dem Hook-Bridge-Offer-CTA-Schema erstellt. Der Skill ist sowohl für interaktive (mit Rückfragen) als auch für headless/automatisierte (ohne Rückfragen) Nutzung ausgelegt und enthält Kostenkontrollen vor kostenpflichtigen API-Aufrufen.

Funktioniert mit✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add keinsaasforever/gtm-pipeline-skills

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Demo

Generiere eine Demo-Liste mit ~10 angereicherten Kontakten und personalisierten Nachrichtenbeispielen, ausgelöst durch einen Webhook-Prompt.

Lies ~/.claude/skills/gtm-pipeline/_shared/conventions.md vor der Ausführung.


Wann verwenden

  • Webhook-Trigger: Ein Benutzer sendet ein kostenloses Demo-Formular, in dem er seine Zielgruppe beschreibt.
  • Ziel: Nachweisen, dass der AI-Agent authentische, nicht generische Outreach mit echten Leads schreibt.
  • Umfang: ~10 Kontakte, mit LinkedIn + E-Mail angereichert, 2–4 Nachrichtenbeispiele.

Demo-Einschränkungen

  • Keine Telefonanreicherung – nur E-Mail.
  • ~10 Kontakte (10–15 anfordern, Ausfälle durch Anreicherung einplanen).
  • Nachrichtengenerierung ist optional, aber empfohlen.
  • Signalsuche ist opt-in – standardmäßig deaktiviert. Aktivieren über --with-signals-Flag oder explizite Benutzeranfrage. Siehe Schritt 5.5.
  • Kostenkontrolle: Vor dem ersten kostenpflichtigen Provider-Aufruf die erwarteten Kosten nennen (Finder-Suchen pro People-Source-Cadence meist kostenlos; ~10–15 E-Mail-Anreicherungscredits; Signale <0,50 $, falls aktiviert). Interaktiv: Beim Benutzer bestätigen lassen. Headless: Schätzung in run_log.md protokollieren und fortfahren, niemals blockieren.

Schritt 1 – Prompt parsen und ICP erstellen

Der Webhook-Prompt beschreibt die Zielgruppe des Benutzers. Extrahiere:

Zwingend erforderlich:

  • Was verkaufst du / bietest du an?
  • Wer ist dein idealer Kunde? (Branche, Rolle, Unternehmensgröße, Standort)
  • Was ist dein Wertversprechen?
  • Welcher Ton? (formell vs. locker, ggf. Beispiele)
  • Dient dies der Rekrutierung ODER dem Verkauf an Kunden?

Falls nicht im Prompt enthalten, ableiten (nicht anhalten):

  • Ziel-Jobtitel, Standort, Unternehmensgröße/-typ

Den Anforderer identifizieren, bevor die Zielgruppe interpretiert wird (behebt die wiederkehrende Lücke „Was verkaufen sie überhaupt / warum wollen sie diese Zielgruppe?“):

  1. Domain des Anforderers ermitteln aus der E-Mail (z. B. [email protected] → acme.de), diese scrapen/anreichern und feststellen, was sie verkaufen. Bei Unternehmen mit mehreren Produkten: bestätigen, für welche Produktlinie die Demo gedacht ist – das im Prompt genannte Produkt kann vom tatsächlichen abweichen.
  2. Beziehung zur Zielgruppe bestimmen – ein Zielbegriff (z. B. „Callcenter“) ist normalerweise ein Segment, an das verkauft wird, nicht das, was sie selbst sind. Klassifiziere: verkaufen-an / kaufen-von / akquirieren / partner / rekrutieren. Persona-Keywords leiten sich daraus ab, nicht aus einer Vermutung.

Interaktiv vs. bereitgestellt (headless):

  • Interaktiv: Wenn ein Muss-Feld nach Auto-Auflösung wirklich mehrdeutig ist, eine präzise Klärungsfrage stellen. Ansonsten fortfahren.
  • Bereitgestellt / Headless (aufgerufen über claude -p vom Webhook – siehe Bereitstellung): niemals bei Fragen blockieren. Jedes Feld aus dem Prompt + Recherche zur Domain des Anforderers ableiten, Annahmen in context/icp.md unter einer Überschrift „Annahmen“ festhalten und durchgängig fortfahren.

Erst mit der Suche beginnen, wenn das ICP ausreichend klar für einen sinnvollen Filter ist.

Speichere ICP in: {client-slug}-gtm/context/icp.md (inkl. Angebot, Beziehungsklassifikation und etwaiger Headless-Annahmen).


Schritt 2 – Arbeitsverzeichnis erstellen

Erstelle die Verzeichnisstruktur {client-slug}-gtm/ wie in conventions.md definiert. Schreibe die ICP-Definition in context/icp.md.


Schritt 3 – Personensuche (10 Kontakte)

Verwende den **Personensuche-**Skill, um ~10–15 Kontakte zu finden.

Provider-Auswahl für Demo: Befolge die Finder-Reihenfolge in conventions.md → People-Source-Cadence – FullEnrich Finder → BetterContact → Pipe0 → Amplemarket/Crustdata (letzter Ausweg), max. 2 Versuche/Quelle, FE-first für KMU/inhabergeführte/nicht-englische Segmente. FE und BC liefern direkt LinkedIn-URLs (erforderlich für E-Mail-Anreicherung). Falls keine Unternehmensliste (persona-basierter Prompt), Parallel FindAll oder BC Search verwenden. Bei verzeichnis-/scrape-basierten Unternehmenslisten nach Unternehmensname + Standort suchen, niemals nach exakter Domain (Konvention #11).

Wichtige zu sammelnde Felder:

full_name, first_name, last_name,
job_title, company_name, company_domain,
linkedin_profile_url, location

Befolge das Personensuche-Ausführungsprotokoll: Sandbox → Test → Review → Ausführen.


Schritt 4 – Kontaktfilter (ICP-Ranking)

Führe contact-filter auf den 10–15 gefundenen Kontakten aus. Selbst kleine Batches profitieren vom ICP-Ranking – es stellt sicher, dass sich der Anreicherungsschritt auf die am besten passenden Kontakte konzentriert.

  • Wendet Job-Tier, Branchen-Tier, Standort-Tier und Unternehmensgrößen-Klassifikation an
  • Lehnt harte Nicht-ICP-Kontakte ab
  • Ordnet bestandene Kontakte nach Priorität
  • Ausgabe: csv/intermediate/contacts_filtered.csv

Für Demos: Lockere Härteablehnungsschwelle verwenden (Tiers 1–5 durchlassen), Filterung gegenüber Ranking priorisieren.


Schritt 5 – Personen-Anreicherung (nur E-Mail)

Führe people-enrichment auf den gefilterten Kontakten aus. Demo-Modus: nur E-Mail, kein Telefon.

Empfohlener Ablauf:

  1. FullEnrich v2 (E-Mail) – alle Kontakte
  2. Pipe0-Wasserfall – nur für FE-Fehlschläge

Zusätzliche Anreicherung für Nachrichtenpersonalisierung (falls verfügbar):

  • LinkedIn-Headline und Zusammenfassung (via LinkedIn-Scrape über PhantomBuster)
  • Aktuelle LinkedIn-Beiträge (2–3 pro Kontakt) – verbessert die Nachrichtenqualität erheblich

Mindestfelder für die Nachrichtengenerierung:

name, job_title, company_name, linkedin_profile_url,
headline (optional), summary (optional), recent_posts (optional)

Geringe Ausbeute: Wenn weniger als ~8 Kontakte Filterung + Anreicherung überleben, einen zusätzlichen Finder-Durchlauf (nächste Quelle in der People-Source-Cadence) ausführen, bevor mit Nachrichten fortgefahren wird.


Schritt 5.5 – Signalsuche (Optional)

Standard: AUS. Aktivieren, wenn:

  • Der Benutzer explizit nach signalverankerten Nachrichten fragt
  • Der Webhook-Prompt Kaufauslöser erwähnt (Finanzierung, Einstellungen, Transformation, aktuelle Nachrichten)
  • Das Angebot des Kunden auf Timing-Signalen basiert (z. B. „Wir helfen Post-Series-A-Unternehmen beim Skalieren“)
  • Ein --with-signals-Flag an den Demo-Aufruf übergeben wird

Kostenhinweis: Fügt ~0,01–0,05 $ pro eindeutigem Unternehmen hinzu (Websuche + Bewertung). Bei einer 10-Kontakt-Demo sind das typischerweise 5–10 Unternehmen, also <0,50 $.

Erforderliche Eingaben für die Signalsuche

Die Signalsuche benötigt drei Kontextdateien:

  • context/icp.md – bereits in Schritt 1 gesammelt
  • context/offering.md – der Wertversprechens-Block aus Schritt 1 (jetzt schreiben, falls noch nicht gespeichert)
  • context/signal_criteria.md – Aufzählung relevanter Signaltypen für das Angebot

Falls signal_criteria.md nicht existiert, den Benutzer fragen: „Was würde ein Unternehmen gerade tun, das darauf hindeutet, dass es braucht, was Sie anbieten?“ – 5–10 Punkte sammeln und speichern.

Ausführung

# Unternehmensliste aus den eindeutigen Unternehmen der angereicherten Kontakte erstellen
python3 -c "
import csv, sys
seen = set()
with open('csv/output/contacts_enriched.csv') as f, open('csv/input/companies_raw.csv', 'w', newline='') as out:
    reader = csv.DictReader(f)
    writer = csv.DictWriter(out, fieldnames=['company_name', 'company_domain', 'company_website'])
    writer.writeheader()
    for row in reader:
        c = row.get('company_name') or row.get('company') or ''
        if c and c not in seen:
            seen.add(c)
            writer.writerow({
                'company_name': c,
                'company_domain': row.get('company_domain') or '',
                'company_website': row.get('company_website') or row.get('website') or '',
            })
"

# Signalsuche auf den eindeutigen Unternehmen ausführen
source \"$HOME/.claude/skills/gtm-pipeline/_shared/resolve_env.sh\" && \
export $(grep -E '^(PARALLEL_API_KEY|OPENROUTER_API_KEY|FIRECRAWL_API_KEY|GEMINI_API_KEY)=' \"$GTM_ENV_PATH\" | xargs) && \
  python3 ~/.claude/skills/gtm-signal-search/signal_search.py \
    --client-dir {client-slug}-gtm

Die resolve_env.sh-Source-Zeile stellt sicher, dass $GTM_ENV_PATH auch in einer frischen Shell gesetzt ist (siehe signal-search SKILL.md / Konventionen). Für die Demo Firecrawl und Parallel-Anreicherung AUS lassen – Websuche + Bewertung reicht für eine ~10-Kontakt-Lead-Liste. Firecrawl nur aktivieren, wenn On-Site-Inhalte (Karriere, Blog) die primäre Signalquelle sind; falls diese Maschine Firecrawl nur via MCP (kein FIRECRAWL_API_KEY) hat, den im signal-search-Skill dokumentierten --firecrawl-pages-dir-Pfad verwenden.

Signale zurück in Kontakte mergen

import csv, json
signals = {}
with open('csv/intermediate/signals.csv') as f:
    for row in csv.DictReader(f):
        signals[row['company_name']] = {
            'overall_score': row.get('overallScore', ''),
            'scored_signals': row.get('scoredSignals', ''),
            'overall_summary': row.get('overallSummary', ''),
        }

rows_out = []
with open('csv/output/contacts_enriched.csv') as f:
    for row in csv.DictReader(f):
        s = signals.get(row.get('company_name') or row.get('company') or '', {})
        row['company_overall_score'] = s.get('overall_score', '')
        row['company_scored_signals'] = s.get('scored_signals', '')
        row['company_overall_summary'] = s.get('overall_summary', '')
        rows_out.append(row)

with open('csv/output/contacts_enriched.csv', 'w', newline='') as f:
    w = csv.DictWriter(f, fieldnames=list(rows_out[0].keys()))
    w.writeheader()
    w.writerows(rows_out)

Der Nachrichtengenerierungsschritt in Schritt 6 hat dann company_overall_summary und company_scored_signals pro Kontakt – das am höchsten bewertete Signal als Nachrichtenhaken verwenden.


Schritt 6 – Nachrichtenbeispiele generieren

Generiere 2–4 Beispielnachrichten, bevor du dich auf den gesamten Batch festlegst.

Nachrichtenstruktur

Jede Nachricht muss folgendem Schema folgen: Hook → Bridge → Offer → Soft CTA

TeilZweckLänge
HookAuf etwas für diese Person Spezifisches Bezug nehmen (Beitrag, Karriereschritt, Unternehmenssignal)1 Satz
BridgeIhre Situation mit deinem Angebot verknüpfen1 Satz
OfferKlar darlegen, was du bietest1 Satz
CTASanfte Aufforderung – nicht „Lass uns einen Termin vereinbaren“1 Satz

Gesamt: 320–450 Zeichen. Keine Leerzeile nach der Anrede. Absätze durch einzelnen Zeilenumbruch trennen.

Qualitätsregeln

Muss haben:

  • Spezifischer Hook (Beitragsbezug ODER Karriere-Einblick ODER bewertetes Kaufsignal – nicht generisch)
  • Klares Wertversprechen
  • Natürlicher, gesprächiger Ton
  • Sanfter CTA

Vermeiden:

  • Wiederholung von Profilinformationen, die die Person bereits kennt („Du arbeitest als X bei Y“)
  • Allgemeine Beobachtungen („beeindruckender Hintergrund“, „Mir ist aufgefallen, dass du in [Branche] tätig bist“)
  • Unternehmensjargon oder Schlagwörter
  • Aufdringliche CTAs („Lass uns diese Woche einen Termin vereinbaren“)

Falls Schritt 5.5 ausgeführt wurde: für jeden Kontakt das am höchsten bewertete Signal aus company_scored_signals als Hook bevorzugen, gegenüber generischen LinkedIn-Beitragsbezügen. Ein Signal mit Score >= 70, verankert in tatsächlichen aktuellen Nachrichten, ist der stärkste Hook, den die Demo produzieren kann.

Generierungsprozess

  1. Kundenspezifischen System-Prompt schreiben (speichern in prompts/message_prompt.md)
  2. 2–4 Samples generieren – Kontakte mit und ohne LinkedIn-Beiträge einbeziehen
  3. Gegen obige Qualitätscheckliste prüfen
  4. Bei Problemen den System-Prompt verfeinern und neu generieren
  5. Nur Batch-generieren, wenn die Qualität freigegeben ist

System-Prompt-Vorlage (wichtige Abschnitte)

- Kundenkontext: was sie verkaufen, wen sie ansprechen, ihr Wertversprechen, Ton
- Verbotene Regeln: keine Profilwiederholung, keine generische Schmeichelei
- Nachrichtenstruktur: hook → bridge → offer → CTA
- Hook-Beispiele: mit Beiträgen / ohne Beiträge
- Zeichenlimit: 320–450

Schritt 7 – Bereinigen & Ausgeben

Schritt 7a – Bereinigen (obligatorisch, deterministisch, ohne LLM). csv/intermediate/ behält alle Felder. Bevor etwas Lead-seitiges erstellt wird, das gemeinsame Bereinigungsskript ausführen, damit die wiederkehrende manuelle Nachbearbeitung (Provider-Labels, leere Spalten, schlechte E-Mails, veraltete Signale) nicht mehr nötig ist.

Verwandte Skills