Anpassung FSM Pitch

This commit is contained in:
2025-07-18 08:58:39 +00:00
parent 9bfe5785e6
commit 9d227ae8da

View File

@@ -1058,76 +1058,73 @@ def verify_wiki_article_chatgpt(company_name, website, wiki_url):
def generate_fsm_pitch(company_name, company_short_name, ki_branche, website_summary, wiki_absatz, anzahl_ma, anzahl_techniker, techniker_bucket_ml):
"""
Generiert einen maßgeschneiderten, nicht-werblichen Satz, der eine operative
Service-Herausforderung des Unternehmens beschreibt (v2.1).
Service-Herausforderung des Unternehmens beschreibt (v2.2 - Final).
"""
logger = logging.getLogger(__name__)
# 1. Daten-Check: Genug Futter für einen guten Satz?
# 1. Daten-Check
beschreibung_kombiniert = []
if website_summary and 'k.a.' not in website_summary.lower():
beschreibung_kombiniert.append(f"Website-Zusammenfassung: {website_summary}")
if wiki_absatz and 'k.a.' not in wiki_absatz.lower():
beschreibung_kombiniert.append(f"Wikipedia-Einleitung: {wiki_absatz}")
final_beschreibung = "\n".join(beschreibung_kombiniert)
if not final_beschreibung or len(final_beschreibung.split()) < 10:
logger.warning(f"Zu wenige Informationen für FSM-Pitch für {company_name}. Breche ab.")
return "FEHLER (Mangelnde Daten)"
# 2. Firmennamen priorisieren: Kurzform > Langform
# 2. Firmennamen priorisieren
display_name = company_short_name if company_short_name and company_short_name.lower() != 'k.a.' else company_name
# 3. Mitarbeiter-/Techniker-Info aufbereiten und priorisieren
# 3. Personal-Info aufbereiten
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" # Default
personal_info = "Ihrer mobilen Teams" # Neuer, neutralerer Default
try:
# Priorität 1: Explizite Technikerzahl
if anzahl_techniker and int(anzahl_techniker) > 0:
anzahl_techniker = round_number(int(anzahl_techniker))
personal_info = f"bei rund {anzahl_techniker} Servicetechnikern"
# Priorität 2: ML-Techniker-Bucket (wenn keine exakte Zahl vorhanden)
personal_info = f"Ihrer {anzahl_techniker} Servicetechniker im Außendienst"
elif techniker_bucket_ml and 'k.a.' not in techniker_bucket_ml.lower() and anzahl_techniker == 0:
personal_info = f"bei schätzungsweise {techniker_bucket_ml} Servicetechnikern"
# Priorität 3: Gesamtmitarbeiterzahl
personal_info = f"Ihrer schätzungsweise {techniker_bucket_ml} Servicetechniker"
elif anzahl_ma and int(anzahl_ma) > 0:
anzahl_ma = round_number(int(anzahl_ma))
personal_info = f"bei über {anzahl_ma} Mitarbeitern"
personal_info = f"Ihrer Teams bei über {anzahl_ma} Mitarbeitern"
except (ValueError, TypeError):
logger.debug("Keine validen MA/Techniker-Zahlen für Pitch.")
# 4. Der finale, verbesserte Prompt
# 4. Der finale, stark verbesserte Prompt
prompt_parts = [
"Du bist ein B2B-Stratege, der die operativen Herausforderungen eines Unternehmens im technischen Außendienst erkennt und präzise auf den Punkt bringt.",
"Aufgabe: Formuliere EINEN EINZIGEN, flüssig lesbaren Satz (ca. 20-35 Wörter).",
"Dieser Satz muss eine spezifische, operative Service-Herausforderung des Unternehmens beschreiben, basierend auf seinen Produkten oder Dienstleistungen.",
"Aufgabe: Formuliere EINEN EINZIGEN, flüssig lesbaren Satz (ca. 20-35 Wörter), der eine spezifische, operative Service-Herausforderung beschreibt.",
"\n--- Stil-Regeln ---",
"- Formuliere als scharfsinnige Beobachtung, nicht werblich.",
"- Verwende den bereitgestellten 'Kurznamen des Unternehmens' natürlich im Satz.",
"- Verwende KEINE Anführungszeichen um den Firmennamen im finalen Satz.",
"- Vermeide generische Phrasen wie 'Schlüssel zum Erfolg'. Fokussiere auf operative Konsequenzen (z.B. 'entscheidend für die Servicequalität', 'unerlässlich für die Anlagenverfügbarkeit').",
"- Wenn die Beschreibung keine klare Service-Tätigkeit enthält, antworte NUR mit dem Wort 'FEHLER_DATEN'.",
"\n--- ABSOLUTE TOP-PRIORITÄT: STRIKTE REGELN ---",
"1. **Fokus auf Field Service:** Der Satz MUSS eine Herausforderung beschreiben, die von mobilen Teams (Techniker, Installateure, Gutachter, etc.) gelöst wird. Beschreibe NICHT die allgemeine Unternehmensstrategie, Produktion oder Produktentwicklung.",
"2. **Kein externes Wissen:** Verwende AUSSCHLIESSLICH die Informationen aus dem 'Unternehmenskontext'. Erfinde keine Fakten (wie z.B. 'jüngste Cyberangriffe').",
"3. **Vermeide Lösungs-Wörter:** Benutze NICHT unsere Lösungs-Wörter wie 'Planung', 'Disposition', 'Koordination', 'Organisation'. Fokussiere auf das Problem des Kunden (z.B. 'pünktliche Ausführung', 'schnelle Störungsbehebung').",
"4. **Keine Business-Floskeln:** Vermeide generische Phrasen. Stattdessen nenne greifbare, operative Konsequenzen.",
"5. **Daten-Check:** Wenn die Beschreibung keine klare Tätigkeit für mobile Teams enthält, antworte NUR mit dem Wort 'FEHLER_DATEN'.",
"\n--- Denkprozess (Schritt für Schritt) ---",
"1. Analysiere die Unternehmensdaten. Leite aus der Beschreibung die konkrete Tätigkeit von mobilen Teams ab (Installation, Wartung, Reparatur, Logistik, Begutachtung).",
"2. Formuliere einen Satz, der diese Tätigkeit mit der Personalinfo verbindet und als Herausforderung darstellt.",
"3. Wenn keine klare Service-Tätigkeit erkennbar ist, antworte mit 'FEHLER_DATEN'.",
"1. Analysiere die Beschreibung: Welche **konkrete Tätigkeit** wird von mobilen Mitarbeitern ausgeführt (z.B. 'Wartung von Klimaanlagen', 'Installation von Sicherheitssystemen', 'Begutachtung von Bauschäden')?",
"2. Leite daraus die **operative Konsequenz** ab, wenn diese Tätigkeit gut oder schlecht ausgeführt wird (z.B. 'Anlagenverfügbarkeit', 'Kundenzufriedenheit', 'Einhaltung von Fristen', 'Betriebssicherheit').",
"3. Formuliere den finalen Satz, der die Tätigkeit, die Personalinfo und die operative Konsequenz elegant verbindet.",
"\n--- Unternehmenskontext ---",
f"Kurzname des Unternehmens: {display_name}",
f"KI-validierte Branche: {ki_branche}",
f"Beschreibung (aus Website & Wikipedia): {final_beschreibung}",
f"Personalinfo für den Satz: {personal_info}",
f"Gesamtmitarbeiterzahl (Kontext): {anzahl_ma}",
"\n--- Beispiele für ZU VERMEIDENDEN Output-Stil ---",
"- FALSCH: '...ist die nahtlose Zusammenführung von Entwicklung und Herstellung der Schlüssel zum Erfolg.' (Fokus-Drift)",
"- FALSCH: '...ist die effiziente Einsatzplanung entscheidend.' (Lösungs-Kontamination)",
"- FALSCH: '...spielt eine entscheidende Rolle für den Markterfolg.' (Business-Floskel)",
"\n--- Beispiele für den gewünschten Output-Stil ---",
"Beispiel 1: Angesichts des beschleunigten Ausbaus der Ladeinfrastruktur bei EnBW ist die reibungslose Koordination der Installationstermine Ihrer mobilen Teams entscheidend für den Projekterfolg.",
"Beispiel 2: Bei der Wartung komplexer Produktionsanlagen für Siemens hängt die Kundenzufriedenheit direkt von der pünktlichen und effizienten Durchführung der Serviceeinsätze ab.",
"Beispiel 1 (Kontext: Wartung von Produktionsanlagen): Bei der Wartung komplexer Produktionsanlagen für Siemens hängt die Anlagenverfügbarkeit direkt von der pünktlichen und effizienten Durchführung der Serviceeinsätze ab.",
"Beispiel 2 (Kontext: Installation von Sicherheitssystemen): Angesichts der hohen Sicherheitsanforderungen im Bankensektor ist die fehlerfreie Installation von Alarmsystemen durch Ihre Servicetechniker entscheidend für die Betriebssicherheit.",
"\n--- Deine Aufgabe ---",
"Führe den Denkprozess durch und gib NUR den finalen Satz aus ODER das Wort 'FEHLER_DATEN'.",
@@ -1136,7 +1133,7 @@ def generate_fsm_pitch(company_name, company_short_name, ki_branche, website_sum
prompt = "\n".join(prompt_parts)
try:
fsm_pitch = call_openai_chat(prompt, temperature=0.6, model="gpt-4o")
fsm_pitch = call_openai_chat(prompt, temperature=0.7, 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 (Grund: Mangelnde Daten).")
return "FEHLER (Mangelnde Daten)"