210 lines
No EOL
8 KiB
Python
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 |