From 32dcf0cc77e90a5769479a5d86759f99816ca042 Mon Sep 17 00:00:00 2001 From: Floke Date: Fri, 18 Jul 2025 09:10:32 +0000 Subject: [PATCH] =?UTF-8?q?die=20neue=20Version=20hat=20zu=20viele=20Fehle?= =?UTF-8?q?r,=20wieder=20einf=C3=BCgen=20der=20vorherigen=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helpers.py | 59 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/helpers.py b/helpers.py index 7df116c2..4e39446d 100644 --- a/helpers.py +++ b/helpers.py @@ -1058,73 +1058,76 @@ 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.2 - Final). + Service-Herausforderung des Unternehmens beschreibt (v2.1). """ logger = logging.getLogger(__name__) - # 1. Daten-Check + # 1. Daten-Check: Genug Futter für einen guten Satz? 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 + # 2. Firmennamen priorisieren: Kurzform > Langform display_name = company_short_name if company_short_name and company_short_name.lower() != 'k.a.' else company_name - # 3. Personal-Info aufbereiten + # 3. Mitarbeiter-/Techniker-Info aufbereiten und priorisieren 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 = "Ihrer mobilen Teams" # Neuer, neutralerer Default + + personal_info = "in einem Unternehmen Ihrer Größe" # 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"Ihrer {anzahl_techniker} Servicetechniker im Außendienst" + personal_info = f"bei rund {anzahl_techniker} Servicetechnikern" + # Priorität 2: ML-Techniker-Bucket (wenn keine exakte Zahl vorhanden) elif techniker_bucket_ml and 'k.a.' not in techniker_bucket_ml.lower() and anzahl_techniker == 0: - personal_info = f"Ihrer schätzungsweise {techniker_bucket_ml} Servicetechniker" + personal_info = f"bei schätzungsweise {techniker_bucket_ml} Servicetechnikern" + # Priorität 3: Gesamtmitarbeiterzahl elif anzahl_ma and int(anzahl_ma) > 0: anzahl_ma = round_number(int(anzahl_ma)) - personal_info = f"Ihrer Teams bei über {anzahl_ma} Mitarbeitern" + personal_info = f"bei über {anzahl_ma} Mitarbeitern" except (ValueError, TypeError): logger.debug("Keine validen MA/Techniker-Zahlen für Pitch.") - - # 4. Der finale, stark verbesserte Prompt + + # 4. Der finale, 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), der eine spezifische, operative Service-Herausforderung beschreibt.", + "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.", - "\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--- 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--- Denkprozess (Schritt für Schritt) ---", - "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.", + "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'.", "\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}", - - "\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)", + f"Gesamtmitarbeiterzahl (Kontext): {anzahl_ma}", "\n--- Beispiele für den gewünschten Output-Stil ---", - "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.", + "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.", "\n--- Deine Aufgabe ---", "Führe den Denkprozess durch und gib NUR den finalen Satz aus ODER das Wort 'FEHLER_DATEN'.", @@ -1133,7 +1136,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.7, model="gpt-4o") + 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 (Grund: Mangelnde Daten).") return "FEHLER (Mangelnde Daten)"