Implementierung der Batch-Brancheneinstufung zur Kostenoptimierung
- FEATURE: Brancheneinstufung erfolgt nun in Batches (z.B. 20 Unternehmen pro API-Call), um die Token-Kosten drastisch zu senken. - REFACTOR: Neue Funktion `evaluate_branches_batch` in `helpers.py` erstellt, die den komplexen Batch-Prompt generiert. - REFACTOR: `reclassify_all_branches` in `data_processor.py` überarbeitet, um die Batch-Verarbeitung und das Ergebnis-Mapping zu steuern.
This commit is contained in:
91
helpers.py
91
helpers.py
@@ -971,6 +971,97 @@ def evaluate_branche_chatgpt(company_name, website_summary, wiki_absatz):
|
||||
"justification": f"Fehler bei der API-Kommunikation: {str(e)[:100]}"
|
||||
}
|
||||
|
||||
|
||||
def evaluate_branches_batch(companies_data):
|
||||
"""
|
||||
Führt eine kontextbasierte Brancheneinstufung für einen Batch von Unternehmen durch.
|
||||
Sendet das Branchenschema nur einmal, um Kosten zu sparen.
|
||||
|
||||
Args:
|
||||
companies_data (list): Eine Liste von Dictionaries, jedes mit 'row_num', 'name', 'summary', 'wiki'.
|
||||
|
||||
Returns:
|
||||
list: Eine Liste von Dictionaries mit den Ergebnissen für jedes Unternehmen.
|
||||
"""
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 1. Baue das ZIEL-BRANCHENSCHEMA als Textblock auf (wird nur einmal gesendet)
|
||||
schema_text_parts = []
|
||||
for i, (branch, details) in enumerate(Config.BRANCH_GROUP_MAPPING.items()):
|
||||
schema_text_parts.append(f"{i+1}. Branche: {branch}")
|
||||
if details.get("definition"):
|
||||
schema_text_parts.append(f" Definition: {details['definition']}")
|
||||
if details.get("beispiele"):
|
||||
schema_text_parts.append(f" Beispiele: {details['beispiele']}")
|
||||
ziel_branchenschema_text = "\n".join(schema_text_parts)
|
||||
|
||||
# 2. Baue die Liste der Unternehmensprofile für den Prompt auf
|
||||
unternehmensprofile_text_parts = []
|
||||
for i, company in enumerate(companies_data):
|
||||
profil = [f"--- UNTERNEHMEN #{i+1} (Original-Zeilennummer: {company['row_num']}) ---"]
|
||||
profil.append(f"- Name: {company.get('name', 'N/A')}")
|
||||
if company.get('summary'):
|
||||
profil.append(f"- Website-Zusammenfassung: {company['summary']}")
|
||||
if company.get('wiki'):
|
||||
profil.append(f"- Wikipedia-Auszug: {company['wiki']}")
|
||||
unternehmensprofile_text_parts.append("\n".join(profil))
|
||||
|
||||
unternehmensprofile_text = "\n\n".join(unternehmensprofile_text_parts)
|
||||
|
||||
# 3. Baue den Master-Prompt zusammen
|
||||
prompt_parts = [
|
||||
"Du bist ein erfahrener Branchenanalyst. Deine Aufgabe ist es, eine Liste von Unternehmen präzise einer von 54 vordefinierten Branchenkategorien zuzuordnen. Nutze dafür ausschließlich das bereitgestellte ZIEL-BRANCHENSCHEMA.",
|
||||
"\n--- ZIEL-BRANCHENSCHEMA (Deine einzig gültige Wissensbasis) ---",
|
||||
ziel_branchenschema_text,
|
||||
"\n--- ZU ANALYSIERENDE UNTERNEHMEN ---",
|
||||
unternehmensprofile_text,
|
||||
"\n--- DEINE AUFGABE ---",
|
||||
f"Analysiere jedes der {len(companies_data)} Unternehmen Schritt für Schritt.",
|
||||
"Vergleiche jedes Unternehmensprofil mit den Definitionen im ZIEL-BRANCHENSCHEMA.",
|
||||
"Gib als Ergebnis eine JSON-Liste zurück, die exakt ein JSON-Objekt für jedes Unternehmen in der gleichen Reihenfolge enthält.",
|
||||
"Jedes JSON-Objekt muss folgende Schlüssel haben: 'row_num', 'Branche', 'Konfidenz', 'Begruendung'.",
|
||||
"Die 'row_num' muss exakt der 'Original-Zeilennummer' aus dem Input entsprechen.",
|
||||
"Beispiel-Format für die Antwort: \n"
|
||||
'''
|
||||
[
|
||||
{
|
||||
"row_num": 123,
|
||||
"Branche": "Maschinenbau",
|
||||
"Konfidenz": "Hoch",
|
||||
"Begruendung": "Das Unternehmen stellt komplexe Maschinen her, was der Definition entspricht."
|
||||
},
|
||||
{
|
||||
"row_num": 456,
|
||||
"Branche": "Facility Management",
|
||||
"Konfidenz": "Mittel",
|
||||
"Begruendung": "Bietet Dienstleistungen rund um Immobilien an, passt zur Definition."
|
||||
}
|
||||
]
|
||||
'''
|
||||
]
|
||||
prompt = "\n".join(prompt_parts)
|
||||
|
||||
# 4. API-Aufruf
|
||||
try:
|
||||
response_str = call_openai_chat(prompt, temperature=0.0, model="gpt-4o", response_format_json=True)
|
||||
if not response_str:
|
||||
raise APIError("Keine Antwort von OpenAI erhalten.")
|
||||
|
||||
# Das Ergebnis sollte direkt eine Liste von Dictionaries sein
|
||||
results_list = json.loads(response_str)
|
||||
|
||||
# Validierung, ob die Antwort eine Liste ist
|
||||
if not isinstance(results_list, list):
|
||||
logger.error(f"KI-Antwort ist keine Liste, sondern {type(results_list)}. Breche Batch ab.")
|
||||
return None
|
||||
|
||||
return results_list
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Endgültiger FEHLER beim Batch-API-Aufruf: {e}")
|
||||
return None
|
||||
|
||||
|
||||
@retry_on_failure
|
||||
def verify_wiki_article_chatgpt(company_name, parent_name, website, wiki_title, wiki_summary):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user