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

210 lines
No EOL
8 KiB
Python

"""
Datenanalyst-Agent für die Analyse und Interpretation von Daten.
Angepasst für das refaktorisierte Core-Modul.
"""
import logging
import traceback
from typing import List, Dict, Any, Optional, Union
from datetime import datetime
import uuid
from modules.agentservice_base import BaseAgent
from connectors.connector_aichat_openai import ChatService
from modules.agentservice_utils import WorkflowUtils, MessageUtils, LoggingUtils, FileUtils
logger = logging.getLogger(__name__)
class AnalystAgent(BaseAgent):
"""Agent für die Analyse und Interpretation von Daten"""
def __init__(self):
"""Initialisiert den Datenanalyst-Agenten"""
super().__init__()
self.id = "analyst"
self.name = "Datenanalyst"
self.type = "analyzer"
self.description = "Analysiert und interpretiert Daten"
self.capabilities = "data_analysis,pattern_recognition,statistics,visualization,data_interpretation"
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"
# Chat-Service initialisieren
self.chat_service = ChatService()
# Utility-Klassen initialisieren
self.message_utils = MessageUtils()
self.file_utils = FileUtils()
def get_agent_info(self) -> Dict[str, Any]:
"""Get agent information for agent registry"""
return {
"id": self.id,
"type": self.type,
"name": self.name,
"description": self.description,
"capabilities": self.capabilities,
"result_format": self.result_format
}
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.
"""
# 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],
workflow: Dict[str, Any],
context: Dict[str, Any] = None,
log_func=None) -> Dict[str, Any]:
"""
Verarbeitet eine Nachricht und führt eine Datenanalyse durch.
Args:
message: Die zu verarbeitende Nachricht
workflow: Der aktuelle Workflow
context: Zusätzlicher Kontext
log_func: Funktion für Workflow-Logging
Returns:
Die generierte Antwort mit der Datenanalyse
"""
# Initialize logging
workflow_id = workflow.get("id", "unknown")
logging_utils = LoggingUtils(workflow_id, log_func)
logging_utils.info(f"AnalystAgent startet Datenanalyse", "agents")
# Create response message
response = self.message_utils.create_message(workflow_id, role="assistant")
response["agent_type"] = self.type
response["agent_name"] = self.name
response["parent_message_id"] = message.get("id")
try:
# Prepare message context for generating the prompt
message_context = {"documents": context.get("documents", [])} if context else {}
# Generate appropriate prompt based on the context
prompt = self.get_prompt(message_context)
logging_utils.info(f"Datenanalyse mit spezifischem Prompt gestartet", "agents")
# Prepare messages for the API
messages = [
{"role": "system", "content": prompt},
{"role": "user", "content": message.get("content", "")}
]
# Add context messages if available
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", "")
})
# Call the API
logging_utils.info("Rufe AI-Service für die Analyse auf", "agents")
response_content = await self.chat_service.call_api(messages)
logging_utils.info("Analyse abgeschlossen", "agents")
# Set the content in the response
response["content"] = response_content
# Finalize the message
self.message_utils.finalize_message(response)
response["result_format"] = self.result_format
return response
except Exception as e:
error_msg = f"Fehler bei der Datenanalyse: {str(e)}"
logging_utils.error(error_msg, "error")
# Create error response
response["content"] = f"## Fehler bei der Datenanalyse\n\n{error_msg}\n\n```\n{traceback.format_exc()}\n```"
self.message_utils.finalize_message(response)
return response
# 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