""" 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 """ self.result_format = "AnalysisReport" 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 analysis_response["result_format"] = self.result_format 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