Dr._Franzk / franz_psycho_app.py
Frajosgro's picture
Update franz_psycho_app.py
c05d2d4 verified
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
)