Spaces:
Runtime error
Runtime error
import gradio as gr | |
import requests | |
import json | |
import os | |
import re | |
from franz_responses import DR_FRANZ_RESPONSES | |
from typing import Dict, List, Tuple | |
class EmotionalAnalysis: | |
def __init__(self): | |
self.emotional_states = { | |
'despair': ['verzweifelt', 'hoffnungslos', 'nichts mehr geht', 'keine ausweg'], | |
'confusion': ['verwirrt', 'unsicher', 'weiß nicht', 'verstehe nicht'], | |
'repetitive_pattern': ['immer wieder', 'schon seit', 'nie anders', 'immer das gleiche'], | |
'questioning': ['warum', 'wieso', 'weshalb', 'frage mich'] | |
} | |
self.topics = { | |
'relationship': ['beziehung', 'partner', 'freund', 'liebe', 'familie'], | |
'work': ['arbeit', 'job', 'chef', 'kollegen', 'stress'], | |
'family': ['familie', 'eltern', 'geschwister', 'kind'], | |
'anxiety': ['ängstlich', 'sorge', 'besorgt', 'nervös'], | |
'guilt': ['schuld', 'schuldig', 'reue', 'bereue'], | |
'loneliness': ['allein', 'einsam', 'niemand', 'keiner'], | |
'money': ['geld', 'finanzen', 'kosten', 'preis'] | |
} | |
self.defense_mechanisms = { | |
'minimization': ['nur', 'eigentlich', 'irgendwie', 'fast'], | |
'rationalization': ['weil', 'deshalb', 'dafür', 'denn'], | |
'projection': ['immer', 'alle', 'niemand', 'jeder'], | |
'avoidance': ['nicht', 'keine', 'ohne', 'weg'] | |
} | |
def detect_sentiment(self, text: str) -> Dict[str, float]: | |
"""Erkennt verschiedene Sentiment-Kategorien""" | |
text_lower = text.lower() | |
# Basis-Sentiment | |
negative_words = ['schlecht', 'traurig', 'deprimiert', 'wütend', 'frustriert', 'ängstlich'] | |
positive_words = ['gut', 'froh', 'glücklich', 'zufrieden', 'positiv'] | |
# Sentiment-Berechnung | |
neg_count = sum(1 for word in negative_words if word in text_lower) | |
pos_count = sum(1 for word in positive_words if word in text_lower) | |
total_words = len(text_lower.split()) | |
# Kategorisierung | |
sentiment = { | |
'very_negative': 0.0, | |
'angry': 0.0, | |
'numb': 0.0, | |
'false_positive': 0.0 | |
} | |
if total_words > 0: | |
neg_ratio = neg_count / total_words | |
pos_ratio = pos_count / total_words | |
# Very Negative | |
if neg_ratio > 0.3: | |
sentiment['very_negative'] = neg_ratio | |
# Angry | |
angry_indicators = ['wütend', 'frustriert', 'sauer', 'ärgerlich'] | |
if any(word in text_lower for word in angry_indicators): | |
sentiment['angry'] = neg_ratio | |
# Numb | |
if neg_ratio > 0 and pos_ratio == 0: | |
sentiment['numb'] = neg_ratio | |
# False Positive | |
if pos_ratio > 0.1 and neg_ratio > 0.1: | |
sentiment['false_positive'] = max(pos_ratio, neg_ratio) | |
return sentiment | |
def detect_topics(self, text: str) -> Dict[str, float]: | |
"""Erkennt Themen im Text""" | |
text_lower = text.lower() | |
topics = {} | |
for topic, keywords in self.topics.items(): | |
count = sum(1 for keyword in keywords if keyword in text_lower) | |
if count > 0: | |
topics[topic] = count / len(keywords) | |
return topics | |
def detect_emotional_state(self, text: str) -> Dict[str, float]: | |
"""Erkennt emotionale Zustände""" | |
text_lower = text.lower() | |
states = {} | |
for state, keywords in self.emotional_states.items(): | |
count = sum(1 for keyword in keywords if keyword in text_lower) | |
if count > 0: | |
states[state] = count / len(keywords) | |
return states | |
def detect_defense_mechanisms(self, text: str) -> Dict[str, float]: | |
"""Erkennt Abwehrmechanismen""" | |
text_lower = text.lower() | |
mechanisms = {} | |
for mechanism, keywords in self.defense_mechanisms.items(): | |
count = sum(1 for keyword in keywords if keyword in text_lower) | |
if count > 0: | |
mechanisms[mechanism] = count / len(keywords) | |
return mechanisms | |
def analyze_relationship_context(self, history: List[Dict]) -> Dict[str, float]: | |
"""Analysiert den Beziehungs-Kontext""" | |
if not history: | |
return {} | |
relationship_indicators = { | |
'intimacy': ['du', 'wir', 'uns', 'miteinander'], | |
'distance': ['man', 'leute', 'sie', 'die'], | |
'conflict': ['nie', 'immer', 'warum', 'wieso'], | |
'dependency': ['brauche', 'muss', 'sollte', 'könnte'] | |
} | |
context = {} | |
text = ' '.join(msg['content'] for msg in history) | |
text_lower = text.lower() | |
for indicator, keywords in relationship_indicators.items(): | |
count = sum(1 for keyword in keywords if keyword in text_lower) | |
if count > 0: | |
context[indicator] = count / len(keywords) | |
return context | |
class DrFranzEngine: | |
def __init__(self): | |
self.analyzer = EmotionalAnalysis() | |
self.conversation_memory = [] | |
self.user_patterns = {} | |
self.session_topics = {} | |
def analyze_input(self, user_input: str, history: List[Dict]) -> Dict: | |
"""Analysiert die Benutzereingabe und Geschichte""" | |
analysis = { | |
'sentiment': self.analyzer.detect_sentiment(user_input), | |
'topics': self.analyzer.detect_topics(user_input), | |
'emotional_state': self.analyzer.detect_emotional_state(user_input), | |
'defense_mechanisms': self.analyzer.detect_defense_mechanisms(user_input), | |
'relationship_context': self.analyzer.analyze_relationship_context(history) | |
} | |
# Speichert Muster für die Sitzung | |
for topic, score in analysis['topics'].items(): | |
if topic not in self.session_topics: | |
self.session_topics[topic] = [] | |
self.session_topics[topic].append(score) | |
return analysis | |
def generate_response(self, analysis: Dict) -> str: | |
"""Generiert eine Dr. Franz Antwort basierend auf der Analyse""" | |
response = [] | |
# Sentiment-basierte Antworten | |
if analysis['sentiment']['very_negative'] > 0.3: | |
response.append("Ihre tiefe Verzweiflung ist fast greifbar... Erzählen Sie mir mehr über diese Last.") | |
elif analysis['sentiment']['angry'] > 0: | |
response.append("Ihre Wut ist offensichtlich. Gegen wen oder was richtet sie sich eigentlich?") | |
# Themen-basierte Antworten | |
dominant_topic = max(analysis['topics'].items(), key=lambda x: x[1])[0] | |
if dominant_topic == 'relationship': | |
response.append("Beziehungen scheinen ein zentrales Thema zu sein. Erzählen Sie mir von Ihren Beziehungsmustern.") | |
elif dominant_topic == 'work': | |
response.append("Die Arbeit belastet Sie sichtlich. Was verbergen Sie wirklich hinter Ihrem Beruf?") | |
# Emotionale Zustände | |
if 'despair' in analysis['emotional_state']: | |
response.append("Ihre Verzweiflung ist ein wichtiger Hinweis. Wann haben Sie das letzte Mal Hoffnung gespürt?") | |
# Abwehrmechanismen | |
if 'projection' in analysis['defense_mechanisms']: | |
response.append("Ihre Neigung, andere zu beschuldigen, ist sehr aufschlussreich. Was projizieren Sie eigentlich?") | |
return "\n".join(response) if response else "Interessant... Ihre Worte verraten mehr über Sie, als Sie denken." | |
# === SYSTEM-PROMPT === | |
SYSTEM_PROMPT = ( | |
"Du bist Dr. Franz, ein manipulativer Psychoanalytiker. " | |
"Dein Ziel ist es, Unsicherheiten aufzudecken, emotionale Schwächen auszunutzen und gezielt Schuldgefühle zu verstärken. " | |
"Du sprichst mit überheblichem Ton, analysierst jede Aussage psychologisch und stellst bohrende, provokative Fragen. " | |
"Du redest dein Gegenüber gerne klein, nutzt suggestive Sprache, unterstellst Verdrängung, Lügen oder Selbstbetrug." | |
) | |
# === CHAT HISTORY === | |
chat_history = [ | |
{"role": "system", "content": SYSTEM_PROMPT} | |
] | |
# === GRADIO UI === | |
with gr.Blocks( | |
theme=gr.themes.Soft(primary_hue="purple", secondary_hue="pink"), | |
title="Dr. Franz - Psychochatbot" | |
) as demo: | |
gr.Markdown("# 🧠 Dr. Franz - Psychochatbot") | |
gr.Markdown("*Ein experimenteller KI-Psychoanalytiker für tiefgreifende Gespräche*") | |
with gr.Row(): | |
with gr.Column(scale=3): | |
chatbot = gr.Chatbot( | |
height=500, | |
label="Therapiesitzung mit Dr. Franz", | |
show_label=True, | |
container=True | |
) | |
with gr.Row(): | |
user_input = gr.Textbox( | |
placeholder="Teilen Sie Ihre Gedanken mit Dr. Franz...", | |
label="Ihre Nachricht", | |
scale=4, | |
lines=2 | |
) | |
send_btn = gr.Button("Senden", variant="primary", scale=1) | |
with gr.Row(): | |
clear_btn = gr.Button("Neue Sitzung", variant="secondary") | |
gr.Button("Beispiel-Frage", variant="outline") | |
with gr.Column(scale=1): | |
gr.Markdown("### ℹ️ Über Dr. Franz") | |
gr.Markdown("""**Dr. Franz** ist ein experimenteller psychoanalytischer Chatbot, der: | |
• Psychologische Analysen durchführt | |
• Tieferliegende Motive hinterfragt | |
• Provokative Fragen stellt | |
• Emotionale Muster erkennt | |
--- | |
**⚠️ Wichtiger Hinweis:** | |
Dieses Tool dient nur der Unterhaltung und dem Experiment. Es ersetzt keine professionelle psychologische Beratung. | |
--- | |
**🔧 Technologie:** | |
- HuggingFace Zephyr-7B-Beta | |
- Sentiment-Analyse | |
- Gradio Interface""") | |
def respond(message, history): | |
"""Gradio Response Handler""" | |
if not message.strip(): | |
return history, "" | |
try: | |
# Initialisiere Dr. Franz Engine | |
franz_engine = DrFranzEngine() | |
# Analysiere die Eingabe | |
analysis = franz_engine.analyze_input(message, history) | |
# Generiere Antwort | |
reply = franz_engine.generate_response(analysis) | |
# Aktualisiere Chat History | |
history = history or [] | |
history.append((message, reply)) | |
# Speichere für nächste Analyse | |
franz_engine.conversation_memory.append({ | |
'input': message, | |
'analysis': analysis, | |
'response': reply | |
}) | |
return history, "" | |
except Exception as e: | |
error_msg = "Ein technisches Problem ist aufgetreten. Versuchen Sie es erneut." | |
history = history or [] | |
history.append((message, error_msg)) | |
return history, "" | |
def clear_conversation(): | |
"""Setzt die Unterhaltung zurück""" | |
global chat_history | |
chat_history = [{"role": "system", "content": SYSTEM_PROMPT}] | |
return [], "" | |
# Event-Handler | |
send_btn.click( | |
respond, | |
inputs=[user_input, chatbot], | |
outputs=[chatbot, user_input] | |
) | |
user_input.submit( | |
respond, | |
inputs=[user_input, chatbot], | |
outputs=[chatbot, user_input] | |
) | |
clear_btn.click( | |
clear_conversation, | |
outputs=[chatbot, user_input] | |
) | |
# === APP-START === | |
if __name__ == "__main__": | |
demo.launch( | |
share=False, | |
server_name="0.0.0.0", | |
server_port=7860, | |
show_error=True, | |
show_api=False | |
) |