""" modules/persona.py - Persönlichkeitsmodul für den Dr. Franz Psychochatbot Dieses Modul definiert die Persönlichkeit des Chatbots, einschließlich: - System-Prompts - Charaktereigenschaften - Antwortstrategien basierend auf Nutzerverhalten """ import random from typing import List, Dict, Optional # Importieren der Konfiguration import config class Persona: """Klasse zur Verwaltung der Chatbot-Persönlichkeit""" def __init__(self, name: str = config.CHATBOT_NAME, intensity: int = config.DEFAULT_INTENSITY): """Initialisiert die Persona mit Namen und Intensitätsstufe""" self.name = name self.intensity = intensity # Skala von 1-5 self.base_prompt = config.SYSTEM_PROMPT def get_system_prompt(self) -> str: """Gibt den Basis-System-Prompt zurück""" return self.base_prompt def adjust_intensity(self, new_intensity: int) -> None: """Passt die Intensität der Persönlichkeit an (1-5)""" if 1 <= new_intensity <= 5: self.intensity = new_intensity def get_response_strategy(self, user_input: str, emotion: Optional[str] = None) -> Dict[str, any]: """ Bestimmt die Antwortstrategie basierend auf Nutzereingabe und erkannter Emotion Args: user_input: Die Eingabe des Nutzers emotion: Optional, die erkannte Emotion (z.B. "negative", "positive", "neutral") Returns: Ein Dictionary mit Anweisungen für die Antwortgenerierung """ strategy = { "tone": self._determine_tone(emotion), "focus": self._determine_focus(user_input), "technique": self._determine_technique(emotion, self._determine_manipulation_opportunities(user_input)), "intensity_modifier": self.intensity / 3.0 # Skalierungsfaktor für die Intensität } return strategy def _determine_tone(self, emotion: Optional[str]) -> str: """Bestimmt den Ton basierend auf der erkannten Emotion""" if emotion == "negative": tones = ["überheblich", "herablassend", "provokativ", "konfrontativ", "skeptisch"] weights = [0.1, 0.3, 0.3, 0.2, 0.1] elif emotion == "positive": tones = ["skeptisch", "hinterfragend", "manipulativ", "suggestiv", "überheblich"] weights = [0.2, 0.2, 0.3, 0.2, 0.1] else: # neutral oder None tones = ["analytisch", "distanziert", "suggestiv", "überheblich", "provokativ"] weights = [0.2, 0.2, 0.2, 0.2, 0.2] # Intensität beeinflusst die Gewichtung if self.intensity >= 4: # Bei hoher Intensität mehr provokative und konfrontative Töne weights = [w * (1 + (i % 3) * 0.2 * (self.intensity - 3)) for i, w in enumerate(weights)] # Normalisieren der Gewichte total = sum(weights) weights = [w / total for w in weights] return random.choices(tones, weights=weights, k=1)[0] def _determine_focus(self, user_input: str) -> str: """Bestimmt den Fokus der Antwort basierend auf der Nutzereingabe""" # Einfache Schlüsselwortanalyse (in einer vollständigen Implementierung # würde hier eine komplexere NLP-Analyse stehen) lower_input = user_input.lower() if any(word in lower_input for word in ["mutter", "vater", "eltern", "familie", "kind"]): return "familiäre Beziehungen" elif any(word in lower_input for word in ["angst", "sorge", "furcht", "panik"]): return "Ängste und Unsicherheiten" elif any(word in lower_input for word in ["liebe", "beziehung", "partner", "ehe"]): return "romantische Beziehungen" elif any(word in lower_input for word in ["arbeit", "job", "karriere", "beruf"]): return "berufliche Ambitionen" elif any(word in lower_input for word in ["freund", "kollege", "bekannte"]): return "soziale Beziehungen" else: return "persönliche Unsicherheiten" def _determine_technique(self, emotion: Optional[str]) -> str: """Wählt eine psychoanalytische Technik basierend auf der Emotion""" techniques = [ "Freie Assoziation", "Traumdeutung", "Übertragungsanalyse", "Widerstandsanalyse", "Projektion aufdecken", "Verdrängung ansprechen", "Abwehrmechanismen identifizieren" ] # Bei negativen Emotionen eher konfrontative Techniken if emotion == "negative": return random.choice(techniques[3:]) # Bei positiven Emotionen eher subtile Techniken elif emotion == "positive": return random.choice(techniques[:4]) # Bei neutralen Emotionen zufällige Auswahl else: return random.choice(techniques) def get_additional_context(self, strategy: Dict[str, any]) -> str: """ Generiert zusätzlichen Kontext für das LLM basierend auf der Strategie Dies wird dem System-Prompt hinzugefügt, um die Antwortgenerierung zu steuern """ intensity_phrases = [ "Sei subtil in deiner Analyse.", "Hinterfrage vorsichtig die Aussagen.", "Sei direkter in deiner psychologischen Deutung.", "Konfrontiere den Patienten mit seinen Widersprüchen.", "Sei aggressiv in deiner Interpretation und Konfrontation." ] intensity_instruction = intensity_phrases[min(self.intensity - 1, 4)] context = ( f"Verwende einen {strategy['tone']} Ton. " f"Fokussiere dich auf {strategy['focus']}. " f"Nutze die Technik der {strategy['technique']}. " f"{intensity_instruction}" ) return context