Kartieren Sie Ihren Markt
Nehmen Sie eine Produktbeschreibung, Kategorie-Keywords oder Wettbewerbsnamen. Durchsuchen Sie Reddit, HN, GitHub Issues, G2 und Google Trends nach echten Schmerzsignalen. Bewerten und clustern Sie diese. Erstellen Sie ein vollständiges Positionierungs-Framework: ICP-Definition, gewichtete Schmerzthemen mit wörtlichen Zitaten, Marktgrößensignale und Messaging-Ansätze, die aus der tatsächlich verwendeten Sprache der Menschen abgeleitet sind.
Wichtige Regel: Jedes Schmerzzitat in der Ausgabe muss wörtlich in den vom Skript gesammelten Rohdaten existieren. Jeder Anbietername in der Marktkarte muss aus G2-Scraping-Ergebnissen oder GitHub-Suchergebnissen stammen. Die Marktgröße muss "Signale deuten darauf hin" sagen – schätzen Sie niemals einen Dollar-Betrag aus dünnen Proxy-Daten. Wenn eine Quelle 0 Ergebnisse liefert, melden Sie 0 – ergänzen Sie nicht mit erfundenen Beispielen.
Häufige Fehler
| Der Agent wird wahrscheinlich... | Warum das falsch ist |
|---|---|
| Schmerzpunkte oder Marktgrößenzahlen erfinden | Jedes Schmerzzitat muss wörtlich aus den Rohdaten stammen. Die Marktgröße muss gefundene Signale zitieren. Schätzen Sie niemals eine "typische" Marktgröße. |
| Nach Post-Anzahl statt nach pain_score bewerten | Ein Post mit 2.000 Upvotes über Preise ist stärker als 50 Posts mit je 10 Upvotes. Verwenden Sie die pain_score-Formel aus references/pain-scoring.md. |
| Für jede Kategorie dieselben Subreddits verwenden | r/politics fügt einer DevOps-Suche Rauschen hinzu. Erkennen Sie relevante Subreddits automatisch aus der Kategorie und Wettbewerbsnamen vor der Suche. |
| Alle rohen Signale ohne Bewertung an KI senden | Bewerten Sie lokal zuerst. Senden Sie nur die Top-60-Signale mit hohem Schmerzscore an das KI-Clustering. Spart Tokens und verbessert die Clusterqualität. |
| ICP-Extraktion aus Post-Metadaten überspringen | Subreddit, Flair, Autoren-Bio (HN) und GitHub-Organisationstyp sind reichhaltigere ICP-Signale als Post-Inhalte. Erfassen und melden Sie sie immer. |
| Anbieteranzahl mit Marktgröße verwechseln | "47 Anbieter auf G2" bedeutet wettbewerbsintensiv, nicht groß. Präsentieren Sie alle Signale als richtungsweisende Indikatoren, nicht als harte Zahlen. |
Schritt 1: Setup-Prüfung
echo "GITHUB_TOKEN: ${GITHUB_TOKEN:-nicht gesetzt – GitHub Issues-Suche läuft mit 60 req/hr unauthentifiziert}"
echo "Keine anderen API-Schlüssel erforderlich."
echo ""
echo "In diesem Durchlauf verwendete Datenquellen:"
echo " Reddit public JSON (keine Authentifizierung, 10 req/min)"
echo " HN Algolia API (keine Authentifizierung, kostenlos)"
echo " GitHub Issues API (${GITHUB_TOKEN:+authentifiziert, }60-5000 req/hr)"
echo " G2 Kategorie-Scrape (keine Authentifizierung, HTML-Parse)"
echo " Google Trends (keine Authentifizierung, inoffizieller Endpunkt)"
Wenn GITHUB_TOKEN nicht gesetzt ist: Fahren Sie fort. Unauthhentifizierte GitHub-Suche ist mit 60 req/hr für einen Standardlauf ausreichend. Bei wiederholter Nutzung fügen Sie ein Token unter github.com/settings/tokens hinzu (keine Bereiche für öffentliche Repos erforderlich).
Schritt 2: Eingabe parsen
Sammeln Sie aus dem Gespräch:
category– Keyword(s), die den Marktbereich beschreiben (z. B. "Developer Observability", "B2B-Analytik", "DevOps-Tooling")competitors– optionale Liste von Wettbewerbsproduktnamen oder Domains (z. B. "Datadog, New Relic, Grafana")product_context– optional: was das Produkt des Benutzers tut (hilft bei der Anpassung von Messaging-Ansätzen)
Wenn der Benutzer nur eine Produktbeschreibung ohne Kategorie-Keyword angibt: Extrahieren Sie selbst 2-3 Kategorie-Keywords daraus.
Wenn der Benutzer nur Wettbewerbsnamen ohne Kategorie angibt: Leiten Sie die Kategorie durch Nachschlagen der Wettbewerber ab.
Schreiben Sie die geparste Eingabe:
python3 << 'PYEOF'
import json, os
data = {
"category": "CATEGORY_HIER",
"competitors": ["WETTBEWERBER_1", "WETTBEWERBER_2"],
"product_context": "PRODUKTKONTEXT_HIER"
}
with open("/tmp/mym-input.json", "w") as f:
json.dump(data, f, indent=2)
print("Eingabe nach /tmp/mym-input.json geschrieben")
print(f"Kategorie: {data['category']}")
print(f"Wettbewerber: {', '.join(data['competitors']) if data['competitors'] else 'keine angegeben'}")
PYEOF
Schritt 3: Ausführen des eigenständigen Datensammlungsskripts
Das Skript übernimmt die gesamte Datensammlung. Überprüfen Sie zuerst, ob es existiert:
ls scripts/fetch.py 2>/dev/null && echo "Skript verfügbar" || echo "nicht gefunden"
Wenn verfügbar, führen Sie es aus:
GITHUB_TOKEN="${GITHUB_TOKEN:-}" python3 scripts/fetch.py \
"$(python3 -c "import json; d=json.load(open('/tmp/mym-input.json')); print(d['category'])")" \
--competitors "$(python3 -c "import json; d=json.load(open('/tmp/mym-input.json')); print(','.join(d['competitors']))")" \
--context "$(python3 -c "import json; d=json.load(open('/tmp/mym-input.json')); print(d['product_context'])")" \
--output /tmp/mym-raw.json
Warten Sie auf den Abschluss (erlauben Sie bis zu 4 Minuten – Reddit + HN-Suchen dauern insgesamt ~90 Sekunden).
Überprüfen Sie die Ausgabe:
python3 -c "
import json
with open('/tmp/mym-raw.json') as f:
d = json.load(f)
print(f'Reddit-Signale: {d[\"market_signals\"][\"reddit_signals_found\"]}')
print(f'HN-Signale: {d[\"market_signals\"][\"hn_signals_found\"]}')
print(f'GitHub-Signale: {d[\"market_signals\"][\"github_issue_signals\"]}')
print(f'G2-Anbieter: {d[\"market_signals\"][\"vendor_count_g2\"]}')
print(f'Trends: {d[\"market_signals\"][\"trends_direction\"]}')
print(f'Signale gesamt: {d[\"summary\"][\"total_pain_signals\"]}')
"
Wenn die Gesamtzahl der Signale < 10 ist: Stoppen Sie. Sagen Sie dem Benutzer: "Für diese Kategorie wurden weniger als 10 Schmerzsignale gefunden. Der Markt ist möglicherweise zu nischenhaft für Reddit/HN-Abdeckung, oder die Kategorie-Keywords müssen angepasst werden. Versuchen Sie es mit breiteren Keywords oder fügen Sie Wettbewerbsnamen hinzu."
Schritt 4: KI-Schmerzpunkt-Clustering
Drucken Sie die Top-60-Schmerzsignale für die KI-Analyse:
python3 -c "
import json
with open('/tmp/mym-raw.json') as f:
d = json.load(f)
top60 = sorted(d['raw_pains'], key=lambda x: x['pain_score'], reverse=True)[:60]
print(json.dumps(top60, indent=2))
"
Sie haben nun die Top-60-Schmerzsignale. Analysieren Sie sie und erstellen Sie Schmerzcluster.
Anweisungen für die KI-Analyse:
- Identifizieren Sie 5-7 wiederkehrende Schmerzthemen über alle Quellen hinweg
- Wählen Sie für jedes Thema einen Namen, der die eigene Sprache des Marktes verwendet (nicht Ihre Worte)
- Aggregieren Sie den pain_score aller Signale in jedem Cluster
- Wählen Sie für jedes Thema die 3-5 besten wörtlichen Zitate (höchste Punktzahl, spezifischste Sprache)
- Notieren Sie, in welchen Quellen und Subreddits sich jedes Thema konzentriert
- Markieren Sie jedes Thema, das nur in einer Quelle erscheint (geringere Konfidenz)
Schreiben Sie die Cluster nach /tmp/mym-clusters.json:
{
"clusters": [
{
"theme": "genaue Sprache aus den Daten",
"total_score": 847,
"signal_count": 34,
"sources": {"reddit": 18, "hn": 12, "github_issue": 4},
"top_subreddits": ["devops", "sysadmin"],
"verbatim_quotes": [
{"text": "genaues Zitat", "source": "reddit", "score": 234, "url": "..."},
{"text": "genaues Zitat", "source": "hn", "score": 87, "url": "..."}
],
"who_has_this_pain": "Beschreibung, wer darüber postet"
}
]
}
python3 -c "
import json, os
# Bestätigen, dass die Cluster-Datei geschrieben wurde
with open('/tmp/mym-clusters.json') as f:
d = json.load(f)
print(f'Cluster geschrieben: {len(d[\"clusters\"])}')
for c in d['clusters']:
print(f' {c[\"theme\"]} -- Score: {c[\"total_score\"]}, Signale: {c[\"signal_count\"]}')
"
Schritt 5: ICP-Profilierung
Drucken Sie die ICP-Signale aus den Rohdaten:
python3 -c "
import json
with open('/tmp/mym-raw.json') as f:
d = json.load(f)
print('ICP-Signale:')
print(json.dumps(d['icp_signals'], indent=2))
print()
print('Subreddit-Verteilung:')
sub_counts = {}
for p in d['raw_pains']:
s = p.get('subreddit', '')
if s:
sub_counts[s] = sub_counts.get(s, 0) + 1
for sub, count in sorted(sub_counts.items(), key=lambda x: -x[1])[:10]:
print(f' r/{sub}: {count} Signale')
"
Verwenden Sie die obigen ICP-Signale und die Subreddit-Verteilung, um das ICP-Profil zu synthetisieren. Schreiben Sie es nach /tmp/mym-clusters.json, indem Sie einen icp-Schlüssel hinzufügen:
{
"icp": {
"who_they_are": "2-3-Satz-Profil unter Verwendung von Sprache aus den Daten",
"where_they_live": ["r/devops (89 Beiträge)", "r/sysadmin (67 Beiträge)", "HN ask-hn (34 Threads)"],
"what_they_say": ["wörtliches Zitat 1", "wörtliches Zitat 2", "wörtliches Zitat 3"],
"what_they_have_tried": ["alternative Tools oder Ansätze, die in den Daten erwähnt werden"],
"confidence": "hoch|mittel|niedrig – basierend auf Signalvolumen und Quellenvielfalt"
}
}
Schritt 6: Marktgrößen-Synthese
Drucken Sie die Marktsignale:
python3 -c "
import json
with open('/tmp/mym-raw.json') as f:
d = json.load(f)
ms = d['market_signals']
print('Marktsignale:')
print(f' G2-Anbieter: {ms[\"vendor_count_g2\"]}')
print(f' Trendrichtung: {ms[\"trends_direction\"]}')
print(f' HN-Signale (12M): {ms[\"hn_signals_found\"]}')
print(f' Reddit-Signale: {ms[\"reddit_signals_found\"]}')
print(f' G2-Top-Anbieter: {json.dumps(ms.get(\"top_vendors\", []), indent=4)}')
"
Synthetisieren Sie eine richtungsweisende Marktgrößenbewertung unter ausschließlicher Verwendung dieser Signale. Schätzen Sie keinen Dollar-Betrag. Verwenden Sie Ausdrücke wie:
- "Signale deuten auf einen wettbewerbsintensiven, wachsenden Markt hin" (viele Anbieter + Trends steigen)
- "Signale deuten auf einen frühen Markt hin" (wenige Anbieter + geringes Signalvolumen)
- "Signale deuten auf einen gesättigten Markt hin" (viele Anbieter + flache/rückläufige Trends)
Fügen Sie die Bewertung als market_size-Schlüssel zu /tmp/mym-clusters.json hinzu.
Schritt 7: Positionierungs-Framework
Erstellen Sie unter Verwendung der Cluster (Schritt 4), des ICP (Schritt 5) und der Marktgröße (Schritt 6) das Positionierungs-Framework.
Anweisungen:
- Wählen Sie die Top-3-Schmerzcluster als primäre Positionierungswinkel
- Schreiben Sie für jeden Winkel eine Positionierungsaussage unter Verwendung wörtlicher Sprache aus den Daten (nicht paraphrasiert)
- Generieren Sie 3 Landingpage-Überschriften, die die genauen Phrasen verwenden, die Menschen in den Schmerzdaten verwenden
- Generieren Sie 3 Kalt-E-Mail-Betreffzeilen basierend auf der Schmerzsprache
- Verwenden Sie KEINE verbotenen Wörter: powerful, robust, seamless, innovative, game-changing, streamline, leverage, transform, revolutionize
Schreiben Sie das vollständige Positionierungs-Framework nach /tmp/mym-output.json:
{
"positioning_angles": [
{
"pain": "Themenname",
"statement": "einzeilige Positionierung unter Verwendung von Marktsprache",
"headline": "Landingpage-Überschrift mit wörtlicher Schmerzsprache",
"cold_email_subject": "Betreffzeile"
}
],
"icp_card": {
"one_liner": "ein Satz: wer sie sind + was ihnen wichtig ist",
"where_to_find_them": [...],
"how_to_talk_to_them": "Tonfall + Vokabularnotizen aus den Daten"
},
"market_map": [...Top-Anbieter von G2 mit Positionierungsnotizen...]
}
Schritt 8: Selbst-QA und Ausgabe speichern
Führen Sie Selbst-QA-Prüfungen durch:
python3 -c "
import json
# Alle Ausgaben laden
with open('/tmp/mym-raw.json') as f:
raw = json.load(f)
with open('/tmp/mym-clusters.json') as f:
clusters = json.load(f)
with open('/tmp/mym-output.json') as f:
output = json.load(f)
raw_texts = set()
for p in raw['raw_pains']:
raw_texts.add(p.get('title', ''))
raw_texts.add(p.get('body_excerpt', ''))
# Prüfung 1: Keine Em-Dashes
import json as j
full_text = j.dumps(output)
if '—' in full_text:
print('FEHLGESCHLAGEN: Em-Dash in der Ausgabe gefunden')
else:
print('BESTANDEN: Keine Em-Dashes')
# Prüfung 2: Keine verbotenen Wörter
banned = ['powerful', 'robust', 'seamless', 'innovative', 'game-changing',
'streamline', 'leverage', 'transform', 'revolutionize']
found = [w for w in banned if w.lower() in full_text.lower()]
if found:
print(f'FEHLGESCHLAGEN: Verbotene Wörter gefunden: {found}')
else:
print('BESTANDEN: Keine verbotenen Wörter')
# Prüfung 3: Marktgrößen-Sprachprüfung
if 'billion' in full_text.lower() or 'trillion' in full_text.lower() or 'worth \$' in full_text.lower():
print('FEHLGESCHLAGEN: Harte Marktgrößenschätzung gefunden – nur richtungsweisende Sprache verwenden')
else:
print('BESTANDEN: Keine harten Marktgrößenschätzungen')
# Prüfung 4: Signalzahlen stimmen überein
total = raw['summary']['total_pain_signals']
print(f'BESTANDEN: {total} Schmerzsignale insgesamt in Rohdaten')
print('Selbst-QA abgeschlossen.')
"
Beheben Sie Fehler vor dem Speichern.
Speichern Sie den endgültigen Bericht:
python3 << 'PYEOF'
import json, re
from datetime import datetime
with open('/tmp/mym-input.json') as f:
inp = json.load(f)
with open('/tmp/mym-raw.json') as f:
raw = json.load(f)
with open('/tmp/mym-clusters.json') as f:
clusters = json.load(f)
with open('/tmp/mym-output.json') as f:
output = json.load(f)
slug = re.sub(r'[^a-z0-9]+', '-', inp['category'].lower()).strip('-')
date = datetime.now().strftime('%Y-%m-%d')
outpath_md = f'docs/market-maps/{slug}-{date}.md'
outpath_json = f'docs/market-maps/{slug}-{date}.json'
# Markdown-Bericht erstellen
ms = raw['market_signals']
icp = clusters.get('icp', {})
market_assessment = clusters.get('market_size', {})
angles = output.get('positioning_angles', [])
icp_card = output.get('icp_card', {})
market_map = output.get('market_map', [])
lines = [
f'# Marktkarte: {inp["category"].title()}',
f'Datum: {date} | Analysierte Signale: {raw["summary"]["total_pain_signals"]} | Quellen: Reddit ({ms["reddit_signals_found"]}) + HN ({ms["hn_signals_found"]}) + GitHub Issues ({ms["github_issue_signals"]})',
'',
'---',
'',
'## Marktgrößensignale',
f'Anbieter auf G2: {ms["vendor_count_g2"]} | Google Trends: {ms["trends_direction"].upper()} | Marktphase: {market_assessment.get("stage", "siehe Signale unten")}',
'',
market_assessment.get('summary', ''),
'',
'---',
'',
'## Ihr ICP',
'',
f'**Wer sie sind:** {icp.get("who_they_are", "")}',
'',
f'**Wo sie leben:** {", ".join(icp.get("where_they_live", []))}',
'',
'**Was sie sagen:**',
]
for q in icp.get('what_they_say', []):
lines.append(f'> "{q}"')
lines += ['', '---', '', '## Top-Schmerzen (nach Signalstärke geordnet)', '']
for i, c in enumerate(clusters.get('clusters', []), 1):
lines.append(f'### Schmerz {i}: {c["theme"]} [Score: {c["total_score"]}]')
sources = c.get('sources', {})
source_str = ' + '.join(f'{src} ({cnt})' for src, cnt in sources.items())
lines.append(f'{c["signal_count"]} Signale | Quellen: {source_str}')
lines.append(f'Wer hat diesen Schmerz: {c.get("who_has_this_pain", "")}')
lines.append('')
lines.append('Wörtlich:')
for q in c.get('verbatim_quotes', [])[:4]:
lines.append(f'- "{q["text"]}" ({q["source"]}, Score: {q["score"]})')
lines.append('')
lines += ['---', '', '## Positionierungs-Framework', '']
for angle in angles:
lines.append(f'**Schmerz:** {angle["pain"]}')
lines.append(f'**Aussage:** {angle["statement"]}')
lines.append(f'**Überschrift:** {angle["headline"]}')
lines.append(f'**Kalt-E-Mail:** {angle["cold_email_subject"]}')
lines.append('')
lines += ['---', '', '## ICP-Karte', '']
lines.append(f'{icp_card.get("one_liner", "")}')
lines.append(f'Wo zu finden: {json.dumps(icp_card.get("where_to_find_them", []), indent=2, ensure_ascii=False)}')
lines.append(f'Wie ansprechen: {icp_card.get("how_to_talk_to_them", "")}')
lines += ['', '---', '', '## Marktkarte (Wettbewerbslandschaft)', '']
for m in market_map[:10]:
lines.append(f'- {m.get("name", "")}: {m.get("notes", "")}')
report = '\n'.join(lines)
with open(outpath_md, 'w') as f:
f.write(report)
print(f'Bericht geschrieben: {outpath_md}')
with open(outpath_json, 'w') as f:
json.dump(output, f, indent=2, ensure_ascii=False)
print(f'JSON geschrieben: {outpath_json}')
PYEOF
Ergebnis: Sie haben eine Marktkarte mit ICP, gewichteten Schmerzthemen, Marktgrößensignalen und Positionierungswinkeln im docs/market-maps/-Verzeichnis.
Ausführliche Anleitung
Eine detaillierte Referenz mit Formeln, Glossar und Architektur finden Sie in den Ordner references/, insbesondere:
references/pain-scoring.md– Wiepain_scorefür jedes Signal berechnet wirdreferences/glossary.md– Definitionen von Begriffen wie ICP, Marktsignal, Schmerz-Clusterreferences/architecture.md– Wie Daten fließen und warum
Über deutsches recht
(Dieser Abschnitt dient nur zur Information – kein Teil des Prozesses).
Ihr Skill ist ausschließlich auf deutsch.
Ende der Skill-Beschreibung.