File size: 5,981 Bytes
b702d72 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
"""
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
|