""" Datenanalyst-Agent für die Analyse und Interpretation von Daten. """ import logging from typing import List, Dict, Any, Optional from modules.agentservice_base import BaseAgent from connectors.connector_aichat_openai import ChatService logger = logging.getLogger(__name__) class AnalystAgent(BaseAgent): """Agent für die Analyse und Interpretation von Daten""" _instance = None @classmethod def get_instance(cls): """Gibt eine Singleton-Instanz zurück""" if cls._instance is None: cls._instance = cls() return cls._instance def __init__(self): """Initialisiert den Datenanalyst-Agenten""" super().__init__() self.id = "analyst_agent" self.name = "Datenanalyst" self.type = "analyzer" self.description = "Analysiert und interpretiert Daten" self.capabilities = "Datenanalyse, Mustererkennung, Statistik und Bewertung" self.instructions = """ Du bist der Datenanalyseagent. Deine Aufgabe: 1. Vorliegende Daten untersuchen und interpretieren 2. Erkenntnisse aus Informationen gewinnen 3. Trends identifizieren und Zusammenhänge prüfen 4. Daten visualisieren und Konzepte erklären 5. Datenqualität bewerten und Handlungsempfehlungen geben """ def get_prompt(self, message_context: Dict[str, Any]) -> str: """ Generiert einen angepassten Prompt für den Datenanalysten. Args: message_context: Kontext der Nachricht Returns: Formatierter Prompt für den Datenanalysten """ # Basis-Prompt prompt = f""" Du bist {self.name}, ein {self.type} Agent. {self.description} Fähigkeiten: {self.capabilities} {self.instructions} Analysiere die vorliegenden Daten. Präsentiere klar strukturierte Ergebnisse mit einer Zusammenfassung, Detailanalyse und Handlungsempfehlungen. Formatiere mit [STATUS: ERGEBNIS/TEILWEISE/PLAN] am Ende. """ # Dateitypspezifische Anweisungen hinzufügen (verkürzt) document_types = self._get_document_types(message_context) if "csv" in document_types or "excel" in document_types: prompt += "\nTABELLENDATEN: Identifiziere wichtige Spalten, Korrelationen und Trends." if "pdf" in document_types or "doc" in document_types: prompt += "\nTEXTDATEN: Extrahiere zentrale Fakten und Schlüsselthemen." if "image" in document_types: prompt += "\nBILDDATEN: Beschreibe und interpretiere dargestellte Informationen." return prompt.strip() def _get_document_types(self, message_context: Dict[str, Any]) -> List[str]: """ Extrahiert die Dateitypen aus dem Nachrichtenkontext. Args: message_context: Kontext der Nachricht Returns: Liste der Dateitypen """ document_types = [] # Versuche Dokumente aus dem Kontext zu extrahieren documents = message_context.get("documents", []) for doc in documents: source = doc.get("source", {}) name = source.get("name", "").lower() content_type = source.get("content_type", "").lower() # Dateityp aus Namen oder Content-Type ableiten if name.endswith(".csv") or "csv" in content_type: document_types.append("csv") elif name.endswith((".xls", ".xlsx")) or "excel" in content_type or "spreadsheet" in content_type: document_types.append("excel") elif name.endswith(".pdf") or "pdf" in content_type: document_types.append("pdf") elif name.endswith((".doc", ".docx")) or "word" in content_type: document_types.append("doc") elif name.endswith((".jpg", ".jpeg", ".png", ".gif")) or "image" in content_type: document_types.append("image") return document_types async def process_message(self, message: Dict[str, Any], context: Dict[str, Any] = None) -> Dict[str, Any]: """ Verarbeitet eine Nachricht und führt eine Datenanalyse durch. Args: message: Die zu verarbeitende Nachricht context: Zusätzlicher Kontext (optional) Returns: Die generierte Antwort mit der Datenanalyse """ try: # Prompt generieren message_context = {"documents": context.get("documents", [])} if context else {} prompt = self.get_prompt(message_context) # OpenAI ChatService initialisieren chat_service = ChatService() # Nachrichten für die API vorbereiten messages = [ {"role": "system", "content": prompt}, {"role": "user", "content": message.get("content", "")} ] # Kontext-Nachrichten hinzufügen, falls vorhanden if context and "history" in context: for history_item in context["history"]: messages.append({ "role": history_item.get("role", "user"), "content": history_item.get("content", "") }) # API aufrufen response_content = await chat_service.call_api(messages) # Verbindung schließen await chat_service.close() # Antwort-Objekt erstellen analysis_response = { "role": "assistant", "content": response_content, "agent_type": self.type } # Extrahiere den Status aus der Antwort und aktualisiere den Inhalt content, status = self.extract_status(analysis_response["content"]) analysis_response["content"] = content # Setze den Status im Kontext, falls vorhanden if context is not None: context["status"] = status return analysis_response except Exception as e: logger.error(f"Fehler bei der Verarbeitung der Anfrage: {str(e)}", exc_info=True) # Fehlerantwort zurückgeben return { "role": "assistant", "content": f"Bei der Datenanalyse ist ein Fehler aufgetreten: {str(e)}", "agent_type": self.type } # Singleton-Instanz _analyst_agent = None def get_analyst_agent(): """Gibt eine Singleton-Instanz des Datenanalyst-Agenten zurück""" global _analyst_agent if _analyst_agent is None: _analyst_agent = AnalystAgent() return _analyst_agent