From 6938ed611afdeea9f0f99059999181434cc21c31 Mon Sep 17 00:00:00 2001 From: Floke Date: Mon, 21 Jul 2025 12:53:40 +0000 Subject: [PATCH] The Definitive FSM Pitch (Master Prompt Implementation) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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. --- helpers.py | 88 +++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/helpers.py b/helpers.py index 9fd8544f..57a08a1a 100644 --- a/helpers.py +++ b/helpers.py @@ -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}") @@ -1062,50 +1060,58 @@ 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 (20–35 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. 20–35 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}")