PR-Wettbewerber-Finder
Gib deine Produkt-URL ein. Es findet deine Wettbewerber, recherchiert alle PR-Kanäle (Nachrichten, Podcasts, Communities), identifiziert die Kanäle, die bei mehreren Wettbewerbern vorkommen (deine bewährten Ziele), findet die verantwortlichen Journalisten oder Hosts und erstellt personalisierte Kaltakquise-Pitches für dein Produkt auf jedem Kanal der Stufe 1.
Null-Halluzinations-Richtlinie: Jeder Kanal, jeder Journalistenname, jede Story-Angle und jedes Pitch-Detail in der Ausgabe muss auf ein bestimmtes Tavily-Suchergebnis oder die abgerufene Produktseite zurückgeführt werden können. Dies gilt für:
- Wettbewerbsnamen: müssen in Tavily-Suchergebnissen erscheinen, nicht aus dem KI-Training
- Kanalnamen: müssen eine URL in den Suchergebnissen haben
- Journalisten-/Host-Namen: müssen wörtlich in einem Tavily-Auszug erscheinen
- Story-Angeln: werden nur aus Artikel-/Episodentiteln in den Suchergebnissen extrahiert
- Pitch-Entwürfe: müssen sich auf spezifische Beweise aus den Suchdaten + der Produktanalyse beziehen
Häufige Fehler
| Der Agent wird versuchen zu... | Warum das falsch ist |
|---|---|
| Einen Journalisten aus dem Trainingswissen nennen | Jeder Journalistenname muss auf einen Suchergebnis-Auszug zurückgehen. "Sarah Perez schreibt bei TechCrunch über Startups" aus dem Gedächtnis ist eine Halluzination. |
| Kanäle ohne Beleg-URLs auflisten | Jeder Kanal in der Ausgabe muss mindestens eine URL aus den PR-Suchergebnissen haben, die belegt, dass ein Wettbewerber dort vorgestellt wurde. |
| Den Schritt zur Wettbewerberbestätigung überspringen | Zeige immer die entdeckten Wettbewerber an und warte auf die Bestätigung des Benutzers. Falsche Wettbewerber = verschwendete Suchen und eine nutzlose Ausgabe. |
| Generische Pitches erstellen ("Wir würden gerne vorgestellt werden") | Jeder Pitch muss sich auf eine bestimmte Angle aus den Beweisen UND ein spezifisches Unterscheidungsmerkmal aus der Produktanalyse beziehen. |
| Einen Kanal als Stufe 1 markieren, obwohl nur 1 Wettbewerber dort vorkommt | Stufe 1 = 3+ Wettbewerber. Stufe 2 = genau 2. Stufe 3 = 1. Befördere keine Kanäle, die sich nicht bewährt haben. |
| Em-Dashes in der Ausgabe verwenden | Ersetze alle Em-Dashes (—) durch Bindestriche. |
Referenzdateien vor jedem Durchlauf lesen
cat references/pr-channel-types.md
cat references/pitch-guide.md
cat references/tier-scoring.md
Schritt 1: Setup-Prüfung
echo "TAVILY_API_KEY: ${TAVILY_API_KEY:+set}${TAVILY_API_KEY:-NOT SET -- erforderlich}"
echo "FIRECRAWL_API_KEY: ${FIRECRAWL_API_KEY:+set}${FIRECRAWL_API_KEY:-nicht gesetzt, Tavily extract wird als Fallback verwendet}"
Wenn TAVILY_API_KEY fehlt: Sofort abbrechen. Teile dem Benutzer mit: "TAVILY_API_KEY wird benötigt, um Wettbewerber zu recherchieren und PR-Berichterstattung zu finden. Es gibt keinen Fallback. Hol dir den Schlüssel unter app.tavily.com -- kostenloser Tarif: 1000 Credits/Monat (ca. 43 vollständige Durchläufe bei ~23 Suchanfragen/Durchlauf). Füge ihn zu deiner .env-Datei hinzu."
Wenn nur FIRECRAWL_API_KEY fehlt: Fortfahren. Tavily extract wird für den URL-Abruf verwendet.
Schritt 2: Eingabe parsen
Sammle aus dem Gespräch:
product_url: die abzurufende URL (erforderlich, es sei denn, der Benutzer fügt direkt eine Beschreibung ein)product_name: optional, wird von der Seite abgeleitet, falls nicht angegebengeography: optional -- US / Europa / global. Standard: US
Wenn der Benutzer nur eine eingefügte Beschreibung (keine URL) angibt: Überspringe die Schritte 3 und 4. Gehe direkt zu Schritt 4 (Produktanalyse) mit dem eingefügten Text als product_content. Setze page_source auf user_description und vermerke dies in data_quality_flags.
Wenn weder URL noch Beschreibung: Frage: "Was ist die URL Ihres Produkts oder Startups? Oder fügen Sie eine kurze Beschreibung ein: Was es tut, für wen es ist und was es von Wettbewerbern unterscheidet."
Leite den Produkt-Slug ab:
PRODUCT_SLUG=$(python3 -c "
from urllib.parse import urlparse
import sys
url = 'URL_HIER'
if url.startswith('http'):
host = urlparse(url).netloc.replace('www.', '')
print(host.split('.')[0])
else:
import re
print(re.sub(r'[^a-z0-9]', '-', url[:30].lower()).strip('-'))
")
echo "Product slug: $PRODUCT_SLUG"
Schritt 3: Produktseite abrufen
Primär: Firecrawl (wenn FIRECRAWL_API_KEY gesetzt ist)
curl -s -X POST https://api.firecrawl.dev/v1/scrape \
-H "Authorization: Bearer $FIRECRAWL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "URL_HIER", "formats": ["markdown"], "onlyMainContent": true}' \
| python3 -c "
import sys, json
d = json.load(sys.stdin)
content = d.get('data', {}).get('markdown', '') or d.get('markdown', '')
print(f'Abgerufen via Firecrawl: {len(content)} Zeichen')
open('/tmp/cprf-product-raw.md', 'w').write(content)
"
Fallback: Tavily extract (wenn FIRECRAWL_API_KEY nicht gesetzt ist)
curl -s -X POST https://api.tavily.com/extract \
-H "Content-Type: application/json" \
-d "{\"api_key\": \"$TAVILY_API_KEY\", \"urls\": [\"URL_HIER\"]}" \
| python3 -c "
import sys, json
d = json.load(sys.stdin)
content = d.get('results', [{}])[0].get('raw_content', '')
print(f'Abgerufen via Tavily extract: {len(content)} Zeichen')
open('/tmp/cprf-product-raw.md', 'w').write(content)
"
Kontrollpunkt:
python3 -c "
content = open('/tmp/cprf-product-raw.md').read()
if len(content) < 200:
print('FEHLER: weniger als 200 Zeichen abgerufen')
else:
print(f'Inhalt ok: {len(content)} Zeichen')
"
Wenn Inhalt < 200 Zeichen: Abruf abbrechen. Teile dem Benutzer mit: "Die Produktseite hat keinen lesbaren Inhalt zurückgegeben -- die Seite verwendet wahrscheinlich JavaScript und blockiert den Abruf. Bitte fügen Sie direkt eine kurze Beschreibung ein: Was es tut, für wen es ist und was es unterscheidend macht."
Schritt 4: Produktanalyse (KI)
Seiteninhalt ausgeben:
python3 -c "
content = open('/tmp/cprf-product-raw.md').read()[:5000]
print('=== PRODUKTSEITE (erste 5000 Zeichen) ===')
print(content)
"
KI-Anweisungen: Analysiere die obige Produktseite und extrahiere:
product_name: der Produkt- oder Firmennameone_line_description: was es tut, für wen, Kernnutzenversprechen. Unter 20 Wörtern. Keine Marketing-Sprache. Beispiel: "CI/CD-Automatisierung für Entwicklerteams, die ihre Pipelines selbst hosten."industry_taxonomy:l1(oberste Ebene: z. B. Entwicklertools / Fintech / Healthtech / Consumer),l2(Bereich: z. B. DevOps / Zahlungen / Telemedizin),l3(spezifische Nische: z. B. CI/CD-Automatisierung / eingebettete Zahlungen / asynchrone Videoberatung). Vage Bezeichnungen wie "Technologie" allein sind nicht akzeptabel.differentiators: genau 2-3 spezifische Dinge, die dieses Produkt von generischen Wettbewerbern unterscheiden. Diese fließen direkt in die Pitch-Entwürfe ein -- sei spezifisch. Beispiel: ["Self-gehosteter Pipeline-Runner -- keine Daten verlassen Ihre Infrastruktur", "Native Unterstützung für Monorepos mit dynamischer Schritterzeugung"]icp:buyer_persona(Berufsbezeichnung),company_type,company_sizegeography_bias: US / Europa / global / unklarpage_source: "live_page" oder "user_description"
Schreibe nach /tmp/cprf-product-analysis.json:
python3 << 'PYEOF'
import json
analysis = {
# FÜLLE aus deiner obigen Analyse
"product_name": "",
"one_line_description": "",
"industry_taxonomy": {"l1": "", "l2": "", "l3": ""},
"differentiators": [],
"icp": {"buyer_persona": "", "company_type": "", "company_size": ""},
"geography_bias": "US",
"page_source": "live_page"
}
json.dump(analysis, open('/tmp/cprf-product-analysis.json', 'w'), indent=2)
print('Produktanalyse geschrieben.')
PYEOF
Überprüfen:
python3 -c "
import json
a = json.load(open('/tmp/cprf-product-analysis.json'))
print('Produkt:', a['product_name'])
print('Branche:', a['industry_taxonomy']['l1'], '>', a['industry_taxonomy']['l2'], '>', a['industry_taxonomy']['l3'])
print('Unterscheidungsmerkmale:')
for d in a['differentiators']:
print(f' - {d}')
"
Schritt 4b: Phase 1 -- Wettbewerber entdecken
ls scripts/research.py 2>/dev/null && echo "Skript gefunden" || echo "FEHLER: scripts/research.py nicht gefunden -- kann nicht fortfahren"
python3 scripts/research.py \
--phase discover \
--product-analysis /tmp/cprf-product-analysis.json \
--tavily-key "$TAVILY_API_KEY" \
--output /tmp/cprf-competitors-raw.json
Ergebnisse zur KI-Überprüfung ausgeben:
python3 -c "
import json
data = json.load(open('/tmp/cprf-competitors-raw.json'))
print(f'Durchgeführte Suchanfragen: {len(data[\"competitor_searches\"])}')
for s in data['competitor_searches']:
print(f'\nAbfrage: {s[\"query\"]}')
print(f'Antwort: {s.get(\"answer\",\"\")[:400]}')
for r in s.get('results', [])[:5]:
print(f' - {r[\"title\"]} | {r[\"url\"]}')
print(f' {r.get(\"content\",\"\")[:200]}')
"
KI-Anweisungen: Lies die obigen Suchergebnisse. Wähle genau 5 Wettbewerbsunternehmen aus, die:
- in den Titeln, Antworten oder Auszügen der Suchergebnisse genannt werden
- sich in derselben L3-Nische wie das analysierte Produkt befinden
- tatsächliche Konkurrenzprodukte sind (keine Agenturen, Beratungen oder Listenartikel)
- sich voneinander unterscheiden (nicht dasselbe Unternehmen unter verschiedenen Namen)
Schreibe für jeden Wettbewerber: name, url (aus dem Suchergebnis, in dem er erschien), description (ein Satz aus dem Auszug), source_url (die URL des Suchergebnisses, wo er gefunden wurde).
Schritt 5: Wettbewerber bestätigen
Zeige dem Benutzer die entdeckten Wettbewerber an:
python3 << 'PYEOF'
import json
analysis = json.load(open('/tmp/cprf-product-analysis.json'))
# FÜLLE: 5 Wettbewerber aus den obigen Suchergebnissen
candidates = [
# {"name": str, "url": str, "description": str, "source_url": str}
]
print(f"\nGefundene 5 Wettbewerber für {analysis['product_name']} in {analysis['industry_taxonomy']['l3']}:\n")
for i, c in enumerate(candidates, 1):
print(f" {i}. {c['name']} -- {c['description']}")
print(f" {c['url']}")
data = json.load(open('/tmp/cprf-competitors-raw.json'))
data['competitor_candidates'] = candidates
json.dump(data, open('/tmp/cprf-competitors-raw.json', 'w'), indent=2)
PYEOF
Teile dem Benutzer mit: "Dies sind die 5 Wettbewerber, die ich auf PR-Berichterstattung untersuchen werde. Du kannst jeden hinzufügen, entfernen oder austauschen -- oder sage 'sieht gut aus', um fortzufahren."
Auf Bestätigung warten. Wenn der Benutzer die Liste bearbeitet (hinzufügt/entfernt/austauscht), aktualisiere die Kandidaten entsprechend. Schreibe dann die bestätigte Liste:
python3 << 'PYEOF'
import json
# FÜLLE: bestätigte Wettbewerberliste (nach Benutzerprüfung)
confirmed = [
# {"name": str, "url": str}
]
json.dump({"confirmed_competitors": confirmed}, open('/tmp/cprf-competitors-confirmed.json', 'w'), indent=2)
print(f"Bestätigte {len(confirmed)} Wettbewerber für die PR-Recherche.")
for c in confirmed:
print(f" - {c['name']} ({c['url']})")
PYEOF
Schritt 6: Drei-Spur-PR-Recherche (Phase 2)
python3 scripts/research.py \
--phase pr-research \
--competitors /tmp/cprf-competitors-confirmed.json \
--product-analysis /tmp/cprf-product-analysis.json \
--tavily-key "$TAVILY_API_KEY" \
--output /tmp/cprf-pr-raw.json
Dies führt 3 Suchanfragen pro Wettbewerber durch (insgesamt 15):
- Spur A (Redaktionell):
"[Wettbewerber]" vorgestellte Presseberichterstattung TechCrunch Forbes Wired Artikel Interview - Spur B (Podcasts):
"[Wettbewerber]" Gründer CEO Podcast Interview erschien Episode - Spur C (Communities):
"[Wettbewerber]" site:reddit.com OR site:news.ycombinator.com OR site:producthunt.com
Zusammenfassung der Berichterstattung ausgeben:
python3 -c "
import json
data = json.load(open('/tmp/cprf-pr-raw.json'))
print(f'Recherchierte Wettbewerber: {data[\"competitors_researched\"]}')
print()
for r in data['results']:
print(f'{r[\"competitor\"]}:')
for track, tdata in r['tracks'].items():
n = len(tdata.get('results', []))
print(f' {track:12}: {n} Ergebnisse')
"
Wenn alle 3 Spuren für einen Wettbewerber 0 Ergebnisse liefern: Dieser Wettbewerber hat eine sehr geringe Presseberichterstattung. Vermerke dies in data_quality_flags und fahre fort -- das kanalübergreifende Muster funktioniert trotzdem mit den verbleibenden 4.
Schritt 7: Musteranalyse (KI)
Alle rohen PR-Ergebnisse ausgeben:
python3 -c "
import json
data = json.load(open('/tmp/cprf-pr-raw.json'))
for r in data['results']:
print(f'\n=== {r[\"competitor\"]} ===')
for track, tdata in r['tracks'].items():
print(f'\n--- Spur {track.upper()} ---')
print(f'Abfrage: {tdata[\"query\"]}')
print(f'Antwort: {tdata.get(\"answer\",\"\")[:400]}')
for item in tdata.get('results', [])[:5]:
print(f' Titel: {item[\"title\"]}')
print(f' URL: {item[\"url\"]}')
print(f' Auszug: {item.get(\"content\",\"\")[:200]}')
"
KI-Anweisungen: Lese ALLE obigen Suchergebnisse. Erstelle eine Kanal-Frequenzkarte.
Schritt 1 -- Normalisiere URLs zur Root-Domain: https://techcrunch.com/2023/06/artikel-titel → techcrunch.com. https://open.spotify.com/episode/... → als Podcast identifizieren (Spotify-Episode). https://www.reddit.com/r/devops/ → reddit.com/r/devops.
Schritt 2 -- Zähle Vorkommen: Wie viele verschiedene Wettbewerber sind in den Ergebnissen jedes Kanal-Roots aufgetaucht? Ein Kanal, der in Wettbewerber A's Spur A UND Wettbewerber B's Spur A auftaucht, zählt als Häufigkeit 2.
Schritt 3 -- Kanäle einstufen (befolge references/tier-scoring.md):
- Stufe 1: in 3+ Wettbewerbern erschienen
- Stufe 2: in genau 2 Wettbewerbern erschienen
- Stufe 3: in 1 Wettbewerber erschienen
Schritt 4 -- Extrahiere Story-Winkel aus Artikel-/Episodentiteln in den Ergebnissen. Klassifiziere jeden als: Finanzierungsankündigung / Produkteinführung / Gründergeschichte / Trendartikel / Kategorie-Schaffung / Anleitung / Vergleich / Auszeichnung. Schreibe nicht -- klassifiziere nur Winkel, die in den Titeln sichtbar sind.
Schritt 5 -- Klassifiziere Kanaltyp für jeden: redaktionell / Podcast / Community / Newsletter.
Schreibe nach /tmp/cprf-pr-patterns.json:
python3 << 'PYEOF'
import json
patterns = {
"tier_1_channels": [
# FÜLLE -- Kanäle, die in 3+ Wettbewerbern erscheinen
# Jeder: {"channel_name": str, "channel_url": str, "channel_type": str,
# "frequency": int, "found_in_competitors": [str],
# "evidence_urls": [str], "story_angles_used": [str],
# "journalist_name": "", "journalist_beat": ""}
],
"tier_2_channels": [
# FÜLLE -- Kanäle, die in genau 2 Wettbewerbern erscheinen
# Jeder: {"channel_name": str, "channel_url": str, "channel_type": str,
# "frequency": int, "found_in_competitors": [str],
# "evidence_urls": [str], "story_angles_used": [str],
# "journalist_name": "", "journalist_beat": ""}
],
"tier_3_channels": [
# FÜLLE -- Kanäle, die in 1 Wettbewerber erscheinen
]
}
json.dump(patterns, open('/tmp/cprf-pr-patterns.json', 'w'), indent=2)
print(f"Muster geschrieben: {len(patterns['tier_1_channels'])} Stufe-1, {len(patterns['tier_2_channels'])} Stufe-2, {len(patterns['tier_3_channels'])} Stufe-3")
for t in ['tier_1_channels', 'tier_2_channels', 'tier_3_channels']:
for c in patterns[t]:
print(f" {t}: {c['channel_name']} ({c['channel_url']}) Häufigkeit {c['frequency']} Gefunden in {c['found_in_competitors']}")
PYEOF
Schritt 8: Journalisten-/Host-Recherche
Führe für jeden Stufe-1-Kanal eine direkte Suche durch, um den spezifischen Journalisten oder Host zu finden, der die Kategorie abdeckt:
python3 scripts/research.py \
--phase journalist-finder \
--patterns /tmp/cprf-pr-patterns.json \
--product-analysis /tmp/cprf-product-analysis.json \
--tavily-key "$TAVILY_API_KEY" \
--output /tmp/cprf-journalists-raw.json
Dies führt eine Suche durch wie: "techcrunch" "CI/CD" "reporter" ODER "editor" site:techcrunch.com
Ergebnisse ausgeben:
python3 -c "
import json
data = json.load(open('/tmp/cprf-journalists-raw.json'))
for r in data['results']:
print(f'\nKanal: {r[\"channel\"]}')
print(f'Abfrage: {r[\"query\"]}')
print(f'Antwort: {r.get(\"answer\",\"\")[:400]}')
for item in r.get('results', [])[:3]:
print(f' {item[\"title\"]} - {item[\"url\"]}')
"
KI-Anweisungen: Lies die Suchergebnisse. Gib für jeden Stufe-1-Kanal aus:
journalist_name: Der namentlich genannte Journalist oder Host in den Auszügen (muss wörtlich sein)journalist_beat: Das Fachgebiet, das dieser Journalist abdeckt, aus den Suchergebnissenevidence: Direktes Zitat aus dem Auszug, das Name und Zuständigkeit bestätigtstory_angle_match: Welcher der Story-Winkel, die in diesem Kanal gefunden wurden, am ehesten mit dem Produkt übereinstimmt
Schreibe nach /tmp/cprf-journalists-confirmed.json:
python3 << 'PYEOF'
import json
journalists = {
# FÜLLE für jeden Stufe-1-Kanal
# "techcrunch.com": {
# "journalist_name": "",
# "journalist_beat": "",
# "evidence": "",
# "story_angle_match": ""
# }
}
json.dump(journalists, open('/tmp/cprf-journalists-confirmed.json', 'w'), indent=2)
print(f"Journalisten/Hosts bestätigt für {len(journalists)} Kanäle")
for k, v in journalists.items():
print(f" {k}: {v['journalist_name']} ({v['journalist_beat']})")
PYEOF
Schritt 9: Abschließende Musterausgabe
Lese Referenzdateien vor dem Schreiben des Pitches:
cat references/pitch-guide.md
KI-Anweisungen: Generiere den vollständigen Bericht im folgenden Markdown-Format. KEINE Em-Dashes (—) verwenden -- stattdessen Bindestriche (-).
# PR-Outreach-Bericht: [Produktname]
**Produkt:** [Produktname]
**Beschreibung:** [Einzeiler]
**Branche:** [L1 > L2 > L3]
**Zielgruppe:** [Käufer-Persona] bei [Unternehmenstyp] ([Unternehmensgröße])
**Datenqualität:** [Hinweise, wenn Beschreibung verwendet wurde oder Seitenabruf fehlschlug]
---
## Zusammenfassung
[Produktname] hat eine PR-Landschaft mit [N] Stufe-1-Kanälen, [N] Stufe-2-Kanälen und [N] Stufe-3-Kanälen. Die Stufe-1-Kanäle repräsentieren bewährte Outreach-Ziele, die von 3+ Wettbewerbern genutzt werden. Die folgenden Pitch-Entwürfe sind auf jedes spezifische Ziel zugeschnitten und referenzieren entweder [Unterscheidungsmerkmal 1] oder [Unterscheidungsmerkmal 2] als primären Winkel.
---
## Stufe-1-Kanäle (Höchste Priorität)
### 1. [Kanalname] ([channel_url])
**Typ:** [redaktionell/podcast/community/newsletter]
**Häufigkeit:** [N] Wettbewerber
**Gefunden in:** [Wettbewerber A, Wettbewerber B, Wettbewerber C]
**Verwendete Story-Winkel:** [Winkel 1], [Winkel 2]
**Empfohlener Winkel:** [Empfohlener Winkel, basierend auf Produktunterscheidungsmerkmalen]
**Journalist/Host kontaktiert:** [Name] -- [Ressort]
**Nachweis:** "[Direktes Zitat aus Suchergebnissen, das Name bestätigt]"
**Pitch-Entwurf:**
---
Betreff: [Vorschlag für personalisierte Betreffzeile basierend auf Winkel + Produkt]
Hallo [Name],
[Einleitung -- Verweis auf frühere Berichterstattung über die Kategorie oder Nische. Bsp.: „Ich habe Ihre aktuelle Berichterstattung über CI/CD-Tools verfolgt, insbesondere Ihren Artikel über [Wettbewerber A] und [Winkel in seiner Geschichte]."]
[Produktbeschreibung -- was das Produkt tut und für wen. Bsp.: „Ich bin der [Rolle] von [Produktname]. Wir bauen [Einzeiler-Beschreibung]."]
[Unterscheidungsmerkmal -- eine harte Unterscheidung. Bsp.: „Im Gegensatz zu [Wettbewerber A] oder [Wettbewerber B], die [gemeinsamer Kompromiss], wir [Unterscheidungsmerkmal 1]. Das bedeutet [Vorteil für die Zielgruppe]."]
[Winkel -- verbinde Produktunterscheidungsmerkmal mit dem Story-Winkel, der in den Suchergebnissen gesehen wurde. Bsp.: „Ich denke, das passt gut zu dem [Winkel]-Stück, das Sie über [Thema] geschrieben haben, weil [spezifischer Grund]."]
[CTA -- was als Nächstes. Bsp.: „Wären Sie offen für eine kurze Demo oder ein Interview mit unserem [Rolle/CEO/CTO] nächste Woche? Ich sende Ihnen gerne weitere Details."]
Beste Grüße,
[Name]
[Rolle]
[Produktname]
[URL]
---
... (wiederhole für jeden Stufe-1-Kanal)
---
## Stufe-2-Kanäle (Mittlere Priorität)
| Kanal | URL | Typ | Häufigkeit | Gefunden in |
|---|---|---|---|---|
| [Name] | [URL] | [Typ] | 2 | [Wettbewerber] |
---
## Stufe-3-Kanäle (Niedrige Priorität)
| Kanal | URL | Typ | Häufigkeit | Gefunden in |
|---|---|---|---|---|
| [Name] | [URL] | [Typ] | 1 | [Wettbewerber] |
---
## Datenqualitätsflags
- [Alle Probleme: Beschreibung verwendet, Seitenabruf fehlgeschlagen, Wettbewerber ohne Ergebnisse usw.]
Ende des Workflows
Bestätige die Ausgabe: "Bericht generiert. Alle Kanalfrequenzen, Journalistennamen und Pitch-Winkel sind auf Suchevidenz zurückgeführt."