From 45abafcb10b3702ef1ac8876ee0b0ded8535c15c Mon Sep 17 00:00:00 2001 From: Floke Date: Tue, 1 Jul 2025 14:51:57 +0000 Subject: [PATCH] STABLE - Objektorientiertes Schema-Handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MAJOR REFACTOR: Globale Variablen für Branchenschema komplett entfernt. Das Schema wird nun in der `DataProcessor`-Instanz gehalten und als Argument übergeben. - FIX: Kritischer Prompt-Fehler endgültig behoben. `evaluate_branche_chatgpt` erhält das Schema nun als explizites Argument, was Scope-Probleme beseitigt. - Das Projekt ist nun in einem stabilen, logisch konsistenten und lauffähigen Zustand für die Bestandsanreicherung. --- helpers.py | 59 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/helpers.py b/helpers.py index cfd3f5fa..a5cc3758 100644 --- a/helpers.py +++ b/helpers.py @@ -674,35 +674,42 @@ def get_email_address(firstname, lastname, website): def initialize_target_schema(): """ - Initialisiert das Ziel-Branchenschema dynamisch aus dem - BRANCH_GROUP_MAPPING in config.py. + Initialisiert das Ziel-Branchenschema aus der Config und gibt es als Dictionary zurück. + Setzt KEINE globalen Variablen mehr. """ logger = logging.getLogger(__name__) - from config import Config, TARGET_SCHEMA_STRING, ALLOWED_TARGET_BRANCHES, FOCUS_BRANCHES_PROMPT_PART + from config import Config - logger.info("Initialisiere Ziel-Schema aus Config.BRANCH_GROUP_MAPPING...") + logger.info("Lade Ziel-Schema aus Config.BRANCH_GROUP_MAPPING...") - if not Config.BRANCH_GROUP_MAPPING or not isinstance(Config.BRANCH_GROUP_MAPPING, dict): + if not hasattr(Config, 'BRANCH_GROUP_MAPPING') or not isinstance(Config.BRANCH_GROUP_MAPPING, dict): logger.critical("FEHLER: Config.BRANCH_GROUP_MAPPING ist nicht vorhanden oder kein Dictionary.") - globals()['ALLOWED_TARGET_BRANCHES'] = [] - return False + return None - # Die erlaubten Branchen sind direkt die Schlüssel des Mappings - allowed_branches = list(Config.BRANCH_GROUP_MAPPING.keys()) + allowed_branches = sorted(list(Config.BRANCH_GROUP_MAPPING.keys()), key=str.lower) + if not allowed_branches: + logger.error("Keine Branchen im BRANCH_GROUP_MAPPING in der Config gefunden.") + return None + + # Baue den Prompt-String zusammen + schema_lines = ["Ziel-Branchenschema: Folgende Branchenbereiche sind gueltig (Kurzformen):"] + schema_lines.extend(f"- {branch}" for branch in allowed_branches) + schema_lines.append("\nBitte ordne das Unternehmen ausschliesslich in einen dieser Bereiche ein.") + schema_lines.append("Antworte ausschliesslich im folgenden Format (keine Einleitung, kein Schlusssatz):") + schema_lines.append("Branche: ") + schema_lines.append("Konfidenz: ") + schema_lines.append("Begruendung: ") + + schema_string = "\n".join(schema_lines) - globals()['ALLOWED_TARGET_BRANCHES'] = sorted(allowed_branches, key=str.lower) - globals()['FOCUS_TARGET_BRANCHES'] = [] # Fokus wird derzeit nicht unterstützt - logger.info(f"Ziel-Schema initialisiert: {len(allowed_branches)} eindeutige Zielbranchen gefunden.") - schema_lines = ["Ziel-Branchenschema: Folgende Branchenbereiche sind gueltig (Kurzformen):"] - schema_lines.extend(f"- {branch}" for branch in ALLOWED_TARGET_BRANCHES) - schema_lines.append("\nBitte ordne das Unternehmen ausschliesslich in einen dieser Bereiche ein...") - # (Der Rest des Prompt-Strings bleibt gleich) - globals()['TARGET_SCHEMA_STRING'] = "\n".join(schema_lines) - globals()['FOCUS_BRANCHES_PROMPT_PART'] = "" - - return True + # Gib ein sauberes Dictionary zurück + return { + "allowed_branches": allowed_branches, + "schema_prompt_string": schema_string + } + # ============================================================================== # 8. OPENAI API WRAPPERS (CHAT & SUMMARY) # ============================================================================== @@ -945,16 +952,20 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg suggested_branch = line.split(":", 1)[1].strip().strip('"\'') break if not suggested_branch and lines: - suggested_branch = lines[0].strip().split(":", 1)[-1].strip().strip('"\'') + # Fallback: Extrahiere Text nach Doppelpunkt, wenn einer da ist, sonst nimm die ganze Zeile + if ":" in lines[0]: + suggested_branch = lines[0].split(":", 1)[1].strip().strip('"\'') + else: + suggested_branch = lines[0].strip() + logger.warning(f"Konnte 'Branche:' nicht finden. Interpretiere erste Zeile als Vorschlag: '{suggested_branch}'") - # Extrahiere Konfidenz und Begründung for line in lines: if line.lower().startswith("konfidenz:"): result["confidence"] = line.split(":", 1)[1].strip() elif line.lower().startswith("begruendung:"): result["justification"] = line.split(":", 1)[1].strip() if not suggested_branch: - logger.error(f"Fehler: Konnte keine Branche aus Antwort parsen: {chat_response[:200]}") - return {"branch": "FEHLER PARSING", "confidence": "N/A", "consistency": "error_parsing", "justification": f"Antwortformat unerwartet: {chat_response[:100]}"} + logger.error(f"Fehler: Konnte keine Branche aus der Antwort extrahieren: {chat_response[:200]}") + return {"branch": "FEHLER PARSING", "confidence": "N/A", "consistency": "error_parsing", "justification": f"Antwort leer oder unklar: {chat_response[:100]}"} # Validierung und intelligenter Fallback final_branch = None