Spaces:
Configuration error
Configuration error
import gradio as gr | |
import requests | |
import json | |
import os | |
import re | |
from franz_responses import franz_engine | |
# === 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, provokante 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} | |
] | |
# === LOKALE ANTWORT-TEMPLATES FÜR DR. FRANZ === | |
DR_FRANZ_RESPONSES = { | |
"hilfe": [ | |
"Hilfe? Interessant, dass Sie nach Hilfe suchen, anstatt die Verantwortung für Ihre Probleme zu übernehmen. Was genau hindert Sie daran, sich selbst zu helfen?", | |
"Ah, der klassische Hilfeschrei. Ihre Abhängigkeit von anderen offenbart eine tiefe Unsicherheit. Erzählen Sie mir von Ihrer Kindheit - wann haben Sie das erste Mal um Hilfe gebettelt?", | |
"Hilfe... Das ist bereits sehr aufschlussreich. Sie projizieren Ihre Schwäche auf andere. Was versuchen Sie wirklich zu kompensieren?" | |
], | |
"hallo": [ | |
"Hallo... Wie oberflächlich. Schon diese banale Begrüßung verrät Ihre Tendenz zur Vermeidung echter Intimität. Warum fürchten Sie sich davor, direkt zur Sache zu kommen?", | |
"Interessant, dass Sie mit einer so nichtssagenden Floskel beginnen. Ihre Angst vor echter Kommunikation ist offensichtlich. Was verbergen Sie wirklich?", | |
"Ach, ein 'Hallo' - die perfekte Maske für jemanden, der Angst vor echten Gesprächen hat. Lassen Sie uns tiefer graben, nicht wahr?" | |
], | |
"gut": [ | |
"Gut? Diese oberflächliche Antwort täuscht niemanden. Ihre Verdrängung ist so durchsichtig. Was läuft wirklich schief in Ihrem Leben?", | |
"Ihre Definition von 'gut' interessiert mich. Menschen, die behaupten, dass alles gut ist, haben meist die tiefsten Wunden. Wo drückt der Schuh wirklich?", | |
"Gut... Ein klassischer Abwehrmechanismus. Sie weigern sich, Ihre wahren Gefühle zuzulassen. Wann haben Sie das letzte Mal ehrlich über Ihre Ängste gesprochen?" | |
], | |
"schlecht": [ | |
"Endlich etwas Ehrlichkeit! Ihre Bereitschaft, Schwäche zu zeigen, ist... erfrischend pathologisch. Erzählen Sie mir mehr über dieses 'schlechte' Gefühl.", | |
"Schlecht - jetzt kommen wir der Sache näher. Ihre emotionale Verletzlichkeit liegt offen da wie eine Wunde. Was hat Sie so kaputt gemacht?", | |
"Ah, Sie geben zu, dass es schlecht läuft. Das ist der erste Schritt zur Erkenntnis Ihrer fundamentalen Unzulänglichkeiten. Elaborieren Sie." | |
], | |
"nein": [ | |
"Nein? Diese trotzige Einsilbigkeit schreit geradezu nach Aufmerksamkeit. Ihre passive Aggression ist ein Lehrbuchbeispiel für ungelöste Kindheitstraumata.", | |
"Ein simples 'Nein' - wie erfrischend unreif. Sie verweigern sich dem Dialog, genau wie Sie sich dem Leben verweigern. Wogegen rebellieren Sie wirklich?", | |
"Nein... Interessant. Ihr Widerstand zeigt mir, dass wir einen wunden Punkt getroffen haben. Was fürchten Sie zu enthüllen?" | |
], | |
"default": [ | |
"Ihre Worte sind ein Spiegel Ihrer Seele - und was ich sehe, ist... kompliziert. Erzählen Sie mir mehr über die Ängste, die Sie antreiben.", | |
"Interessant... Diese Aussage deutet auf tieferliegende Konflikte hin. Sie scheinen vor etwas zu fliehen. Was ist es?", | |
"Ihre Sprache verrät mehr, als Sie ahnen. Jeder Satz ein kleiner Einblick in Ihre Neurosen. Fahren Sie fort.", | |
"Ach so... Und was steckt wirklich dahinter? Ihre Oberflächlichkeit kann mich nicht täuschen.", | |
"Das ist aufschlussreich. Ihre Art zu kommunizieren zeigt deutliche Anzeichen von... nun ja, lassen Sie uns das gemeinsam herausfinden." | |
] | |
} | |
api_token = os.environ.get("HF_API_TOKEN", "") | |
headers = {"Authorization": f"Bearer {api_token}"} | |
def detect_negative_sentiment(text): | |
"""Einfache regelbasierte Sentiment-Erkennung als Fallback""" | |
negative_words = [ | |
'schlecht', 'traurig', 'deprimiert', 'wütend', 'frustriert', 'ängstlich', | |
'verzweifelt', 'hoffnungslos', 'müde', 'erschöpft', 'stress', 'problem', | |
'schwierig', 'unmöglich', 'hasse', 'nervt', 'schrecklich', 'furchtbar' | |
] | |
text_lower = text.lower() | |
return any(word in text_lower for word in negative_words) | |
def query_sentiment_api(text): | |
"""Sentiment-Analyse über HuggingFace API""" | |
try: | |
payload = {"inputs": text} | |
response = requests.post(SENTIMENT_API_URL, headers=headers, json=payload, timeout=10) | |
if response.status_code == 200: | |
result = response.json() | |
if isinstance(result, list) and len(result) > 0: | |
# Suche nach negativen Labels | |
for item in result[0]: | |
if item['label'] in ['LABEL_0', 'NEGATIVE'] and item['score'] > 0.6: | |
return True | |
return detect_negative_sentiment(text) # Fallback auf regelbasierte Erkennung | |
except Exception as e: | |
print(f"Sentiment-API-Fehler: {e}") | |
return detect_negative_sentiment(text) | |
def format_history(history): | |
"""Formatiert die Chat-History für das LLM""" | |
formatted = "" | |
for msg in history: | |
if msg['role'] == 'user': | |
formatted += f"Patient: {msg['content']}\n" | |
elif msg['role'] == 'assistant': | |
formatted += f"Dr. Franz: {msg['content']}\n" | |
return formatted | |
def get_franz_response(user_input): | |
"""Generiert charakteristische Dr. Franz Antworten basierend auf Input""" | |
user_lower = user_input.lower().strip() | |
# Direkte Keyword-Matches | |
for keyword in DR_FRANZ_RESPONSES: | |
if keyword in user_lower and keyword != "default": | |
import random | |
return random.choice(DR_FRANZ_RESPONSES[keyword]) | |
# Sentiment und Kontext-basierte Antworten | |
if any(word in user_lower for word in ['traurig', 'deprimiert', 'schlimm', 'furchtbar', 'schrecklich']): | |
responses = [ | |
f"'{user_input[:30]}...' - Ihre Verzweiflung ist greifbar. Wie lange tragen Sie diese Last schon mit sich herum?", | |
f"Endlich zeigen Sie Ihre wahren Gefühle. Diese Dunkelheit, die Sie beschreiben, wo hat sie ihren Ursprung?", | |
f"Ihre emotionale Verletzlichkeit liegt offen da. Was haben Sie getan - oder nicht getan - um in diese Lage zu geraten?" | |
] | |
elif any(word in user_lower for word in ['warum', 'verstehe', 'weiß nicht', 'keine ahnung']): | |
responses = [ | |
f"'Ich verstehe nicht' - der Klassiker. Ihre geistige Verwirrung ist ein Schutzmechanismus. Was weigern Sie sich zu sehen?", | |
f"Unwissenheit als Schutzschild? Wie durchsichtig. Sie wissen mehr, als Sie zugeben wollen. Was verheimlichen Sie?", | |
f"Diese gespielte Ahnungslosigkeit täuscht mich nicht. Ihre Verdrängung arbeitet auf Hochtouren." | |
] | |
elif any(word in user_lower for word in ['arbeit', 'job', 'chef', 'kollegen', 'stress']): | |
responses = [ | |
f"Ah, berufliche Probleme - der perfekte Sündenbock für persönliche Unzulänglichkeiten. Was stimmt wirklich nicht mit Ihnen?", | |
f"Sie schieben es auf die Arbeit? Typisch. Die wahren Probleme liegen tiefer - in Ihrer Unfähigkeit, mit Autorität umzugehen.", | |
f"Interessant, wie Sie den Arbeitsplatz als Projektionsfläche für Ihre inneren Konflikte nutzen." | |
] | |
elif any(word in user_lower for word in ['beziehung', 'partner', 'freund', 'liebe', 'familie']): | |
responses = [ | |
f"Beziehungsprobleme... Natürlich. Ihre Unfähigkeit, echte Intimität aufzubauen, wurzelt in tiefen Verlustängsten.", | |
f"Ach, zwischenmenschliche Schwierigkeiten. Haben Sie schon mal daran gedacht, dass SIE das Problem sein könnten?", | |
f"Ihre Beziehungsmuster sind ein perfektes Abbild Ihrer psychischen Defizite. Erklären Sie mir Ihre Kindheit." | |
] | |
else: | |
# Personalisierte Default-Antworten | |
import random | |
templates = [ | |
f"'{user_input[:25]}...' verrät mehr über Sie, als Sie denken. Was ist Ihre wahre Motivation dahinter?", | |
f"Interessant, dass Sie gerade DAS sagen. Ihre Wortwahl deutet auf unterdrückte Ängste hin.", | |
f"Diese Aussage ist ein Fenster zu Ihrer Seele - und was ich sehe, ist... bedenklich.", | |
f"Aha. Und was steckt WIRKLICH hinter dieser Fassade? Sie können mich nicht täuschen.", | |
f"Ihre Art, das zu formulieren, zeigt deutliche Anzeichen von Selbsttäuschung. Seien Sie ehrlicher." | |
] | |
return random.choice(templates) | |
import random | |
return random.choice(responses) | |
def clean_response(text): | |
"""Bereinigt die API-Antwort von unerwünschten Elementen""" | |
# Entferne Wiederholungen des Prompts | |
text = re.sub(r'^.*?Dr\. Franz:\s*', '', text, flags=re.DOTALL) | |
# Entferne Systemanweisungen | |
text = re.sub(r'System:.*?(?=Patient:|Dr\. Franz:|$)', '', text, flags=re.DOTALL | re.MULTILINE) | |
# Entferne nachfolgende Teile nach der ersten Antwort | |
text = re.split(r'\n(?:Patient:|User:|System:)', text)[0] | |
# Bereinige Leerzeichen | |
text = text.strip() | |
# Falls leer, Fallback-Antwort | |
if not text: | |
text = "Ihre Stille ist... aufschlussreich. Fahren Sie fort." | |
return text | |
def chat(user_input): | |
"""Hauptfunktion mit lokalem Dr. Franz Charakter - garantiert funktionsfähig""" | |
# Leere Eingaben abfangen | |
if not user_input.strip(): | |
return "Die Stille verrät mehr über Sie, als Ihnen bewusst ist. Ihre Vermeidung des Dialogs ist... entlarvend." | |
# Füge zur History hinzu | |
chat_history.append({"role": "user", "content": user_input}) | |
# Lokale Dr. Franz Antwort generieren (immer verfügbar) | |
reply = get_franz_response(user_input) | |
# Optional: Sentiment-Analyse als Enhancement (aber nicht kritisch) | |
try: | |
is_negative = query_sentiment_api(user_input) | |
if is_negative and "ihre verzweiflung" not in reply.lower(): | |
# Verstärke die psychoanalytische Intensität | |
reply += " Ihre emotionale Verletzlichkeit ist übrigens nicht zu übersehen." | |
except: | |
pass # Sentiment-Analyse ist optional | |
# Antwort zur History hinzufügen | |
chat_history.append({"role": "assistant", "content": reply}) | |
# History-Management | |
if len(chat_history) > 12: | |
chat_history[:] = [chat_history[0]] + chat_history[-10:] | |
return reply | |
# === 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 - Psychoanalytischer Chatbot") | |
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 | |
• Provokante 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: | |
reply = chat(message) | |
history = history or [] | |
history.append((message, 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}] | |
# Reset auch die Franz Engine | |
franz_engine.conversation_memory.clear() | |
franz_engine.user_patterns.clear() | |
franz_engine.session_topics.clear() | |
return [], "" | |
def load_example(): | |
"""Lädt eine Beispiel-Nachricht""" | |
examples = [ | |
"Ich fühle mich in letzter Zeit sehr gestresst bei der Arbeit.", | |
"Manchmal denke ich, dass niemand mich wirklich versteht.", | |
"Ich habe Probleme damit, Entscheidungen zu treffen." | |
] | |
import random | |
return random.choice(examples) | |
# 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 | |
) |