From 2049c3de5c9bd5cc2dde8787366fad1b952d53b9 Mon Sep 17 00:00:00 2001 From: Floke Date: Fri, 18 Jul 2025 08:58:39 +0000 Subject: [PATCH] Anpassung FSM Pitch --- helpers.py | 59 ++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/helpers.py b/helpers.py index 4e39446d..7df116c2 100644 --- a/helpers.py +++ b/helpers.py @@ -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)"