gateway/gwserver/modules/agentservice_agent_analyst.py
2025-04-06 23:57:10 +02:00

189 lines
No EOL
6.9 KiB
Python

"""
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