|
""" |
|
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 |
|
|
|
|
|
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 |
|
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 |
|
} |
|
|
|
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: |
|
tones = ["analytisch", "distanziert", "suggestiv", "überheblich", "provokativ"] |
|
weights = [0.2, 0.2, 0.2, 0.2, 0.2] |
|
|
|
|
|
if self.intensity >= 4: |
|
|
|
weights = [w * (1 + (i % 3) * 0.2 * (self.intensity - 3)) for i, w in enumerate(weights)] |
|
|
|
|
|
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""" |
|
|
|
|
|
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" |
|
] |
|
|
|
|
|
if emotion == "negative": |
|
return random.choice(techniques[3:]) |
|
|
|
elif emotion == "positive": |
|
return random.choice(techniques[:4]) |
|
|
|
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 |
|
|