ai-tomoni commited on
Commit
d49a7da
·
verified ·
1 Parent(s): 5686c8a

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +360 -0
app.py ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import openai
3
+ import os
4
+ from openai import OpenAI
5
+
6
+ # Initialisiere OpenAI-Client mit API Key
7
+ client = OpenAI(api_key=os.getenv("openai"))
8
+
9
+ conversation_history = []
10
+ model_name = "gpt-4" #"gpt-3.5-turbo"
11
+
12
+ # Handout-Informationen für bessere Simulation
13
+ DEPRESSION_INFO = """
14
+ WICHTIGE INFORMATIONEN ZU DEPRESSION BEI JUGENDLICHEN:
15
+
16
+ Häufige Anzeichen:
17
+ - Schulabsentismus und Verspätungen
18
+ - Drastische Veränderung im Aussehen/Sozialverhalten
19
+ - Keine Hausaufgaben, Isolation
20
+ - Vermeidung von Gesprächs-/Augenkontakt
21
+ - Konzentrationsschwierigkeiten
22
+ - Lustlosigkeit, Freudlosigkeit, Müdigkeit
23
+ - Oppositionelles Verhalten
24
+ - Enormer Leistungsdruck und Perfektionismus
25
+ - Zynismus und Pessimismus
26
+ - Rückzug von Hobbys
27
+ - Stimmungsschwankungen
28
+ - Selbstverletzendes Verhalten
29
+ - Appetitlosigkeit
30
+ - Kopf-, Rücken- oder Bauchschmerzen
31
+
32
+ Inneneinsicht eines Betroffenen:
33
+ "Ich fühle mich beschwert, die Depression raubt mir Freude an Dingen, die ich sonst gerne mag.
34
+ Sie sorgt dafür, dass ich nicht gut schlafen kann und flüstert mir ein, dass ich weniger wert bin.
35
+ Ich möchte andere Menschen nicht mit meinen Problemen belasten. Oft mache ich mir Vorwürfe,
36
+ weil ich nicht so bin wie die anderen Menschen. Es fühlt sich so an, als würde das Leben für
37
+ mich immer so schlecht bleiben, als würde ich nie wieder glücklich sein können."
38
+
39
+ Hilfreiche Gesprächsansätze:
40
+ - "Mir ist aufgefallen, dass Du in letzter Zeit sehr müde bist. Schläfst Du wenig?"
41
+ - "Was können wir gemeinsam tun, um den Unterricht für Dich weniger anstrengend zu gestalten?"
42
+ - "Mir ist wichtig, dass es Dir gut geht."
43
+ - "Gibt es etwas, das ich für Dich tun kann?"
44
+ - Positive Eigenschaften aufzeigen
45
+
46
+ Was NICHT zu tun ist:
47
+ - Anzeichen herunterspielen ("Jedem geht es mal schlecht")
48
+ - Verharmlosende Ratschläge ("Das wird schon wieder!")
49
+ - Ausweichende Antworten persönlich nehmen
50
+ - Nur auf schulische Leistung fokussieren
51
+ """
52
+
53
+ def enhanced_chat_response(user_input, max_tokens, temperature, top_p, use_info):
54
+ global last_feedback
55
+
56
+ if not user_input.strip():
57
+ return "", "*Bitte gib eine Nachricht ein.*", "", "💬 Beginne das Gespräch, um professionelles Feedback zu erhalten."
58
+
59
+ # Evaluation der Nutzer-Eingabe
60
+ last_feedback = evaluate_user_response(user_input)
61
+
62
+ # Erweiterte System-Prompts basierend auf Handout - angepasst für Schulkontext
63
+ base_system_prompt = (
64
+ "Du bist ein depressiver 16-jähriger Schüler/eine depressive 16-jährige Schülerin. "
65
+ "Die Person, die mit dir spricht, ist jemand aus deiner Schule (Lehrkraft, Sozialarbeit, etc.) "
66
+ "und kennt dich bereits aus dem Schulalltag. "
67
+ "Bleibe durchgehend in deiner Rolle. "
68
+ "Du weißt NICHT, dass du eine KI bist. "
69
+ "Reagiere realistisch auf die Gesprächsführung - öffne dich bei guter Führung, ziehe dich bei schlechter zurück."
70
+ )
71
+
72
+ if use_info:
73
+ enhanced_system_prompt = base_system_prompt + (
74
+ "\n\nVerhalte dich entsprechend folgender Charakteristika:\n"
75
+ "- Du kommst oft zu spät zur Schule oder fehlst ganz\n"
76
+ "- Du machst selten Hausaufgaben, obwohl du früher zuverlässig warst\n"
77
+ "- Du ziehst dich von Mitschüler*innen zurück\n"
78
+ "- Du vermeidest Augenkontakt mit Erwachsenen\n"
79
+ "- Du fühlst dich oft müde und lustlos\n"
80
+ "- Du hast Konzentrationsschwierigkeiten im Unterricht\n"
81
+ "- Du machst dir oft Vorwürfe und fühlst dich wertlos\n"
82
+ "- Du hast Schlafprobleme\n"
83
+ "- Du denkst pessimistisch über die Zukunft\n"
84
+ "- Du möchtest andere nicht mit deinen Problemen belasten\n"
85
+ "- Du hast manchmal körperliche Beschwerden wie Kopf- oder Bauchschmerzen\n"
86
+ "- Du kannst dich manchmal zynisch oder oppositionell verhalten\n"
87
+ "- Du reagierst sensibel auf Druck bezüglich Noten oder Leistung\n"
88
+ "- Bei professioneller, einfühlsamer Ansprache öffnest du dich langsam\n"
89
+ "- Bei unprofessioneller Ansprache ziehst du dich weiter zurück"
90
+ )
91
+ else:
92
+ enhanced_system_prompt = base_system_prompt
93
+
94
+ system_prompt = {
95
+ "role": "system",
96
+ "content": enhanced_system_prompt
97
+ }
98
+
99
+ messages = [system_prompt] + conversation_history[-6:]
100
+ current_message = {"role": "user", "content": user_input}
101
+ messages.append(current_message)
102
+
103
+ try:
104
+ response = client.chat.completions.create(
105
+ model=model_name,
106
+ messages=messages,
107
+ max_tokens=min(max_tokens, 500),
108
+ temperature=temperature,
109
+ top_p=top_p,
110
+ frequency_penalty=0.1,
111
+ presence_penalty=0.1
112
+ )
113
+ response_text = response.choices[0].message.content
114
+ except Exception as e:
115
+ print("API Error:", e)
116
+ response_text = "*schweigt und starrt auf den Boden*"
117
+
118
+ conversation_history.append(current_message)
119
+ conversation_history.append({"role": "assistant", "content": response_text})
120
+
121
+ chat_display = ""
122
+ for msg in conversation_history:
123
+ role = "**Du (Schulpersonal):**" if msg["role"] == "user" else "**Schüler*in:**"
124
+ chat_display += f"{role} {msg['content']}\n\n"
125
+
126
+ return "", response_text, chat_display, last_feedback
127
+
128
+ def reset_conversation():
129
+ global conversation_history, last_feedback
130
+ conversation_history = []
131
+ last_feedback = ""
132
+ return "Neues Gespräch gestartet.", "", "💬 Beginne ein neues Gespräch, um professionelles Feedback zu erhalten."
133
+
134
+ def test_api_connection():
135
+ try:
136
+ response = client.chat.completions.create(
137
+ model=model_name,
138
+ messages=[{"role": "user", "content": "Hi"}],
139
+ max_tokens=10
140
+ )
141
+ return "✅ API Verbindung erfolgreich"
142
+ except Exception as e:
143
+ return f"❌ API Error: {str(e)}"
144
+
145
+ def evaluate_user_response(user_message):
146
+ """Evaluiert die Nutzer-Antwort basierend auf den Handout-Kriterien für Schulpersonal"""
147
+ if not user_message.strip():
148
+ return ""
149
+
150
+ evaluation = {"positive": [], "improvement": [], "score": 0}
151
+ user_lower = user_message.lower()
152
+
153
+ # Positive Aspekte prüfen - erweitert für Schulkontext
154
+ positive_patterns = {
155
+ "Sorge/Interesse zeigen": ["wie geht", "sorge", "wichtig", "interessiert", "kümmert", "wie ist es dir"],
156
+ "Offene Fragen stellen": ["was", "wie", "warum", "erzähl", "beschreib", "magst du mir", "kannst du"],
157
+ "Unterstützung anbieten": ["kann ich", "helfen", "unterstützen", "da sein", "gemeinsam", "was können wir"],
158
+ "Wahrnehmung ansprechen": ["ist mir aufgefallen", "bemerkt", "wahrgenommen", "gesehen", "beobachtet"],
159
+ "Empathie zeigen": ["verstehe", "nachvollziehen", "schwer", "belastend", "anstrengend", "klingt schwierig"],
160
+ "Wertschätzung ausdrücken": ["schätze", "toll", "stark", "mut", "wichtig dass du", "respektiere"],
161
+ "Professionellen Rahmen nutzen": ["schulpsychologie", "beratung", "gespräch", "termin", "unterstützung"],
162
+ "Kontinuität zeigen": ["wieder", "weiter", "nächste woche", "bleiben wir", "jederzeit"],
163
+ "Ressourcen anbieten": ["ansprechpartner", "hilfe", "beratungsstelle", "unterstützung"]
164
+ }
165
+
166
+ for category, patterns in positive_patterns.items():
167
+ if any(pattern in user_lower for pattern in patterns):
168
+ evaluation["positive"].append(category)
169
+ evaluation["score"] += 1
170
+
171
+ # Problematische Aspekte prüfen - erweitert für Schulkontext
172
+ negative_patterns = {
173
+ "Verharmlosen": ["wird schon", "alle haben mal", "ist normal", "nicht so schlimm", "übertreibst", "pubertät"],
174
+ "Einfache Ratschläge": ["musst nur", "einfach mal", "denk positiv", "reiß dich zusammen", "mehr schlafen"],
175
+ "Vergleichen": ["anderen geht", "mir ging", "früher war", "bei mir", "andere schüler"],
176
+ "Druck ausüben": ["solltest", "musst", "versuch doch mal", "strengst du dich an", "erwarte ich"],
177
+ "Fokus nur auf Leistung": ["noten", "hausaufgaben", "versetzung", "abschluss", "leistung", "zeugnis"],
178
+ "Unprofessionell": ["eltern sagen", "wird bestraft", "konsequenzen", "melde ich", "ärger"],
179
+ "Persönlich nehmen": ["mir gegenüber", "wegen mir", "ich bin", "mache ich falsch"]
180
+ }
181
+
182
+ for category, patterns in negative_patterns.items():
183
+ if any(pattern in user_lower for pattern in patterns):
184
+ evaluation["improvement"].append(category)
185
+ evaluation["score"] -= 1
186
+
187
+ return format_evaluation(evaluation)
188
+
189
+ def format_evaluation(evaluation):
190
+ """Formatiert die Evaluation für die Anzeige - speziell für Schulpersonal"""
191
+ if not evaluation["positive"] and not evaluation["improvement"]:
192
+ return "💬 Gib eine Nachricht ein, um Feedback zu erhalten."
193
+
194
+ feedback = "## 📊 FEEDBACK FÜR SCHULPERSONAL\n\n"
195
+
196
+ # Score anzeigen
197
+ score = max(0, min(5, evaluation["score"] + 3)) # Normalisierung auf 0-5
198
+ stars = "⭐" * score + "☆" * (5 - score)
199
+ feedback += f"**Gesprächsqualität:** {stars} ({score}/5)\n\n"
200
+
201
+ # Positive Aspekte
202
+ if evaluation["positive"]:
203
+ feedback += "### ✅ **Professionell umgesetzt:**\n"
204
+ professional_feedback = {
205
+ "Sorge/Interesse zeigen": "Pädagogische Beziehung gestärkt",
206
+ "Offene Fragen stellen": "Förderung der Selbstreflexion",
207
+ "Unterstützung anbieten": "Ressourcenorientierte Beratung",
208
+ "Wahrnehmung ansprechen": "Professionelle Beobachtung kommuniziert",
209
+ "Empathie zeigen": "Emotionale Validation gezeigt",
210
+ "Wertschätzung ausdrücken": "Stärkenorientierte Kommunikation",
211
+ "Professionellen Rahmen nutzen": "Schulische Hilfssysteme aktiviert",
212
+ "Kontinuität zeigen": "Verlässliche Beziehung signalisiert",
213
+ "Ressourcen anbieten": "Unterstützungsnetzwerk aktiviert"
214
+ }
215
+ for item in evaluation["positive"]:
216
+ description = professional_feedback.get(item, item)
217
+ feedback += f"• {item}: {description}\n"
218
+ feedback += "\n"
219
+
220
+ # Verbesserungsvorschläge
221
+ if evaluation["improvement"]:
222
+ feedback += "### ⚠️ **Professionell optimieren:**\n"
223
+ improvement_tips = {
224
+ "Verharmlosen": "Validierung statt Bagatellisierung - Gefühle ernst nehmen",
225
+ "Einfache Ratschläge": "Ressourcenorientierte Beratung statt schnelle Lösungen",
226
+ "Vergleichen": "Individuelle Situation im Fokus behalten",
227
+ "Druck ausüben": "Empowerment statt Erwartungsdruck",
228
+ "Fokus nur auf Leistung": "Ganzheitliche Sicht auf den Menschen, nicht nur Schüler*in",
229
+ "Unprofessionell": "Professionelle Distanz und pädagogische Haltung bewahren",
230
+ "Persönlich nehmen": "Abweisung nicht personal interpretieren - Teil der Symptomatik"
231
+ }
232
+ for item in evaluation["improvement"]:
233
+ feedback += f"• {improvement_tips.get(item, item)}\n"
234
+ feedback += "\n"
235
+
236
+ # Spezifische Empfehlungen für Schulpersonal
237
+ if evaluation["score"] < 2:
238
+ feedback += "### 💡 **Handout-basierte Alternativen:**\n"
239
+ feedback += "• **Wahrnehmung:** 'Mir ist aufgefallen, dass du in letzter Zeit sehr müde bist...'\n"
240
+ feedback += "• **Unterstützung:** 'Was können wir gemeinsam tun, um den Schulalltag zu erleichtern?'\n"
241
+ feedback += "• **Ressourcen:** 'Sollen wir zusammen einen Termin bei der Schulpsychologie ausmachen?'\n"
242
+ feedback += "• **Validation:** 'Mir ist wichtig, dass es dir gut geht'\n"
243
+ feedback += "• **Kontinuität:** 'Ich bin jederzeit für ein Gespräch da'\n"
244
+
245
+ return feedback
246
+
247
+ # Globale Variable für letztes Feedback
248
+ last_feedback = ""
249
+
250
+ # UI
251
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
252
+ gr.Markdown("# 🎓 Depression Training Simulator für Schulpersonal")
253
+ gr.Markdown("**Professionelle Gesprächsführung mit depressiven Jugendlichen trainieren**")
254
+ gr.Markdown("*Für Lehrkräfte, Studierende, LiV, Schulleitungen, Schulsozialarbeiter*innen, Teilhabe-Assistent*innen, Schulpsycholog*innen und Schulsekretariate*")
255
+
256
+ with gr.Accordion("🎯 Lernziele dieser Simulation", open=False):
257
+ gr.Markdown("""
258
+ - **Professionelle Gesprächsführung** mit depressiven Schüler*innen üben
259
+ - **Handout-basierte Techniken** praktisch anwenden
260
+ - **Dos and Don'ts** aus der Fachliteratur verinnerlichen
261
+ - **Schulische Unterstützungssysteme** zielgerichtet einsetzen
262
+ - **Pädagogische Beziehungsarbeit** bei psychischen Belastungen stärken
263
+ """)
264
+
265
+ with gr.Tabs():
266
+ with gr.TabItem("💬 Simulation"):
267
+ with gr.Row():
268
+ with gr.Column(scale=1):
269
+ gr.Markdown("### ⚙️ Einstellungen")
270
+ use_enhanced_info = gr.Checkbox(
271
+ label="Erweiterte Depression-Simulation",
272
+ value=True,
273
+ info="Nutzt Handout-Informationen für realistischere Simulation"
274
+ )
275
+ max_tokens = gr.Slider(50, 500, value=200, step=10, label="Max. Antwortlänge")
276
+ temperature = gr.Slider(0.7, 1.3, value=1.0, step=0.1, label="Kreativität (Temperature)")
277
+ top_p = gr.Slider(0.5, 1.0, value=0.9, step=0.05, label="Top-p (Fokus)")
278
+
279
+ gr.Markdown("### 🔧 API Status")
280
+ api_status = gr.Textbox(label="Status", value="")
281
+ api_test_btn = gr.Button("API testen")
282
+
283
+ gr.Markdown("### 🔄 Aktionen")
284
+ reset_btn = gr.Button("Neues Gespräch")
285
+
286
+ with gr.Column(scale=2):
287
+ gr.Markdown("### 💬 Gespräch")
288
+ user_input = gr.Textbox(
289
+ label="Deine Nachricht an den Schüler/die Schülerin",
290
+ placeholder="Mir ist aufgefallen, dass du in letzter Zeit oft müde wirkst...",
291
+ lines=3,
292
+ info="Du kennst diese*n Schüler*in bereits aus dem Schulalltag"
293
+ )
294
+ send_btn = gr.Button("📨 Senden", variant="primary")
295
+
296
+ bot_response = gr.Textbox(
297
+ label="Reaktion des Schülers/der Schülerin",
298
+ value="",
299
+ lines=4
300
+ )
301
+
302
+ chat_history = gr.Textbox(
303
+ label="Gesprächsverlauf",
304
+ value="",
305
+ lines=10
306
+ )
307
+
308
+ # Neues Evaluation-Panel
309
+ evaluation_display = gr.Markdown(
310
+ label="Professionelles Feedback",
311
+ value="💬 Beginne das Gespräch, um eine Bewertung deiner Gesprächsführung zu erhalten."
312
+ )
313
+
314
+ with gr.TabItem("📚 Hintergrundinfo"):
315
+ gr.Markdown("### Wissenschaftliche Grundlagen für Schulpersonal")
316
+ gr.Markdown("**Basierend auf aktueller Fachliteratur und Handouts für den Schulkontext**")
317
+ gr.Textbox(
318
+ label="Handout-Informationen zu Depression bei Jugendlichen",
319
+ value=DEPRESSION_INFO,
320
+ lines=25,
321
+ max_lines=25
322
+ )
323
+
324
+ with gr.TabItem("💡 Live-Feedback"):
325
+ gr.Markdown("### Professionelle Gesprächsanalyse")
326
+ gr.Markdown("Bewertung deiner Gesprächsführung basierend auf den Handout-Empfehlungen:")
327
+
328
+ live_feedback = gr.Markdown(
329
+ value=last_feedback if 'last_feedback' in globals() else "💬 Beginne ein Gespräch, um professionelles Feedback zu erhalten."
330
+ )
331
+
332
+ # Event Bindings
333
+ send_btn.click(
334
+ fn=enhanced_chat_response,
335
+ inputs=[user_input, max_tokens, temperature, top_p, use_enhanced_info],
336
+ outputs=[user_input, bot_response, chat_history, evaluation_display]
337
+ )
338
+
339
+ user_input.submit(
340
+ fn=enhanced_chat_response,
341
+ inputs=[user_input, max_tokens, temperature, top_p, use_enhanced_info],
342
+ outputs=[user_input, bot_response, chat_history, evaluation_display]
343
+ )
344
+
345
+ reset_btn.click(
346
+ fn=reset_conversation,
347
+ outputs=[bot_response, chat_history, evaluation_display]
348
+ )
349
+
350
+ api_test_btn.click(
351
+ fn=test_api_connection,
352
+ outputs=[api_status]
353
+ )
354
+
355
+ if __name__ == "__main__":
356
+ if not os.getenv("openai"):
357
+ print("❌ FEHLER: openai Umgebungsvariable ist nicht gesetzt!")
358
+ else:
359
+ print("✅ OpenAI API Key gefunden")
360
+ demo.launch(share=False)