expand_knowledge_base.py hinzugefügt
This commit is contained in:
164
expand_knowledge_base.py
Normal file
164
expand_knowledge_base.py
Normal file
@@ -0,0 +1,164 @@
|
||||
# expand_knowledge_base.py
|
||||
|
||||
import os
|
||||
import yaml
|
||||
import logging
|
||||
import time
|
||||
import openai
|
||||
import argparse # NEU: Für Kommandozeilen-Argumente
|
||||
from config import Config, BRANCH_GROUP_MAPPING
|
||||
|
||||
# --- Konfiguration ---
|
||||
BASE_KNOWLEDGE_FILE = "marketing_wissen.yaml"
|
||||
OUTPUT_FILE = "marketing_wissen_komplett.yaml"
|
||||
MODEL_TO_USE = "gpt-4o"
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
def call_openai_with_retry(prompt, is_extraction=False, max_retries=3, delay=5):
|
||||
# ... (Diese Funktion bleibt unverändert) ...
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
logging.info(f"Sende Prompt an OpenAI (Länge: {len(prompt)} Zeichen)...")
|
||||
response_format = {"type": "json_object"} if is_extraction else {"type": "text"}
|
||||
response = openai.ChatCompletion.create(
|
||||
model=MODEL_TO_USE,
|
||||
response_format=response_format,
|
||||
messages=[{"role": "user", "content": prompt}],
|
||||
temperature=0.3,
|
||||
max_tokens=2048
|
||||
)
|
||||
content = response.choices[0].message['content'].strip()
|
||||
return content
|
||||
except Exception as e:
|
||||
logging.error(f"Fehler bei OpenAI-API-Aufruf: {e}")
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(delay)
|
||||
else:
|
||||
return None
|
||||
|
||||
def generate_research_prompt(branch_name):
|
||||
# ... (Diese Funktion bleibt unverändert) ...
|
||||
return (
|
||||
f"Erstelle ein prägnantes Branchen-Dossier (ca. 300-400 Wörter) für: '{branch_name}'.\n"
|
||||
"Struktur des Dossiers:\n"
|
||||
"1. **Geschäftsmodelle & Field Service:** Beschreibe kurz die typischen Geschäftsmodelle und die zentrale Rolle des technischen Außendienstes (Field Service) in dieser Branche.\n"
|
||||
"2. **Herausforderungen & Trends:** Nenne die wichtigsten aktuellen Herausforderungen und Trends, die den Service-Bereich beeinflussen (z.B. Digitalisierung, Regularien, Fachkräftemangel).\n"
|
||||
"3. **Branchenspezifisches Wording:** Liste einige typische Fachbegriffe oder Abkürzungen auf, die im Service-Kontext dieser Branche üblich sind."
|
||||
)
|
||||
|
||||
def generate_extraction_prompt(dossier_content):
|
||||
# ... (Diese Funktion bleibt unverändert) ...
|
||||
return (
|
||||
"Du bist ein Branchenanalyst. Lies das folgende Dossier und extrahiere die geforderten Informationen.\n"
|
||||
"Gib das Ergebnis ausschließlich als sauberes JSON-Objekt mit den Schlüsseln 'summary', 'pain_points' (eine Liste von 5 Punkten) und 'key_terms' (eine Liste von 5-7 Begriffen) aus.\n\n"
|
||||
"--- DOSSIER ---\n"
|
||||
f"{dossier_content}"
|
||||
)
|
||||
|
||||
def main(branches_to_process=None):
|
||||
"""Erweitert die Wissensbasis um die fehlenden Branchen und speichert die Recherche-Dossiers."""
|
||||
logging.info("Starte Erweiterung der Wissensbasis...")
|
||||
|
||||
# ... (Code zum Laden der API-Keys und der Basis-Wissensdatei bleibt unverändert) ...
|
||||
Config.load_api_keys()
|
||||
openai.api_key = Config.API_KEYS.get('openai')
|
||||
if not openai.api_key:
|
||||
logging.critical("OpenAI API Key nicht gefunden.")
|
||||
return
|
||||
|
||||
try:
|
||||
with open(BASE_KNOWLEDGE_FILE, 'r', encoding='utf-8') as f:
|
||||
knowledge_base = yaml.safe_load(f)
|
||||
except FileNotFoundError:
|
||||
logging.critical(f"FEHLER: Basis-Wissensdatei '{BASE_KNOWLEDGE_FILE}' nicht gefunden.")
|
||||
return
|
||||
|
||||
all_branches = set(BRANCH_GROUP_MAPPING.keys())
|
||||
existing_branches = set(knowledge_base.get('Branchen', {}).keys())
|
||||
|
||||
# --- NEUE LOGIK ZUR BRANCHEN-AUSWAHL ---
|
||||
if branches_to_process:
|
||||
# Modus: Nur die übergebenen Branchen verarbeiten
|
||||
target_branches = [b for b in branches_to_process if b in all_branches]
|
||||
if not target_branches:
|
||||
logging.error("Keine der angegebenen Branchen ist gültig. Bitte prüfen Sie die Schreibweise.")
|
||||
logging.info(f"Gültige Branchen sind: {list(all_branches)}")
|
||||
return
|
||||
logging.info(f"Verarbeite die {len(target_branches)} explizit angegebenen Branchen...")
|
||||
else:
|
||||
# Modus: Alle fehlenden Branchen verarbeiten
|
||||
target_branches = sorted(list(all_branches - existing_branches))
|
||||
if not target_branches:
|
||||
logging.info("Glückwunsch! Alle Branchen sind bereits in der Wissensbasis vorhanden.")
|
||||
return
|
||||
logging.info(f"Es werden {len(target_branches)} fehlende Branchen verarbeitet...")
|
||||
|
||||
logging.info(f"Zu verarbeitende Branchen: {', '.join(target_branches)}")
|
||||
|
||||
DOSSIER_FOLDER = "generated_dossiers"
|
||||
os.makedirs(DOSSIER_FOLDER, exist_ok=True)
|
||||
|
||||
for branch in target_branches:
|
||||
if not branches_to_process and branch in existing_branches:
|
||||
logging.debug(f"Branche '{branch}' bereits vorhanden, wird übersprungen.")
|
||||
continue
|
||||
|
||||
logging.info(f"\n--- Verarbeite Branche: {branch} ---")
|
||||
|
||||
# Stufe 1: Recherche-Dossier erstellen
|
||||
# ... (Rest der Logik innerhalb der Schleife bleibt unverändert) ...
|
||||
logging.info(" -> Stufe 1: Generiere Recherche-Dossier...")
|
||||
research_prompt = generate_research_prompt(branch)
|
||||
dossier = call_openai_with_retry(research_prompt)
|
||||
if not dossier: continue
|
||||
|
||||
try:
|
||||
sanitized_branch_name = branch.replace('/', '-').replace('\\', '-')
|
||||
dossier_filepath = os.path.join(DOSSIER_FOLDER, f"{sanitized_branch_name}.txt")
|
||||
with open(dossier_filepath, 'w', encoding='utf-8') as f: f.write(dossier)
|
||||
logging.info(f" -> Dossier erfolgreich in '{dossier_filepath}' gespeichert.")
|
||||
except Exception as e:
|
||||
logging.error(f" -> Fehler beim Speichern des Dossiers für {branch}: {e}")
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
# Stufe 2: Informationen extrahieren
|
||||
logging.info(" -> Stufe 2: Extrahiere strukturierte Daten aus dem Dossier...")
|
||||
extraction_prompt = generate_extraction_prompt(dossier)
|
||||
extracted_data_str = call_openai_with_retry(extraction_prompt, is_extraction=True)
|
||||
if not extracted_data_str: continue
|
||||
|
||||
try:
|
||||
if extracted_data_str.startswith("```"):
|
||||
extracted_data_str = extracted_data_str.split('\n', 1)[1].rsplit('```', 1)[0]
|
||||
|
||||
extracted_data = yaml.safe_load(extracted_data_str)
|
||||
extracted_data['references_DE'] = '[HIER DEUTSCHE REFERENZKUNDEN EINTRAGEN]'
|
||||
extracted_data['references_GB'] = '[HIER ENGLISCHE REFERENZKUNDEN EINTRAGEN]'
|
||||
knowledge_base['Branchen'][branch] = extracted_data
|
||||
logging.info(f" -> {branch} erfolgreich zur Wissensbasis hinzugefügt.")
|
||||
except Exception as e:
|
||||
logging.error(f" Fehler beim Parsen der extrahierten Daten für {branch}: {e}")
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
try:
|
||||
with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
|
||||
yaml.dump(knowledge_base, f, allow_unicode=True, sort_keys=False, width=120)
|
||||
logging.info(f"\nErfolgreich! Die aktualisierte Wissensbasis wurde in '{OUTPUT_FILE}' gespeichert.")
|
||||
except Exception as e:
|
||||
logging.error(f"Fehler beim Speichern der finalen YAML-Datei: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# NEU: Argument Parser für die Kommandozeile
|
||||
parser = argparse.ArgumentParser(description="Erweitert die Marketing-Wissensbasis um fehlende Branchen.")
|
||||
parser.add_argument(
|
||||
"--branches",
|
||||
nargs='+', # Erlaubt mehrere Werte, z.B. --branches "Branche A" "Branche B"
|
||||
type=str,
|
||||
help="Eine oder mehrere spezifische Branchen, die verarbeitet werden sollen. Bei Angabe werden nur diese bearbeitet."
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(branches_to_process=args.branches)
|
||||
Reference in New Issue
Block a user