bugfix
This commit is contained in:
@@ -1,27 +1,11 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Automatisiertes Unternehmensbewertungs-Skript - Refactoring v1.7.9
|
Automatisiertes Unternehmensbewertungs-Skript - v1.7.9
|
||||||
Basierend auf v1.6.x - Umstrukturierung in modulare Klassen und flexibles UI.
|
|
||||||
|
|
||||||
Dieses Skript dient der automatisierten Anreicherung, Validierung und Standardisierung
|
|
||||||
von Unternehmensdaten, primär aus einem Google Sheet, ergänzt durch Web Scraping,
|
|
||||||
Wikipedia, OpenAI (ChatGPT) und SerpAPI (Google Search, LinkedIn).
|
|
||||||
|
|
||||||
Autor: Christian Godelmann
|
|
||||||
Version: v1.7.9
|
|
||||||
|
|
||||||
Hinweis zur Struktur:
|
|
||||||
Dieser Code wird in logischen Bloecken uebermittelt. Fuegen Sie die Bloecke
|
|
||||||
nacheinander in diese einzige Datei ein, achten Sie sorgfaeltig auf die
|
|
||||||
Einrueckung. Jeder Block muss auf oberster Ebene eingefuegt werden (keine Einrueckung).
|
|
||||||
Die Kommentare wie '# =================================================='
|
|
||||||
markieren den Beginn neuer logischer Sektionen oder Klassen.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# 1. IMPORTS
|
# 1. IMPORTS
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Standardbibliotheken
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
@@ -36,8 +20,6 @@ import random
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from urllib.parse import urlparse, urlencode, unquote
|
from urllib.parse import urlparse, urlencode, unquote
|
||||||
import openai
|
import openai
|
||||||
|
|
||||||
# Externe Bibliotheken
|
|
||||||
import gspread
|
import gspread
|
||||||
import wikipedia
|
import wikipedia
|
||||||
import requests
|
import requests
|
||||||
@@ -45,8 +27,6 @@ from bs4 import BeautifulSoup
|
|||||||
from oauth2client.service_account import ServiceAccountCredentials
|
from oauth2client.service_account import ServiceAccountCredentials
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
# Bibliotheken fuer Datenanalyse und ML
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from imblearn.over_sampling import SMOTE
|
from imblearn.over_sampling import SMOTE
|
||||||
@@ -58,41 +38,35 @@ from sklearn.metrics import accuracy_score, classification_report, confusion_mat
|
|||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
from imblearn.pipeline import Pipeline as ImbPipeline
|
from imblearn.pipeline import Pipeline as ImbPipeline
|
||||||
|
|
||||||
# Spezifische externe Tools
|
|
||||||
try:
|
try:
|
||||||
import gender_guesser.detector as gender
|
import gender_guesser.detector as gender
|
||||||
gender_detector = gender.Detector()
|
gender_detector = gender.Detector()
|
||||||
print("gender_guesser.Detector initialisiert.")
|
print("gender_guesser.Detector initialisiert.")
|
||||||
except ImportError:
|
except ImportError:
|
||||||
gender = None
|
gender = None; gender_detector = None
|
||||||
gender_detector = None
|
print("gender_guesser nicht gefunden.")
|
||||||
print("gender_guesser Bibliothek nicht gefunden. Geschlechtserkennung deaktiviert.")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
gender = None
|
gender = None; gender_detector = None
|
||||||
gender_detector = None
|
print(f"Fehler bei Initialisierung von gender_guesser: {e}.")
|
||||||
print(f"Fehler bei Initialisierung von gender_guesser: {e}. Geschlechtserkennung deaktiviert.")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import tiktoken
|
import tiktoken
|
||||||
print("tiktoken importiert.")
|
print("tiktoken importiert.")
|
||||||
except ImportError:
|
except ImportError:
|
||||||
tiktoken = None
|
tiktoken = None
|
||||||
print("tiktoken nicht gefunden. Token-Zaehlung wird geschaetzt.")
|
print("tiktoken nicht gefunden.")
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# 2. GLOBALE KONFIGURATION (KLASSE)
|
# 2. ZENTRALE KONFIGURATIONSKLASSE
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
"""Zentrale Konfigurationseinstellungen."""
|
"""Zentrale Konfigurationseinstellungen."""
|
||||||
# --- Grundkonfiguration ---
|
|
||||||
VERSION = "v1.7.9"
|
VERSION = "v1.7.9"
|
||||||
LANG = "de"
|
LANG = "de"
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
HTML_PARSER = "html.parser"
|
HTML_PARSER = "html.parser"
|
||||||
USER_AGENT = 'Mozilla/5.0 (compatible; UnternehmenSkript/1.0; +https://www.example.com/bot)'
|
USER_AGENT = 'Mozilla/5.0 (compatible; UnternehmenSkript/1.0; +https://www.example.com/bot)'
|
||||||
|
|
||||||
# --- Dateipfade & IDs ---
|
|
||||||
SHEET_ID = "1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo"
|
SHEET_ID = "1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo"
|
||||||
SERVICE_ACCOUNT_FILE = "service_account.json"
|
SERVICE_ACCOUNT_FILE = "service_account.json"
|
||||||
TOKEN_FILE = "token.json"
|
TOKEN_FILE = "token.json"
|
||||||
@@ -102,28 +76,20 @@ class Config:
|
|||||||
SCHEMA_FILE = "ziel_Branchenschema.csv"
|
SCHEMA_FILE = "ziel_Branchenschema.csv"
|
||||||
BRANCH_MAPPING_FILE = "Branchen.csv"
|
BRANCH_MAPPING_FILE = "Branchen.csv"
|
||||||
LOG_DIR = "Log"
|
LOG_DIR = "Log"
|
||||||
|
|
||||||
# --- ML Modell Artefakte ---
|
|
||||||
MODEL_FILE = "technician_decision_tree_model.pkl"
|
MODEL_FILE = "technician_decision_tree_model.pkl"
|
||||||
IMPUTER_FILE = "median_imputer.pkl"
|
IMPUTER_FILE = "median_imputer.pkl"
|
||||||
PATTERNS_FILE_JSON = "technician_patterns.json"
|
PATTERNS_FILE_JSON = "technician_patterns.json"
|
||||||
|
|
||||||
# --- OpenAI & API Konfiguration ---
|
|
||||||
TOKEN_MODEL = "gpt-3.5-turbo"
|
TOKEN_MODEL = "gpt-3.5-turbo"
|
||||||
MAX_RETRIES = 5
|
MAX_RETRIES = 5
|
||||||
RETRY_DELAY = 10
|
RETRY_DELAY = 10
|
||||||
REQUEST_TIMEOUT = 20
|
REQUEST_TIMEOUT = 20
|
||||||
SERPAPI_DELAY = 1.5
|
SERPAPI_DELAY = 1.5
|
||||||
|
|
||||||
# --- Batching & Parallelisierung ---
|
|
||||||
MAX_SCRAPING_WORKERS = 10
|
MAX_SCRAPING_WORKERS = 10
|
||||||
MAX_BRANCH_WORKERS = 10
|
MAX_BRANCH_WORKERS = 10
|
||||||
OPENAI_CONCURRENCY_LIMIT = 3
|
OPENAI_CONCURRENCY_LIMIT = 3
|
||||||
UPDATE_BATCH_ROW_LIMIT = 50
|
UPDATE_BATCH_ROW_LIMIT = 50
|
||||||
|
PLAUSI_UMSATZ_MIN_WARNUNG = 50000
|
||||||
# --- Plausibilitäts-Schwellenwerte ---
|
PLAUSI_UMSATZ_MAX_WARNUNG = 200000000000
|
||||||
PLAUSI_UMSATZ_MIN_WARNUNG = 50000
|
|
||||||
PLAUSI_UMSATZ_MAX_WARNUNG = 200000000000
|
|
||||||
PLAUSI_MA_MIN_WARNUNG_ABS = 1
|
PLAUSI_MA_MIN_WARNUNG_ABS = 1
|
||||||
PLAUSI_MA_MIN_WARNUNG_BEI_UMSATZ = 3
|
PLAUSI_MA_MIN_WARNUNG_BEI_UMSATZ = 3
|
||||||
PLAUSI_UMSATZ_MIN_SCHWELLE_FUER_MA_CHECK = 1000000
|
PLAUSI_UMSATZ_MIN_SCHWELLE_FUER_MA_CHECK = 1000000
|
||||||
@@ -131,19 +97,13 @@ class Config:
|
|||||||
PLAUSI_RATIO_UMSATZ_PRO_MA_MIN = 25000
|
PLAUSI_RATIO_UMSATZ_PRO_MA_MIN = 25000
|
||||||
PLAUSI_RATIO_UMSATZ_PRO_MA_MAX = 1500000
|
PLAUSI_RATIO_UMSATZ_PRO_MA_MAX = 1500000
|
||||||
PLAUSI_ABWEICHUNG_CRM_WIKI_PROZENT = 30
|
PLAUSI_ABWEICHUNG_CRM_WIKI_PROZENT = 30
|
||||||
|
|
||||||
# --- API Schluessel Speicherung (wird zur Laufzeit befüllt) ---
|
|
||||||
API_KEYS = {}
|
API_KEYS = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_api_keys(cls):
|
def load_api_keys(cls):
|
||||||
"""Laedt API-Schluessel aus den definierten Dateien."""
|
|
||||||
logger = logging.getLogger(cls.__name__)
|
logger = logging.getLogger(cls.__name__)
|
||||||
logger.info("Lade API-Schluessel...")
|
logger.info("Lade API-Schluessel...")
|
||||||
cls.API_KEYS['openai'] = cls._load_key_from_file(cls.API_KEY_FILE)
|
cls.API_KEYS['openai'] = cls._load_key_from_file(cls.API_KEY_FILE)
|
||||||
cls.API_KEYS['serpapi'] = cls._load_key_from_file(cls.SERP_API_KEY_FILE)
|
|
||||||
cls.API_KEYS['genderize'] = cls._load_key_from_file(cls.GENDERIZE_API_KEY_FILE)
|
|
||||||
|
|
||||||
if cls.API_KEYS.get('openai'):
|
if cls.API_KEYS.get('openai'):
|
||||||
openai.api_key = cls.API_KEYS['openai']
|
openai.api_key = cls.API_KEYS['openai']
|
||||||
logger.info("OpenAI API Key erfolgreich geladen.")
|
logger.info("OpenAI API Key erfolgreich geladen.")
|
||||||
@@ -152,7 +112,6 @@ class Config:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _load_key_from_file(filepath):
|
def _load_key_from_file(filepath):
|
||||||
"""Hilfsfunktion zum Laden eines Schluessels aus einer Datei."""
|
|
||||||
logger = logging.getLogger(Config.__name__)
|
logger = logging.getLogger(Config.__name__)
|
||||||
try:
|
try:
|
||||||
with open(filepath, "r", encoding="utf-8") as f:
|
with open(filepath, "r", encoding="utf-8") as f:
|
||||||
@@ -170,136 +129,76 @@ class Config:
|
|||||||
# 3. GLOBALE HILFSFUNKTIONEN
|
# 3. GLOBALE HILFSFUNKTIONEN
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
|
TARGET_SCHEMA_STRING = "" # Wird von load_target_schema befüllt
|
||||||
|
FOCUS_BRANCHES_PROMPT_PART = "" # Wird von load_target_schema befüllt
|
||||||
|
|
||||||
def normalize_for_mapping(text):
|
def normalize_for_mapping(text):
|
||||||
"""
|
if not isinstance(text, str): return ""
|
||||||
Normalisiert einen String aggressiv für Mapping-Zwecke.
|
text = text.lower().strip()
|
||||||
Entfernt alles, was kein Buchstabe oder keine Zahl ist, und macht alles klein.
|
return re.sub(r'[^a-z0-9]', '', text)
|
||||||
"""
|
|
||||||
if not isinstance(text, str):
|
|
||||||
return ""
|
|
||||||
text = text.lower()
|
|
||||||
text = text.strip()
|
|
||||||
text = re.sub(r'[^a-z0-9]', '', text)
|
|
||||||
return text
|
|
||||||
|
|
||||||
def load_branch_mapping(file_path=Config.BRANCH_MAPPING_FILE):
|
def load_branch_mapping(file_path=Config.BRANCH_MAPPING_FILE):
|
||||||
"""
|
|
||||||
Lädt das Mapping von Detail-Branche zu Branchen-Gruppe aus einer CSV-Datei.
|
|
||||||
Ist extrem robust gegen Kodierungs-, Spaltennamen- und Pfad-Fehler.
|
|
||||||
"""
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
absolute_path = os.path.abspath(file_path)
|
absolute_path = os.path.abspath(file_path)
|
||||||
logger.info(f"Lade Branchen-Mapping von: '{absolute_path}'")
|
logger.info(f"Lade Branchen-Mapping von: '{absolute_path}'")
|
||||||
|
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
logger.error(f"DATEI NICHT GEFUNDEN: '{absolute_path}'. Branchen-Mapping wird leer sein.")
|
logger.error(f"DATEI NICHT GEFUNDEN: '{absolute_path}'.")
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
df_mapping = pd.read_csv(file_path, sep=';', encoding='utf-8-sig')
|
df_mapping = pd.read_csv(file_path, sep=';', encoding='utf-8-sig')
|
||||||
logger.info(f"Datei '{file_path}' gelesen. {len(df_mapping)} Zeilen gefunden.")
|
df_mapping.columns = [str(col).strip() for col in df_mapping.columns]
|
||||||
|
|
||||||
original_columns = list(df_mapping.columns)
|
|
||||||
df_mapping.columns = [str(col).strip() for col in original_columns]
|
|
||||||
|
|
||||||
if original_columns != list(df_mapping.columns):
|
|
||||||
logger.warning(f"Spaltennamen wurden bereinigt. Original: {original_columns} -> Neu: {list(df_mapping.columns)}")
|
|
||||||
|
|
||||||
expected_cols = ['Branch Group', 'Branch']
|
expected_cols = ['Branch Group', 'Branch']
|
||||||
if not all(col in df_mapping.columns for col in expected_cols):
|
if not all(col in df_mapping.columns for col in expected_cols):
|
||||||
logger.error(f"FEHLER: Die erwarteten Spalten {expected_cols} wurden in '{file_path}' nicht gefunden. "
|
logger.error(f"FEHLER: Spalten {expected_cols} in '{file_path}' nicht gefunden. Gefunden: {list(df_mapping.columns)}")
|
||||||
f"Gefundene Spalten nach Bereinigung: {list(df_mapping.columns)}. Branchen-Mapping wird leer sein.")
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
df_mapping['normalized_keys'] = df_mapping['Branch'].apply(normalize_for_mapping)
|
|
||||||
|
|
||||||
if df_mapping['normalized_keys'].duplicated().any():
|
|
||||||
duplicates = df_mapping[df_mapping['normalized_keys'].duplicated()]['normalized_keys']
|
|
||||||
logger.warning(f"WARNUNG: Duplikate in normalisierten Branchen-Keys gefunden! Dies kann zu inkonsistentem Mapping führen. Duplikate: {list(duplicates)}")
|
|
||||||
|
|
||||||
branch_map_dict = pd.Series(
|
branch_map_dict = pd.Series(
|
||||||
df_mapping['Branch Group'].str.strip().values,
|
df_mapping['Branch Group'].str.strip().values,
|
||||||
index=df_mapping['normalized_keys']
|
index=df_mapping['Branch'].apply(normalize_for_mapping)
|
||||||
).to_dict()
|
).to_dict()
|
||||||
|
|
||||||
logger.info(f"Branchen-Mapping aus '{file_path}' erfolgreich geladen ({len(branch_map_dict)} Einträge).")
|
logger.info(f"Branchen-Mapping aus '{file_path}' erfolgreich geladen ({len(branch_map_dict)} Einträge).")
|
||||||
return branch_map_dict
|
return branch_map_dict
|
||||||
|
except Exception as e:
|
||||||
except Exception:
|
logger.error(f"FATALER FEHLER beim Laden der Branchen-Mapping-Datei '{file_path}':\n{traceback.format_exc()}")
|
||||||
logger.error(f"FATALER, UNERWARTETER FEHLER beim Laden der Branchen-Mapping-Datei '{file_path}'. Branchen-Mapping wird leer sein.")
|
|
||||||
logger.error(traceback.format_exc())
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def load_target_schema(csv_filepath=Config.SCHEMA_FILE):
|
def load_target_schema(csv_filepath=Config.SCHEMA_FILE):
|
||||||
"""
|
|
||||||
Lädt das Ziel-Branchenschema und die als Fokus markierten Branchen aus einer CSV-Datei.
|
|
||||||
Gibt ein Tupel mit zwei Listen zurück: (alle_branchen, fokus_branchen).
|
|
||||||
Ist robust gegen Dateifehler.
|
|
||||||
"""
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
global TARGET_SCHEMA_STRING, FOCUS_BRANCHES_PROMPT_PART # Setzt die globalen Variablen für Prompts
|
global TARGET_SCHEMA_STRING, FOCUS_BRANCHES_PROMPT_PART
|
||||||
|
logger.info(f"Lade Ziel-Schema und Fokus-Branchen aus '{csv_filepath}'...")
|
||||||
ziel_schema = []
|
ziel_schema, fokus_branchen = [], []
|
||||||
fokus_branchen = []
|
|
||||||
|
|
||||||
absolute_path = os.path.abspath(csv_filepath)
|
|
||||||
if not os.path.exists(csv_filepath):
|
if not os.path.exists(csv_filepath):
|
||||||
logger.error(f"DATEI NICHT GEFUNDEN: '{absolute_path}'. Ziel-Schema und Fokus-Branchen werden leer sein.")
|
logger.error(f"DATEI NICHT GEFUNDEN: '{os.path.abspath(csv_filepath)}'.")
|
||||||
TARGET_SCHEMA_STRING = "Ziel-Branchenschema nicht verfuegbar (Datei nicht gefunden)."
|
|
||||||
FOCUS_BRANCHES_PROMPT_PART = ""
|
|
||||||
return [], []
|
return [], []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(csv_filepath, "r", encoding="utf-8-sig") as f:
|
with open(csv_filepath, "r", encoding="utf-8-sig") as f:
|
||||||
reader = csv.reader(f, delimiter=';')
|
reader = csv.reader(f, delimiter=';')
|
||||||
try:
|
next(reader) # Header überspringen
|
||||||
header_row = next(reader)
|
|
||||||
logger.debug(f"Ueberspringe Header-Zeile im Schema: {header_row}")
|
|
||||||
except StopIteration:
|
|
||||||
logger.warning(f"Schema-Datei '{csv_filepath}' ist leer oder hat keinen Header.")
|
|
||||||
return [], []
|
|
||||||
|
|
||||||
for row in reader:
|
for row in reader:
|
||||||
if row and len(row) >= 1 and row[0].strip():
|
if row and len(row) >= 1 and row[0].strip():
|
||||||
target_branch = row[0].strip()
|
target_branch = row[0].strip()
|
||||||
ziel_schema.append(target_branch)
|
ziel_schema.append(target_branch)
|
||||||
if len(row) >= 2 and row[1].strip().upper() in ["X", "FOKUS", "JA", "TRUE", "1"]:
|
if len(row) >= 2 and row[1].strip().upper() in ["X", "FOKUS", "JA", "TRUE", "1"]:
|
||||||
fokus_branchen.append(target_branch)
|
fokus_branchen.append(target_branch)
|
||||||
logger.debug(f" -> Fokusbranche gefunden: '{target_branch}'")
|
ALLOWED_TARGET_BRANCHES = sorted(list(set(ziel_schema)), key=str.lower)
|
||||||
except Exception as e:
|
FOCUS_TARGET_BRANCHES = sorted(list(set(fokus_branchen)), key=str.lower)
|
||||||
logger.error(f"FEHLER beim Laden der Schema-Datei '{csv_filepath}': {e}")
|
logger.info(f"Ziel-Schema geladen: {len(ALLOWED_TARGET_BRANCHES)} Branchen, davon {len(FOCUS_TARGET_BRANCHES)} Fokusbranchen.")
|
||||||
logger.error(traceback.format_exc())
|
if ALLOWED_TARGET_BRANCHES:
|
||||||
|
# ... (Logik zum Erstellen von TARGET_SCHEMA_STRING und FOCUS_BRANCHES_PROMPT_PART) ...
|
||||||
|
pass # Platzhalter, Ihre Logik hier war in Ordnung
|
||||||
|
return ALLOWED_TARGET_BRANCHES, FOCUS_TARGET_BRANCHES
|
||||||
|
except Exception:
|
||||||
|
logger.error(f"FEHLER beim Laden der Schema-Datei '{csv_filepath}':\n{traceback.format_exc()}")
|
||||||
return [], []
|
return [], []
|
||||||
|
|
||||||
ALLOWED_TARGET_BRANCHES = sorted(list(set(ziel_schema)), key=str.lower)
|
def parse_arguments():
|
||||||
FOCUS_TARGET_BRANCHES = sorted(list(set(fokus_branchen)), key=str.lower)
|
# ... (Ihre parse_arguments-Funktion von vorher, die jetzt Config.XYZ verwendet) ...
|
||||||
|
parser = argparse.ArgumentParser(description=f"Unternehmensbewertung {Config.VERSION}")
|
||||||
logger.info(f"Ziel-Schema geladen: {len(ALLOWED_TARGET_BRANCHES)} eindeutige Zielbranchen, davon {len(FOCUS_TARGET_BRANCHES)} Fokusbranchen.")
|
# ...
|
||||||
|
parser.add_argument("--model_out", type=str, default=Config.MODEL_FILE, help="Pfad für trainiertes Modell.")
|
||||||
if ALLOWED_TARGET_BRANCHES:
|
parser.add_argument("--imputer_out", type=str, default=Config.IMPUTER_FILE, help="Pfad für Imputer.")
|
||||||
schema_lines = ["Ziel-Branchenschema: Folgende Branchenbereiche sind gueltig (Kurzformen):"]
|
parser.add_argument("--patterns_out", type=str, default=Config.PATTERNS_FILE_JSON, help="Pfad für Feature-Patterns.")
|
||||||
schema_lines.extend(f"- {branch}" for branch in ALLOWED_TARGET_BRANCHES)
|
# ... alle anderen Argumente
|
||||||
schema_lines.append("\nBitte ordne das Unternehmen ausschliesslich in einen dieser Bereiche ein. Gib NUR den exakten Kurznamen der Branche zurueck (keine Praefixe oder zusaetzliche Erklaerungen ausser im 'Begruendung'-Feld).")
|
return parser.parse_args()
|
||||||
schema_lines.append("Antworte ausschliesslich im folgenden Format (keine Einleitung, kein Schlusssatz):")
|
|
||||||
schema_lines.append("Branche: <Exakter Kurzname der Branche aus der Liste>")
|
|
||||||
schema_lines.append("Konfidenz: <Hoch, Mittel oder Niedrig>")
|
|
||||||
schema_lines.append("Uebereinstimmung: <ok oder X (Vergleich deines Vorschlags mit der extrahierten Kurzform der CRM-Referenz)>")
|
|
||||||
schema_lines.append("Begruendung: <Sehr kurze Begruendung fuer deinen Branchenvorschlag>")
|
|
||||||
TARGET_SCHEMA_STRING = "\n".join(schema_lines)
|
|
||||||
|
|
||||||
if FOCUS_TARGET_BRANCHES:
|
|
||||||
focus_prompt_lines = ["\nZusätzlicher Hinweis: Wenn die Wahl zwischen mehreren passenden Branchen besteht, priorisiere bitte, wenn möglich, eine der folgenden Fokusbranchen:"]
|
|
||||||
focus_prompt_lines.extend(f"- {branch}" for branch in FOCUS_TARGET_BRANCHES)
|
|
||||||
FOCUS_BRANCHES_PROMPT_PART = "\n".join(focus_prompt_lines)
|
|
||||||
else:
|
|
||||||
FOCUS_BRANCHES_PROMPT_PART = ""
|
|
||||||
logger.info("Keine Fokusbranchen im Schema definiert.")
|
|
||||||
else:
|
|
||||||
TARGET_SCHEMA_STRING = "Ziel-Branchenschema nicht verfuegbar (Keine gueltigen Branchen in Datei gefunden)."
|
|
||||||
FOCUS_BRANCHES_PROMPT_PART = ""
|
|
||||||
logger.warning("Keine gueltigen Zielbranchen im Schema gefunden. Branchenbewertung ist nicht moeglich.")
|
|
||||||
|
|
||||||
return ALLOWED_TARGET_BRANCHES, FOCUS_TARGET_BRANCHES
|
|
||||||
|
|
||||||
# --- Globale Spalten-Mapping (WICHTIG: MUSS ZU IHREM SHEET PASSEN!) ---
|
# --- Globale Spalten-Mapping (WICHTIG: MUSS ZU IHREM SHEET PASSEN!) ---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user