bugfix
This commit is contained in:
@@ -389,38 +389,43 @@ def is_valid_company_article(wiki_categories):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def load_target_schema_string(csv_filepath="ziel_Branchenschema.csv"):
|
def load_target_schema(csv_filepath="ziel_Branchenschema.csv"):
|
||||||
"""
|
"""
|
||||||
Liest das Ziel-Branchenschema aus der CSV-Datei ein.
|
Liest das Ziel-Branchenschema aus der CSV-Datei ein.
|
||||||
Die CSV-Datei sollte in Spalte A den externen (Wikipedia-)Branchenbegriff
|
Die CSV-Datei sollte in Spalte A den externen (Wikipedia-)Branchenbegriff
|
||||||
und in Spalte B den zugehörigen Zielwert enthalten.
|
und in Spalte B den zugehörigen Zielwert enthalten.
|
||||||
Es werden alle eindeutigen Zielwerte gesammelt und als Aufzählung zurückgegeben.
|
|
||||||
|
Returns:
|
||||||
|
mapping (dict): Ein Dictionary, das externe Branchenbegriffe (lowercase) auf
|
||||||
|
die zugehörigen Zielwerte (lowercase) abbildet.
|
||||||
|
schema_string (str): Eine formattierte Zeichenkette als Aufzählung der gültigen
|
||||||
|
Zielbranchen, die im Prompt übergeben werden kann.
|
||||||
|
allowed_targets (list): Eine sortierte Liste der eindeutigen Zielwerte.
|
||||||
"""
|
"""
|
||||||
import csv
|
import csv
|
||||||
|
mapping = {}
|
||||||
valid_targets = set()
|
valid_targets = set()
|
||||||
try:
|
try:
|
||||||
with open(csv_filepath, encoding="utf-8") as f:
|
with open(csv_filepath, encoding="utf-8") as f:
|
||||||
reader = csv.reader(f)
|
reader = csv.reader(f, delimiter=";")
|
||||||
for row in reader:
|
for row in reader:
|
||||||
# Wir erwarten mindestens zwei Spalten: Externer Begriff und Zielwert
|
|
||||||
if len(row) >= 2:
|
if len(row) >= 2:
|
||||||
target = row[1].strip()
|
external = row[0].strip().lower()
|
||||||
|
target = row[1].strip().lower()
|
||||||
if target:
|
if target:
|
||||||
|
mapping[external] = target
|
||||||
valid_targets.add(target)
|
valid_targets.add(target)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
debug_print("Fehler beim Einlesen des Ziel-Branchenschemas: " + str(e))
|
debug_print("Fehler beim Einlesen des Ziel-Branchenschemas: " + str(e))
|
||||||
return "Ziel-Branchenschema nicht verfügbar."
|
return {}, "Ziel-Branchenschema nicht verfügbar.", []
|
||||||
|
|
||||||
if valid_targets:
|
sorted_targets = sorted(valid_targets, key=lambda s: s.lower())
|
||||||
# Wir können die Zielwerte sortieren, um immer dieselbe Reihenfolge zu gewährleisten.
|
schema_string = (
|
||||||
sorted_targets = sorted(valid_targets, key=lambda s: s.lower())
|
"Ziel-Branchenschema: Folgende Branchenbereiche sind gültig:\n" +
|
||||||
return (
|
"\n".join(f"- {value}" for value in sorted_targets) +
|
||||||
"Ziel-Branchenschema: Folgende Branchenbereiche sind gültig:\n" +
|
"\nBitte ordne das Unternehmen ausschließlich in einen dieser Bereiche ein."
|
||||||
"\n".join(f"- {value}" for value in sorted_targets) +
|
)
|
||||||
"\nBitte ordne das Unternehmen ausschließlich in einen dieser Bereiche ein."
|
return mapping, schema_string, sorted_targets
|
||||||
)
|
|
||||||
else:
|
|
||||||
return "Ziel-Branchenschema nicht verfügbar."
|
|
||||||
|
|
||||||
def serp_website_lookup(company_name):
|
def serp_website_lookup(company_name):
|
||||||
"""
|
"""
|
||||||
@@ -1533,47 +1538,55 @@ class WikipediaScraper:
|
|||||||
# ==================== NEUE FUNKTION: Angepasste evaluate_branche_chatgpt ====================
|
# ==================== NEUE FUNKTION: Angepasste evaluate_branche_chatgpt ====================
|
||||||
def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kategorien, website_summary):
|
def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kategorien, website_summary):
|
||||||
"""
|
"""
|
||||||
Ordnet das Unternehmen anhand externer Quellen und interner Daten exakt einer Branche
|
Ordnet das Unternehmen basierend auf den angegebenen Informationen exakt einer Branche
|
||||||
des Ziel-Branchenschemas zu.
|
des in der CSV-Datei hinterlegten Ziel-Branchenschemas zu.
|
||||||
|
|
||||||
Vorgehen:
|
Der System-Prompt enthält nun den erlaubten Branchenbereich, und der von ChatGPT gegebene Vorschlag
|
||||||
1. Es wird ein aggregierter Prompt mit den Angaben (CRM-Branche, Beschreibung, Wikipedia-Branche,
|
wird bereinigt und gegen die Einträge des Ziel-Schemas validiert.
|
||||||
Wikipedia-Kategorien, Website-Zusammenfassung) erstellt und an ChatGPT geschickt.
|
|
||||||
2. Zusätzlich wird das gültige Ziel-Branchenschema (als Übersicht) dem Prompt angehängt.
|
Falls der Vorschlag nicht validiert werden kann, erfolgt ein Fallback auf den CRM-Wert.
|
||||||
3. Der von ChatGPT zurückgegebene externe Branchenvorschlag wird geparst, normalisiert und
|
|
||||||
mittels map_external_branch() in den standardisierten Zielwert überführt.
|
Args:
|
||||||
4. Falls erforderlich, wird der CRM-Präfix ergänzt.
|
crm_branche (str): Branche laut CRM
|
||||||
5. Falls kein sinnvoller externer Vorschlag vorliegt, erfolgt der Fallback auf den CRM-Wert.
|
beschreibung (str): Unternehmensbeschreibung (CRM)
|
||||||
|
wiki_branche (str): Branche aus Wikipedia (falls vorhanden)
|
||||||
|
wiki_kategorien (str): Wikipedia-Kategorien
|
||||||
|
website_summary (str): Zusammenfassung des Website-Inhalts
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Enthält "branch", "consistency" (ok oder X) und "justification".
|
||||||
"""
|
"""
|
||||||
debug_print(
|
# Lade Mapping und Liste der erlaubten Ziel-Branchen
|
||||||
f"Verwendete Angaben: CRM-Branche='{crm_branche}', externe Beschreibung='{beschreibung}', "
|
mapping, allowed_branches = load_target_branches()
|
||||||
f"Wiki-Branche='{wiki_branche}', Wiki-Kategorien='{wiki_kategorien}', Website-Zusammenfassung='{website_summary}'"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Hier definieren wir das Ziel-Branchenschema als Text, der ChatGPT als Grundlage dienen soll.
|
# Baue den Text für das Ziel-Branchenschema, der im System-Prompt an ChatGPT übergeben wird
|
||||||
target_schema_info = load_target_schema_string()
|
schema_lines = ["Ziel-Branchenschema: Folgende Branchenbereiche sind gültig:"]
|
||||||
|
for branch in allowed_branches:
|
||||||
|
schema_lines.append(f"- {branch}")
|
||||||
|
target_schema_info = "\n".join(schema_lines)
|
||||||
|
|
||||||
prompt = (
|
# Erstelle den System-Prompt inklusive der Zielvorgaben
|
||||||
f"Ordne das Unternehmen anhand folgender Angaben exakt einer Branche des Ziel-Branchenschemas zu:\n"
|
target_mapping, target_schema_string, allowed_targets = load_target_schema()
|
||||||
f"CRM-Branche: {crm_branche}\n"
|
|
||||||
f"Beschreibung: {beschreibung}\n"
|
|
||||||
f"Wikipedia-Branche: {wiki_branche}\n"
|
|
||||||
f"Wikipedia-Kategorien: {wiki_kategorien}\n"
|
|
||||||
f"Website-Zusammenfassung: {website_summary}\n\n"
|
|
||||||
f"{target_schema_info}\n\n"
|
|
||||||
"Antworte im Format:\n"
|
|
||||||
"Branche: <vorgeschlagene Branche>\n"
|
|
||||||
"Übereinstimmung: <ok oder X>\n"
|
|
||||||
"Begründung: <kurze Begründung>"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
prompt = (
|
||||||
|
f"{target_schema_string}\n\n"
|
||||||
|
f"Ordne das Unternehmen anhand folgender Angaben exakt einer Branche des Ziel-Branchenschemas zu:\n"
|
||||||
|
f"CRM-Branche: {crm_branche}\n"
|
||||||
|
f"Beschreibung: {beschreibung}\n"
|
||||||
|
f"Wikipedia-Branche: {wiki_branche}\n"
|
||||||
|
f"Wikipedia-Kategorien: {wiki_kategorien}\n"
|
||||||
|
f"Website-Zusammenfassung: {website_summary}\n\n"
|
||||||
|
"Antworte im Format:\n"
|
||||||
|
"Branche: <vorgeschlagene Branche>\n"
|
||||||
|
"Übereinstimmung: <ok oder X>\n"
|
||||||
|
"Begründung: <kurze Begründung>"
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
with open("api_key.txt", "r") as f:
|
with open("api_key.txt", "r") as f:
|
||||||
api_key = f.read().strip()
|
api_key = f.read().strip()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
debug_print("Fehler beim Lesen des API-Tokens: " + str(e))
|
debug_print(f"Fehler beim Lesen des API-Tokens für Brancheneinschätzung: {e}")
|
||||||
return {"branch": "k.A.", "consistency": "X", "justification": "Kein API-Key gefunden."}
|
return {"branch": crm_branche, "consistency": "X", "justification": "API-Key Fehler"}
|
||||||
|
|
||||||
openai.api_key = api_key
|
openai.api_key = api_key
|
||||||
try:
|
try:
|
||||||
response = openai.ChatCompletion.create(
|
response = openai.ChatCompletion.create(
|
||||||
@@ -1581,44 +1594,49 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
|||||||
messages=[{"role": "user", "content": prompt}],
|
messages=[{"role": "user", "content": prompt}],
|
||||||
temperature=0.0
|
temperature=0.0
|
||||||
)
|
)
|
||||||
chat_output = response.choices[0].message.content.strip()
|
chat_response = response.choices[0].message.content.strip()
|
||||||
debug_print(f"Branchenabgleich ChatGPT Antwort: '{chat_output}'")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
debug_print("Fehler bei der ChatGPT-Anfrage: " + str(e))
|
debug_print(f"Fehler bei der ChatGPT-Anfrage für Brancheneinschätzung: {e}")
|
||||||
return {"branch": "k.A.", "consistency": "X", "justification": "ChatGPT-Anfrage fehlgeschlagen."}
|
return {"branch": crm_branche, "consistency": "X", "justification": "API-Anfrage Fehler"}
|
||||||
|
|
||||||
# Parsen der Antwort von ChatGPT
|
# Erwarte ein Format:
|
||||||
suggested_branch = ""
|
# Branche: <vorgeschlagene Branche>
|
||||||
|
# Übereinstimmung: <ok oder X>
|
||||||
|
# Begründung: <kurze Begründung>
|
||||||
|
lines = chat_response.split("\n")
|
||||||
|
suggestion = ""
|
||||||
consistency = ""
|
consistency = ""
|
||||||
justification = ""
|
explanation = ""
|
||||||
for line in chat_output.split("\n"):
|
for line in lines:
|
||||||
if line.startswith("Branche:"):
|
if line.lower().startswith("branche:"):
|
||||||
suggested_branch = line.split(":", 1)[1].strip()
|
suggestion = line.split(":", 1)[1].strip()
|
||||||
elif line.startswith("Übereinstimmung:"):
|
elif line.lower().startswith("übereinstimmung:"):
|
||||||
consistency = line.split(":", 1)[1].strip()
|
consistency = line.split(":", 1)[1].strip()
|
||||||
elif line.startswith("Begründung:"):
|
elif line.lower().startswith("begründung:"):
|
||||||
justification = line.split(":", 1)[1].strip()
|
explanation = line.split(":", 1)[1].strip()
|
||||||
|
|
||||||
debug_print(f"Ursprünglicher ChatGPT-Vorschlag: '{suggested_branch}', Übereinstimmung='{consistency}', Begründung='{justification}'")
|
# Bereinige den Vorschlag: entferne unnötige Satzzeichen und konvertiere in Kleinbuchstaben
|
||||||
|
clean_suggestion = re.sub(r'[^\w\s/&-]', '', suggestion).strip().lower()
|
||||||
|
|
||||||
# Entferne ggf. den Zusatz "CRM-Branche:" falls vorhanden
|
# Falls der bereinigte Vorschlag kein Hierarchie-Trennzeichen ">" enthält, übernehme den Präfix aus der CRM-Branche
|
||||||
if suggested_branch.lower().startswith("crm-branche"):
|
if ">" not in clean_suggestion and ">" in crm_branche:
|
||||||
suggested_branch = suggested_branch.split(":", 1)[-1].strip()
|
prefix = crm_branche.split(">")[0].strip().lower()
|
||||||
|
clean_suggestion = prefix + " > " + clean_suggestion
|
||||||
|
|
||||||
# Mapping anwenden: Externen Vorschlag in den standardisierten Zielwert überführen
|
# Prüfe, ob der bereinigte Vorschlag mit einem erlaubten Eintrag (Fuzzy Matching) übereinstimmt
|
||||||
mapped_branch = map_external_branch(suggested_branch)
|
valid = False
|
||||||
debug_print(f"Nach Mapping erhalten: '{mapped_branch}'")
|
for allowed in allowed_branches:
|
||||||
|
sim = fuzzy_similarity(clean_suggestion, allowed)
|
||||||
|
if sim > 0.95: # sehr hoher Ähnlichkeit (kann angepasst werden)
|
||||||
|
valid = True
|
||||||
|
# Setze den Vorschlag exakt auf den Zielwert
|
||||||
|
clean_suggestion = allowed
|
||||||
|
break
|
||||||
|
if not valid:
|
||||||
|
debug_print(f"Mapping ungültig für Vorschlag: '{clean_suggestion}'. Fallback: CRM-Branche ('{crm_branche}') verwendet.")
|
||||||
|
return {"branch": crm_branche, "consistency": consistency, "justification": "Fallback: CRM-Wert verwendet aufgrund ungültiger ChatGPT-Zuweisung."}
|
||||||
|
|
||||||
# Hierarchie ergänzen: Falls das Mapping keinen hierarchischen Trennstrich enthält und ein CRM-Präfix vorhanden ist
|
return {"branch": clean_suggestion, "consistency": consistency, "justification": explanation}
|
||||||
if ">" not in mapped_branch and crm_branche.lower() != "k.a.":
|
|
||||||
prefix = crm_branche.split(">")[0].strip() if ">" in crm_branche else ""
|
|
||||||
if prefix:
|
|
||||||
mapped_branch = prefix + " > " + mapped_branch
|
|
||||||
debug_print(f"Ergänzung der Hierarchie: Ergebnis: '{mapped_branch}'")
|
|
||||||
|
|
||||||
final_branch = mapped_branch
|
|
||||||
debug_print(f"Endergebnis Branchenbewertung: Branche='{final_branch}', Übereinstimmung='{consistency}', Begründung='{justification}'")
|
|
||||||
return {"branch": final_branch, "consistency": consistency, "justification": justification}
|
|
||||||
|
|
||||||
|
|
||||||
def evaluate_servicetechnicians_estimate(company_name, company_data):
|
def evaluate_servicetechnicians_estimate(company_name, company_data):
|
||||||
|
|||||||
Reference in New Issue
Block a user