The Definitive FSM Pitch (Master Prompt Implementation)

- REVERT & FINALIZE: Der FSM-Pitch-Prompt wurde auf die bewährte "Chain of Thought"-Version zurückgesetzt, die die qualitativ besten Ergebnisse liefert.
- FIX: Die Datenaufbereitung und die Anweisung zur Verwendung des Kurznamens wurden integriert, um die Zuverlässigkeit zu maximieren.
- Dies ist die finale, produktionsreife Version des FSM-Pitch-Moduls.
This commit is contained in:
2025-07-21 12:53:40 +00:00
parent 758eaf6208
commit 6938ed611a

View File

@@ -1031,25 +1031,23 @@ def generate_fsm_pitch(
techniker_bucket_ml,
):
"""
Generiert einen maßgeschneiderten, nicht-werblichen Satz, der eine operative
Service-Herausforderung des Unternehmens beschreibt (v2.3.0, basierend auf der bewährten v2.1-Logik).
Generiert einen FSM-Pitch basierend auf dem bewährten "Chain of Thought"-Master-Prompt (v2.3.2).
Liefert den qualitativ hochwertigsten, für die E-Mail-Ansprache geeigneten Satz.
"""
logger = logging.getLogger(__name__)
# 1. VERBESSERTER Daten-Check (aus v2.2.x übernommen)
# Extrahiert intelligent die reine Zusammenfassung aus dem strukturierten Analyse-Text
# 1. Datenaufbereitung (Unsere technische Verbesserung)
parts = []
if website_summary and '**GESCHÄFTSMODELL**' in website_summary:
try:
summary_text = website_summary.split('Zusammenfassung:')[1].split('**FSM-POTENZIAL**')[0].strip()
if summary_text:
parts.append(f"Website-Zusammenfassung: {summary_text}")
parts.append(f"Zusammenfassung der Website: {summary_text}")
except IndexError:
# Fallback, falls das Format unerwartet ist, aber trotzdem verwenden
if 'k.a.' not in website_summary.lower():
parts.append(f"Website-Zusammenfassung: {website_summary}")
parts.append(f"Zusammenfassung der Website: {website_summary}")
elif website_summary and 'k.a.' not in website_summary.lower():
parts.append(f"Website-Zusammenfassung: {website_summary}")
parts.append(f"Zusammenfassung der Website: {website_summary}")
if wiki_absatz and 'k.a.' not in wiki_absatz.lower():
parts.append(f"Wikipedia-Einleitung: {wiki_absatz}")
@@ -1063,49 +1061,57 @@ def generate_fsm_pitch(
# 2. Namenswahl & 3. Personalinfo (Ihre bewährte Logik)
display_name = company_short_name if company_short_name and company_short_name.lower() != 'k.a.' else company_name
def round_number(n):
if n < 100: return n
if n < 1000: return int(round(n / 50.0)) * 50
return int(round(n / 100.0)) * 100
personal_info = "in einem Unternehmen Ihrer Größe"
personal_info = ""
try:
tech = int(anzahl_techniker or 0)
ma = int(anzahl_ma or 0)
if tech > 0:
personal_info = f"bei rund {round_number(tech)} Servicetechnikern"
personal_info = f"Ihre rund {int(round(tech, -1))} Servicetechniker"
elif techniker_bucket_ml and 'k.a.' not in techniker_bucket_ml.lower():
personal_info = f"bei schätzungsweise {techniker_bucket_ml} Servicetechnikern"
elif int(anzahl_ma or 0) > 0:
personal_info = f"bei über {round_number(int(anzahl_ma))} Mitarbeitern"
except Exception:
logger.debug("Keine validen MA/Techniker-Zahlen für Pitch.")
personal_info = f"Ihre schätzungsweise {techniker_bucket_ml} Servicetechniker"
elif ma > 0:
personal_info = f"Ihre über {int(round(ma, -1))} Mitarbeiter"
except (ValueError, TypeError):
pass
# 4. Ihr bewährter Prompt
# 4. IHR MASTER-PROMPT
prompt_parts = [
"Du bist ein B2B-Stratege und Texter, der operative Service-Herausforderungen punktgenau beschreibt.",
"Aufgabe: Formuliere EINEN flüssig lesbaren Satz (2035 Wörter) zur **hochspezifischen** Service-Herausforderung.",
"",
"--- Stil-Regeln ---",
"- Nicht werblich.",
"- Nutze den Kurznamen ohne Anführungszeichen.",
"- Vermeide allgemeine Phrasen wie 'Schlüssel zum Erfolg'.",
"",
"--- Kontext ---",
f"Kurzname: {display_name}",
f"Branche: {ki_branche}",
f"Beschreibung: {combined}",
f"Personalinfo: {personal_info}",
f"Gesamtmitarbeiterzahl: {anzahl_ma}",
"",
"Bei zu allgemeiner Beschreibung → FEHLER_DATEN",
"Du bist ein B2B-Stratege, der die verborgenen operativen Herausforderungen eines Unternehmens erkennt und präzise auf den Punkt bringt.",
"Aufgabe:",
"Formuliere EINEN EINZIGEN, flüssig lesbaren Satz (ca. 2035 Wörter), der als hochpersonalisierter Einstieg in einer E-Mail dient.",
"Stil-Regeln:",
"• Absolut NICHT werblich klingen. Keine Produktnamen, keine direkten Lösungsangebote.",
"• Formuliere es als eine scharfsinnige Beobachtung über die operative Tätigkeit des Unternehmens.",
"• Der Satz muss spezifische Keywords aus der Unternehmensbeschreibung aufgreifen.",
"________________________________________",
"Denkprozess (Schritt für Schritt):",
"1. Analysiere die untenstehenden Unternehmensdaten.",
"2. Identifiziere die spezifischste genannte Dienstleistung oder das spezifischste Produkt (z. B. „Installation von Wärmepumpen“, „Wartung von Aufzügen“).",
"3. Leite daraus die konkrete operative Tätigkeit ab, die von mobilen Teams durchgeführt wird (z. B. „Installations-Termine“, „Störungsbehebungen“).",
"4. Formuliere den finalen Satz, der diese spezifische Tätigkeit und die Personalinfo elegant verbindet, idealerweise beginnend mit '[Unternehmensname] steht vor der Herausforderung...'.",
"________________________________________",
"Unternehmenskontext:",
f"• Unternehmen: {display_name}",
f"• Branche: {ki_branche}",
f"• Beschreibung:\n{combined}",
f"• Personalinfo für den Satz: {personal_info if personal_info else 'Keine Angabe'}",
"________________________________________",
"Beispiele für den gewünschten Output-Stil:",
"• Beispiel 1 (Branche „Energie“, Beschreibung „…baut Ladeinfrastruktur aus…“):",
"1KOMMA5° steht vor der Herausforderung, mit einer begrenzten Anzahl von Servicetechnikern die steigende Nachfrage nach schnellen und effizienten Installationen von integrierten Energielösungen zu bewältigen, um Kundenzufriedenheit sicherzustellen.",
"• Beispiel 2 (Branche „Anlagenbau“, Beschreibung „…Service für Produktionsanlagen…“):",
"2G Energy steht vor der Herausforderung, ihre 200 Servicetechniker effizient zu koordinieren, um die zunehmende Nachfrage nach Vor-Ort-Service und digitaler Wartung bei über 8.500 installierten Modulen weltweit zeitnah zu erfüllen.",
"________________________________________",
"Deine Aufgabe:",
"Führe den Denkprozess durch und gib NUR den finalen, perfekten Satz für das oben genannte Unternehmen aus:",
]
prompt = "\n".join(prompt_parts)
try:
fsm_pitch = call_openai_chat(prompt, temperature=0.6, model="gpt-4o")
if not fsm_pitch or "FEHLER_DATEN" in fsm_pitch:
logger.warning(f"KI konnte keinen validen FSM-Pitch für {company_name} generieren.")
return "FEHLER (Mangelnde Daten)"
if not fsm_pitch or len(fsm_pitch.split()) < 7: # Einfacher Check auf eine minimale Satzlänge
logger.warning(f"KI konnte keinen validen FSM-Pitch für {company_name} generieren (Antwort zu kurz).")
return "FEHLER (KI-Antwort unzureichend)"
return fsm_pitch.strip().replace('"', '')
except Exception as e:
logger.error(f"Fehler bei der Generierung des FSM-Pitches für {company_name}: {e}")