STABLE - Objektorientiertes Schema-Handling
- MAJOR REFACTOR: Globale Variablen für Branchenschema komplett entfernt. Das Schema wird nun in der `DataProcessor`-Instanz gehalten. - 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. Die Grundlage für neue Features ist gelegt.
This commit is contained in:
88
helpers.py
88
helpers.py
@@ -898,30 +898,23 @@ def summarize_batch_openai(tasks_data):
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
@retry_on_failure
|
@retry_on_failure
|
||||||
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, schema_data):
|
||||||
"""
|
"""
|
||||||
Bewertet die Branche eines Unternehmens.
|
Bewertet die Branche eines Unternehmens. Erhält das Schema als Argument.
|
||||||
NUTZT DIE BEWÄHRTE PARSING-LOGIK AUS v1.7.9.
|
Verwendet die robuste Parsing-Logik aus v1.7.9.
|
||||||
"""
|
"""
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# HINWEIS: Die globalen Variablen TARGET_SCHEMA_STRING, FOCUS_BRANCHES_PROMPT_PART
|
if not schema_data or not schema_data.get("allowed_branches"):
|
||||||
# und ALLOWED_TARGET_BRANCHES werden auf Modulebene importiert und von
|
logger.critical("FEHLER: Kein gültiges Schema-Datenobjekt an evaluate_branche_chatgpt übergeben.")
|
||||||
# initialize_target_schema() modifiziert. Wir dürfen sie hier nicht erneut importieren.
|
return {"branch": "FEHLER - SCHEMA FEHLT", "confidence": "N/A", "consistency": "error_schema_missing", "justification": "Fehler: Schema-Daten fehlen."}
|
||||||
|
|
||||||
# Lazy Loading des Branchenschemas
|
allowed_branches = schema_data["allowed_branches"]
|
||||||
if not ALLOWED_TARGET_BRANCHES:
|
schema_prompt = schema_data["schema_prompt_string"]
|
||||||
logger.warning("Branchenschema nicht geladen. Versuche es jetzt zu laden...")
|
allowed_branches_lookup = {b.lower(): b for b in allowed_branches}
|
||||||
if not initialize_target_schema():
|
|
||||||
logger.critical("FEHLER in evaluate_branche_chatgpt: Schema konnte nicht geladen werden.")
|
|
||||||
return {"branch": "FEHLER - SCHEMA FEHLT", "confidence": "N/A", "consistency": "error_schema_missing", "justification": "Fehler: Schema nicht geladen."}
|
|
||||||
|
|
||||||
allowed_branches_lookup = {b.lower(): b for b in ALLOWED_TARGET_BRANCHES}
|
prompt_parts = [schema_prompt]
|
||||||
prompt_parts = [TARGET_SCHEMA_STRING, FOCUS_BRANCHES_PROMPT_PART]
|
# Rest der Prompt-Zusammenstellung
|
||||||
prompt_parts.append("\nOrdne das Unternehmen anhand folgender Angaben exakt einer Branche des Ziel-Branchenschemas (Kurzformen) zu.")
|
|
||||||
prompt_parts.append("Gib zusätzlich eine Konfidenz für deine Branchenwahl an (Hoch, Mittel oder Niedrig).")
|
|
||||||
|
|
||||||
# --- Prompt-Zusammenstellung (unverändert) ---
|
|
||||||
if crm_branche and str(crm_branche).strip() and str(crm_branche).strip().lower() != "k.a.": prompt_parts.append(f"- CRM-Branche (Referenz): {str(crm_branche).strip()}")
|
if crm_branche and str(crm_branche).strip() and str(crm_branche).strip().lower() != "k.a.": prompt_parts.append(f"- CRM-Branche (Referenz): {str(crm_branche).strip()}")
|
||||||
if wiki_branche and str(wiki_branche).strip() and str(wiki_branche).strip().lower() != "k.a.":
|
if wiki_branche and str(wiki_branche).strip() and str(wiki_branche).strip().lower() != "k.a.":
|
||||||
if beschreibung and str(beschreibung).strip() and str(beschreibung).strip().lower() != "k.a.": prompt_parts.append(f"- Beschreibung (CRM): {str(beschreibung).strip()[:500]}...")
|
if beschreibung and str(beschreibung).strip() and str(beschreibung).strip().lower() != "k.a.": prompt_parts.append(f"- Beschreibung (CRM): {str(beschreibung).strip()[:500]}...")
|
||||||
@@ -929,11 +922,10 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
|||||||
prompt_parts.append(f"- Wikipedia-Branche: {str(wiki_branche).strip()[:300]}...")
|
prompt_parts.append(f"- Wikipedia-Branche: {str(wiki_branche).strip()[:300]}...")
|
||||||
if wiki_kategorien and str(wiki_kategorien).strip() and str(wiki_kategorien).strip().lower() != "k.a.": prompt_parts.append(f"- Wikipedia-Kategorien: {str(wiki_kategorien).strip()[:500]}...")
|
if wiki_kategorien and str(wiki_kategorien).strip() and str(wiki_kategorien).strip().lower() != "k.a.": prompt_parts.append(f"- Wikipedia-Kategorien: {str(wiki_kategorien).strip()[:500]}...")
|
||||||
else:
|
else:
|
||||||
logger.debug("evaluate_branche_chatgpt: Keine validen Wiki-Daten, nutze Website-Zusammenfassung als primäre Beschreibung.")
|
|
||||||
if website_summary and str(website_summary).strip() and str(website_summary).strip().lower() != "k.a." and not str(website_summary).strip().startswith("k.A. (Fehler"): prompt_parts.append(f"- Website-Zusammenfassung (als Hauptbeschreibung): {str(website_summary).strip()[:800]}...")
|
if website_summary and str(website_summary).strip() and str(website_summary).strip().lower() != "k.a." and not str(website_summary).strip().startswith("k.A. (Fehler"): prompt_parts.append(f"- Website-Zusammenfassung (als Hauptbeschreibung): {str(website_summary).strip()[:800]}...")
|
||||||
elif beschreibung and str(beschreibung).strip() and str(beschreibung).strip().lower() != "k.a.": prompt_parts.append(f"- Beschreibung (CRM, als Hauptbeschreibung): {str(beschreibung).strip()[:800]}...")
|
elif beschreibung and str(beschreibung).strip() and str(beschreibung).strip().lower() != "k.a.": prompt_parts.append(f"- Beschreibung (CRM, als Hauptbeschreibung): {str(beschreibung).strip()[:800]}...")
|
||||||
|
|
||||||
prompt = "\n".join(filter(None, prompt_parts))
|
prompt = "\n".join(prompt_parts)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
chat_response = call_openai_chat(prompt, temperature=0.0)
|
chat_response = call_openai_chat(prompt, temperature=0.0)
|
||||||
@@ -942,72 +934,54 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
|||||||
logger.error(f"Endgueltiger FEHLER beim OpenAI-Aufruf fuer Branchenevaluation: {e}")
|
logger.error(f"Endgueltiger FEHLER beim OpenAI-Aufruf fuer Branchenevaluation: {e}")
|
||||||
return {"branch": "FEHLER API", "confidence": "N/A", "consistency": "error_api_failed", "justification": f"Fehler API: {str(e)[:100]}"}
|
return {"branch": "FEHLER API", "confidence": "N/A", "consistency": "error_api_failed", "justification": f"Fehler API: {str(e)[:100]}"}
|
||||||
|
|
||||||
# --- v1.7.9 PARSING LOGIK WIEDERHERGESTELLT ---
|
# v1.7.9 Parsing Logic
|
||||||
lines = chat_response.strip().split("\n")
|
lines = chat_response.strip().split("\n")
|
||||||
result = {"confidence": "N/A", "justification": ""}
|
result = {"confidence": "N/A", "justification": ""}
|
||||||
suggested_branch = ""
|
suggested_branch = ""
|
||||||
parsed_branch = False
|
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line_lower = line.lower()
|
line_lower = line.lower()
|
||||||
if line_lower.startswith("branche:"):
|
if "branche:" in line_lower:
|
||||||
suggested_branch = line.split(":", 1)[1].strip()
|
suggested_branch = line.split(":", 1)[1].strip().strip('"\'')
|
||||||
parsed_branch = True
|
break
|
||||||
break # Wichtig: Schleife beenden, sobald der Treffer da ist
|
if not suggested_branch and lines:
|
||||||
|
suggested_branch = lines[0].strip().split(":", 1)[-1].strip().strip('"\'')
|
||||||
|
|
||||||
# Fallback, wenn "Branche:" nicht gefunden wurde (Logik aus v1.7.9)
|
# Extrahiere Konfidenz und Begründung
|
||||||
if not parsed_branch and lines:
|
|
||||||
suggested_branch = lines[0].strip() # Nimm die erste Zeile als Vorschlag
|
|
||||||
logger.warning(f"Konnte 'Branche:' nicht finden. Interpretiere erste Zeile als Vorschlag: '{suggested_branch}'")
|
|
||||||
|
|
||||||
# Extrahiere Konfidenz und Begründung separat
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line_lower = line.lower()
|
if line.lower().startswith("konfidenz:"): result["confidence"] = line.split(":", 1)[1].strip()
|
||||||
if line_lower.startswith("konfidenz:"):
|
elif line.lower().startswith("begruendung:"): result["justification"] = line.split(":", 1)[1].strip()
|
||||||
result["confidence"] = line.split(":", 1)[1].strip()
|
|
||||||
elif line_lower.startswith("begruendung:"):
|
|
||||||
result["justification"] = line.split(":", 1)[1].strip()
|
|
||||||
|
|
||||||
if not suggested_branch:
|
if not suggested_branch:
|
||||||
logger.error(f"Fehler: Konnte keine Branche aus der Antwort extrahieren: {chat_response[:200]}")
|
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"Antwort leer oder unklar: {chat_response[:100]}"}
|
return {"branch": "FEHLER PARSING", "confidence": "N/A", "consistency": "error_parsing", "justification": f"Antwortformat unerwartet: {chat_response[:100]}"}
|
||||||
|
|
||||||
# --- Validierung und intelligenter Fallback (leicht angepasst aus v1.9.1) ---
|
# Validierung und intelligenter Fallback
|
||||||
final_branch = None
|
final_branch = None
|
||||||
suggested_branch_lower = suggested_branch.lower()
|
suggested_branch_lower = suggested_branch.lower()
|
||||||
|
|
||||||
if suggested_branch_lower in allowed_branches_lookup:
|
if suggested_branch_lower in allowed_branches_lookup:
|
||||||
final_branch = allowed_branches_lookup[suggested_branch_lower]
|
final_branch = allowed_branches_lookup[suggested_branch_lower]
|
||||||
logger.debug(f"KI-Vorschlag '{suggested_branch}' ist ein exakter Match.")
|
|
||||||
else:
|
else:
|
||||||
# Substring-Match für KI-Vorschlag
|
best_suggestion_match = next((val for key, val in allowed_branches_lookup.items() if suggested_branch_lower in key.lower()), None)
|
||||||
best_suggestion_match = next((val for key, val in allowed_branches_lookup.items() if suggested_branch_lower in key), None)
|
if best_suggestion_match: final_branch = best_suggestion_match
|
||||||
if best_suggestion_match:
|
|
||||||
final_branch = best_suggestion_match
|
|
||||||
logger.info(f"KI-Vorschlag '{suggested_branch}' per Substring zu '{final_branch}' gemappt.")
|
|
||||||
|
|
||||||
if final_branch:
|
if final_branch:
|
||||||
result["branch"] = final_branch
|
result["branch"] = final_branch
|
||||||
# Konsistenzprüfung (ok/X)
|
if final_branch.lower() == crm_branche.strip().lower(): result["consistency"] = "ok"
|
||||||
if final_branch.lower() == crm_branche.strip().lower():
|
else: result["consistency"] = "X"
|
||||||
result["consistency"] = "ok"
|
|
||||||
else:
|
|
||||||
result["consistency"] = "X"
|
|
||||||
else:
|
else:
|
||||||
# Fallback auf CRM-Branche
|
|
||||||
logger.debug(f"Vorschlag '{suggested_branch}' nicht im Schema. Prüfe Fallback auf CRM-Branche...")
|
|
||||||
crm_short_branch_lower = crm_branche.strip().lower()
|
crm_short_branch_lower = crm_branche.strip().lower()
|
||||||
best_crm_fallback = next((val for key, val in allowed_branches_lookup.items() if crm_short_branch_lower in key and crm_short_branch_lower), None)
|
best_crm_fallback = next((val for key, val in allowed_branches_lookup.items() if crm_short_branch_lower and crm_short_branch_lower in key.lower()), None)
|
||||||
|
|
||||||
if best_crm_fallback:
|
if best_crm_fallback:
|
||||||
result["branch"] = best_crm_fallback
|
result["branch"] = best_crm_fallback
|
||||||
result["consistency"] = "fallback_crm_substring"
|
result["consistency"] = "fallback_crm_substring"
|
||||||
result["justification"] = f"Fallback: KI-Vorschlag ungültig. CRM-Branche '{crm_branche}' passt zu Schema '{best_crm_fallback}'."
|
result["justification"] = f"Fallback: KI-Vorschlag ungültig. CRM-Branche '{crm_branche}' passt zu '{best_crm_fallback}'."
|
||||||
result["confidence"] = "N/A (Fallback)"
|
result["confidence"] = "N/A (Fallback)"
|
||||||
else:
|
else:
|
||||||
result["branch"] = "FEHLER - UNGUELTIGE ZUWEISUNG"
|
result["branch"] = "FEHLER - UNGUELTIGE ZUWEISUNG"
|
||||||
result["consistency"] = "fallback_invalid"
|
result["consistency"] = "fallback_invalid"
|
||||||
result["justification"] = f"Fehler: Weder KI-Vorschlag ('{suggested_branch}') noch CRM-Branche ('{crm_branche}') passen zum Schema."
|
result["justification"] = f"Fehler: Weder KI ('{suggested_branch}') noch CRM ('{crm_branche}') passen."
|
||||||
result["confidence"] = "N/A (Fehler)"
|
result["confidence"] = "N/A (Fehler)"
|
||||||
|
|
||||||
logger.debug(f"Finale Branch-Evaluation: {result}")
|
logger.debug(f"Finale Branch-Evaluation: {result}")
|
||||||
|
|||||||
Reference in New Issue
Block a user