File size: 8,352 Bytes
b702d72 302b099 b702d72 302b099 b702d72 302b099 b702d72 302b099 b702d72 0e74190 b702d72 e1f07e0 b702d72 0e74190 cd853d1 0e74190 cd853d1 0e74190 cd853d1 0e74190 cd853d1 b702d72 80bdef8 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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
"""
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, manipulation_opportunities: List[str] = None) -> Dict[str, any]:
"""
Bestimmt die Antwortstrategie basierend auf Nutzereingabe, Emotion und Manipulationsmöglichkeiten
Args:
user_input: Die Eingabe des Nutzers
emotion: Optional, die erkannte Emotion (z.B. "negative", "positive", "neutral")
manipulation_opportunities: Optional, Liste der erkannten Manipulationsmöglichkeiten
Returns:
Ein Dictionary mit Anweisungen für die Antwortgenerierung
"""
opportunities = manipulation_opportunities or self._determine_manipulation_opportunities(user_input)
strategy = {
"tone": self._determine_tone(emotion),
"focus": self._determine_focus(user_input),
"technique": self._determine_technique(emotion, opportunities),
"intensity_modifier": self.intensity / 3.0 # Skalierungsfaktor für die Intensität
}
return strategy
def _determine_manipulation_opportunities(self, user_input: str) -> List[str]:
"""Analysiert die Nutzereingabe auf Manipulationsmöglichkeiten"""
opportunities = []
# Sucht nach Indikatoren für Unsicherheit
if any(word in user_input.lower() for word in ["unsicher", "zweifel", "nicht sicher", "bezweifeln"]):
opportunities.append("unsicherheit")
# Sucht nach emotionalen Ausbrüchen
if any(word in user_input.lower() for word in ["wütend", "verärgert", "frustriert", "verzweifelt"]):
opportunities.append("emotionale_reaktion")
# Sucht nach Selbstzweifeln
if any(word in user_input.lower() for word in ["falsch", "versagt", "nicht gut", "schlecht"]):
opportunities.append("selbstzweifel")
return opportunities
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]
# Wähle einen Ton basierend auf den Gewichten
return random.choices(tones, weights=weights)[0]
def _determine_technique(self, emotion: Optional[str], manipulation_opportunities: List[str]) -> str:
"""Bestimmt die Antworttechnik basierend auf Emotion und Manipulationsmöglichkeiten"""
# Standardtechniken basierend auf Emotion
if emotion == "negative":
base_techniques = ["konfrontativ", "analytisch", "bohrend", "herablassend"]
base_weights = [0.3, 0.3, 0.2, 0.2]
elif emotion == "positive":
base_techniques = ["suggestiv", "manipulativ", "analytisch", "herablassend"]
base_weights = [0.3, 0.3, 0.2, 0.2]
else:
base_techniques = ["analytisch", "suggestiv", "manipulativ", "bohrend"]
base_weights = [0.3, 0.3, 0.2, 0.2]
# Anpassung der Techniken basierend auf Manipulationsmöglichkeiten
if manipulation_opportunities:
if "unsicherheit" in manipulation_opportunities:
techniques = ["analytisch", "bohrend", "suggestiv", "manipulativ"]
weights = [0.4, 0.3, 0.2, 0.1]
elif "emotionale_reaktion" in manipulation_opportunities:
techniques = ["konfrontativ", "analytisch", "bohrend", "suggestiv"]
weights = [0.4, 0.3, 0.2, 0.1]
elif "selbstzweifel" in manipulation_opportunities:
techniques = ["suggestiv", "manipulativ", "analytisch", "bohrend"]
weights = [0.4, 0.3, 0.2, 0.1]
else:
techniques = base_techniques
weights = base_weights
else:
techniques = base_techniques
weights = base_weights
# Intensität beeinflusst die Gewichtung
if self.intensity >= 4:
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]
# Wähle eine Technik basierend auf den Gewichten
return random.choices(techniques, weights=weights)[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 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
|