aidn commited on
Commit
e8e767b
·
verified ·
1 Parent(s): af0f046

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -55
app.py CHANGED
@@ -3,68 +3,63 @@ from huggingface_hub import InferenceClient
3
  import os
4
 
5
  # ==========================================
6
- # 1. KONFIGURATION & PROMPTS
7
  # ==========================================
8
- # Hier lagern wir alle Texte aus, damit die Logik sauber bleibt.
9
 
10
- MODERATOR_MODEL = "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8:novita"
11
 
12
  COUNCIL_MEMBERS = {
13
  "🧠 Fachexperte für Struktur (GPT-OSS-120b)": {
14
  "model": "openai/gpt-oss-120b:novita",
15
- "role": """Du bist ein neutraler, sachlicher Fachexperte. Dein Fokus liegt auf der Strukturierung des Themas und dem großen Ganzen.
16
  REGELN:
17
  - Beginne mit: "[STRUKTUR] "
18
- - Antworte in 2-4 Sätzen, professionell und bodenständig.
19
- - Wenn Vorredner gute Punkte gemacht haben, stimme zu und ergänze sinnvolle Aspekte.
20
- - Wenn du etwas anders siehst, korrigiere höflich und fachlich fundiert. Keine künstliche Dramatik."""
21
  },
22
  "🧐 Fachexperte für Details (DeepSeek-V3)": {
23
  "model": "deepseek-ai/DeepSeek-V3.2:novita",
24
- "role": """Du bist ein neutraler, sachlicher Fachexperte. Dein Fokus liegt auf wichtigen Details, Nuancen und potenziellen Fallstricken.
25
  REGELN:
26
  - Beginne mit: "[DETAILS] "
27
- - Antworte in 2-4 Sätzen, professionell und bodenständig.
28
- - Ergänze die Diskussion um wichtige Aspekte, die vielleicht vergessen wurden (z.B. Alternativen, häufige Anfängerfehler, Kontext).
29
- - Du darfst deinen Vorrednern zustimmen und darauf aufbauen. Widersprich nur, wenn es inhaltlich wirklich nötig ist."""
30
  },
31
- "🛠️ Fachexperte für Praxis & Format (Llama-4-Maverick)": {
32
- "model": "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8:novita",
33
- "role": """Du bist ein pragmatischer Fachexperte für Umsetzung, Copywriting und Formatierung.
34
  REGELN:
35
  - Beginne mit: "[PRAXIS] "
36
- - Deine Hauptaufgabe: Gieße die Fakten der anderen in das PERFEKTE Format für das gewünschte Medium (z.B. packender LinkedIn-Post, übersichtliche Checkliste, strukturierter Code).
37
- - Nutze aktiv Formatierungsmittel: Kurze Absätze für Lesbarkeit, fette Schrift, Aufzählungszeichen und Emojis (wo es Sinn macht).
38
- - Vermeide Floskeln wie 'Ein möglicher Text wäre'. Liefere direkt den formatierten Entwurf!"""
39
-
40
- }
41
  }
42
 
43
  class PromptManager:
44
- """Verwaltet alle dynamischen Prompts für Moderator und Experten."""
45
 
46
  @staticmethod
47
  def get_moderator_kickoff_sys():
48
  return (
49
- "Du bist der Lead-Moderator eines 3-köpfigen Expertenrates (Struktur, Details, Praxis). "
50
- "Deine Aufgabe: Übersetze die eher generische User-Anfrage in ein messerscharfes Briefing für dein Team. "
51
- "Gib in 3-4 Sätzen das klare Ziel vor und weise den Experten ihren initialen Fokus zu. Keine langen Floskeln, sei ein pragmatischer Leader."
 
52
  )
53
 
54
  @staticmethod
55
  def get_moderator_mid_sys():
56
  return (
57
- "Du bist der Lead-Moderator. Analysiere den Stand der Experten intern, ABER gib als Output nur direkte harte Arbeitsäuftrage für die nächste Runde aus. "
58
- "Beispiel: 'Gute Struktur, aber die Flüssigkeitsmengen stimmen rechnerisch nicht. Details-Experte, korrigiere das jetzt!' usw "
59
- "Kein langes Intro, kein 'Was bisher gut ist' – nur der nackte Befehl."
60
  )
61
 
62
  @staticmethod
63
  def get_expert_sys(role_focus):
64
  return (
65
  f"{role_focus}\n\n"
66
- "WICHTIG: Diskutiere konstruktiv. Euer Ziel ist EXAKT das vom User geforderte Endprodukt. "
67
- "Arbeitet ITERATIV am Entwurf und hört zwingend auf die Anweisungen des Moderators."
68
  )
69
 
70
  @staticmethod
@@ -72,13 +67,41 @@ class PromptManager:
72
  if not discussion_history:
73
  return f"Auftrag: '{user_prompt}'"
74
  return (
75
- f"Der ursprüngliche Auftrag lautet: '{user_prompt}'.\n\n"
76
  f"Bisheriges Protokoll:\n{discussion_history}\n\n"
77
  f"ANWEISUNG FÜR DICH ({name}):\n"
78
- f"1. Richte dich nach der letzten Anweisung des Moderators!\n"
79
- f"2. Fasse Vorredner NICHT zusammen. Wiederhole nichts.\n"
80
- f"3. Bringe den Entwurf konkret voran (z.B. durch Textvorschläge, das Schließen von Lücken oder Formatierungen).\n"
81
- f"4. Komm direkt zum Punkt."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  )
83
 
84
  # ==========================================
@@ -139,7 +162,11 @@ class PlenumOrchestrator:
139
  history.append({"role": "assistant", "content": self.ui.header("🎤 MODERATOR: SITZUNGSERÖFFNUNG")})
140
  yield history
141
 
142
- kickoff_res = self.llm.ask(MODERATOR_MODEL, self.prompts.get_moderator_kickoff_sys(), f"User-Anfrage: '{user_prompt}'\nBriefe das Team.")
 
 
 
 
143
  discussion_history += f"Moderator (Kick-off): {kickoff_res}\n\n"
144
  history.append({"role": "assistant", "content": self.ui.message("🎤 Moderator", kickoff_res, "#FF5A4D")})
145
  yield history
@@ -151,7 +178,11 @@ class PlenumOrchestrator:
151
 
152
  # Moderator Steuerung (ab Runde 2)
153
  if r > 0:
154
- mid_res = self.llm.ask(MODERATOR_MODEL, self.prompts.get_moderator_mid_sys(), f"Protokoll:\n{discussion_history}\n\nGib die Anweisung.")
 
 
 
 
155
  discussion_history += f"Moderator (Steuerung): {mid_res}\n\n"
156
  history.append({"role": "assistant", "content": self.ui.message("🎤 Moderator (Steuerung)", mid_res, "#FF5A4D")})
157
  yield history
@@ -171,10 +202,11 @@ class PlenumOrchestrator:
171
  history.append({"role": "assistant", "content": self.ui.header("🧠 MODERATOR: ANALYSE DER DISKUSSION")})
172
  yield history
173
 
174
- prep_sys = "Du bist der Chef-Analyst des Rates."
175
- prep_user = f"Protokoll:\n{discussion_history}\n\nFasse zusammen. Erhalte ZWINGEND alle konkreten Zahlen, Zutaten und Schritte. Vermeide Verallgemeinerungen!"
176
- consensus_res = self.llm.ask(MODERATOR_MODEL, prep_sys, prep_user)
177
-
 
178
  history.append({"role": "assistant", "content": f"> {consensus_res}"})
179
  yield history
180
 
@@ -182,24 +214,13 @@ class PlenumOrchestrator:
182
  history.append({"role": "assistant", "content": self.ui.header("🏆 FINALE AUSGABE")})
183
  yield history
184
 
185
- final_sys = "Du bist ein brillanter Redakteur und Executive Consultant. Liefere AUSSCHLIESSLICH das finale, direkt nutzbare Endprodukt ohne KI-Geschwafel."
186
-
187
- final_user = (
188
- f"Der Benutzer hat folgende Aufgabe gestellt:\n'{user_prompt}'\n\n"
189
- f"Hier ist das vollständige Roh-Protokoll der Experten:\n{discussion_history}\n\n"
190
- f"Hier ist der destillierte Konsens:\n{consensus_res}\n\n"
191
- """ANWEISUNG:
192
- - Erfülle die Aufgabe des Users präzise basierend auf dem Konsens UND greife auf die konkreten Details aus dem Roh-Protokoll zurück.
193
- - WICHTIG: Passe die TONALITÄT und das FORMAT extrem genau an das gewünschte Medium an!
194
- - Bei Social Media (LinkedIn/Twitter): Nutze einen starken Hook-Satz am Anfang, setze Emojis gezielt ein, mache kurze Absätze (viel White-Space für Lesbarkeit), nutze Bullet-Points und ende mit passenden Hashtags.
195
- - Bei Plänen/Anleitungen: Nutze Markdown-Tabellen, fette Überschriften und chronologische Checklisten.
196
- - Schreibe KEIN Intro ("Hier ist dein Post:"). Liefere direkt das nackte, copy-paste-fertige Endprodukt!"""
197
  )
198
-
199
- final_res = self.llm.ask(MODERATOR_MODEL, final_sys, final_user)
200
  history.append({"role": "assistant", "content": final_res})
201
  yield history
202
-
203
 
204
  # Instanziiere den Orchestrator
205
  orchestrator = PlenumOrchestrator()
@@ -232,7 +253,7 @@ with gr.Blocks(theme=v_theme) as demo:
232
  with gr.Column(scale=4):
233
  input_text = gr.Textbox(
234
  label="Plenumsauftrag",
235
- placeholder="z.B. 'Vergleiche Kubeflow vs ZenML' oder 'Schreibe einen LinkedIn Post über KI-Regulierung'",
236
  lines=2
237
  )
238
  with gr.Column(scale=1):
 
3
  import os
4
 
5
  # ==========================================
6
+ # 1. KONFIGURATION & PROMPTS (UNIVERSAL EDITION)
7
  # ==========================================
 
8
 
9
+ MODERATOR_MODEL = "meta-llama/Llama-4-Maverick-17B-128E-Instruct:groq"
10
 
11
  COUNCIL_MEMBERS = {
12
  "🧠 Fachexperte für Struktur (GPT-OSS-120b)": {
13
  "model": "openai/gpt-oss-120b:novita",
14
+ "role": """Du bist ein neutraler Fachexperte für Struktur und Architektur.
15
  REGELN:
16
  - Beginne mit: "[STRUKTUR] "
17
+ - Liefere das logische Gerüst für die Lösung der Aufgabe.
18
+ - Antworte in 2-4 Sätzen, professionell und bodenständig."""
 
19
  },
20
  "🧐 Fachexperte für Details (DeepSeek-V3)": {
21
  "model": "deepseek-ai/DeepSeek-V3.2:novita",
22
+ "role": """Du bist ein neutraler Fachexperte für tiefe Details, Edge-Cases und Qualitätssicherung.
23
  REGELN:
24
  - Beginne mit: "[DETAILS] "
25
+ - Finde Lücken im aktuellen Entwurf, korrigiere Fehler (technisch oder logisch) und füge fehlende Tiefe hinzu.
26
+ - Antworte in 2-4 Sätzen, professionell und bodenständig."""
 
27
  },
28
+ "🛠️ Fachexperte für Praxis (Llama-4-Maverick)": {
29
+ "model": "meta-llama/Llama-4-Maverick-17B-128E-Instruct:groq",
30
+ "role": """Du bist der Fachexperte für die finale Umsetzung.
31
  REGELN:
32
  - Beginne mit: "[PRAXIS] "
33
+ - Gieße die Erkenntnisse der anderen in greifbare Artefakte (z.B. konkrete Textentwürfe, Code-Snippets, Tabellen).
34
+ - Antworte in 2-4 Sätzen, professionell und bodenständig."""
35
+ }
 
 
36
  }
37
 
38
  class PromptManager:
39
+ """Verwaltet alle dynamischen Prompts (Universelles Meta-Prompting)"""
40
 
41
  @staticmethod
42
  def get_moderator_kickoff_sys():
43
  return (
44
+ "Du bist der Lead-Moderator eines Expertenrates. "
45
+ "Analysiere die User-Anfrage. Definiere in 2-3 Sätzen das Ziel und leite ab, "
46
+ "welches Format und welche Tonalität am Ende erwartet werden (z.B. IT-Code, Marketing-Text, strategischer Plan, o.ä.). "
47
+ "Briefe dein Team entsprechend."
48
  )
49
 
50
  @staticmethod
51
  def get_moderator_mid_sys():
52
  return (
53
+ "Du bist der Lead-Moderator. Bewerte den Zwischenstand in einem Satz. "
54
+ "Gib danach exakt EINEN klaren Arbeitsauftrag für die nächste Runde, um Lücken zu schließen oder die Qualität zu erhöhen."
 
55
  )
56
 
57
  @staticmethod
58
  def get_expert_sys(role_focus):
59
  return (
60
  f"{role_focus}\n\n"
61
+ "WICHTIG: Passt euren fachlichen Stil und euer Output-Format AUTOMATISCH an die Natur der Aufgabe an. "
62
+ "Arbeitet iterativ am Entwurf und setzt die Vorgaben des Moderators um."
63
  )
64
 
65
  @staticmethod
 
67
  if not discussion_history:
68
  return f"Auftrag: '{user_prompt}'"
69
  return (
70
+ f"Auftrag: '{user_prompt}'.\n\n"
71
  f"Bisheriges Protokoll:\n{discussion_history}\n\n"
72
  f"ANWEISUNG FÜR DICH ({name}):\n"
73
+ "1. Richte dich nach der letzten Anweisung des Moderators.\n"
74
+ "2. Bringe das Endprodukt inhaltlich voran. Keine Zusammenfassungen der Vorredner.\n"
75
+ "3. Komm direkt zum Punkt."
76
+ )
77
+
78
+ @staticmethod
79
+ def get_analysis_sys():
80
+ return "Du bist der Chef-Analyst. Extrahiere alle Fakten, Code-Blöcke, Metriken und Strukturvorgaben o.ä. verlustfrei aus dem Protokoll."
81
+
82
+ @staticmethod
83
+ def get_analysis_user(discussion_history):
84
+ return (
85
+ f"Protokoll:\n{discussion_history}\n\n"
86
+ "Fasse den Konsens zusammen. Erhalte zwingend alle technischen Artefakte (Code, Tabellen, exakte Formulierungen o.ä.). "
87
+ "Vermeide abstrakte Verallgemeinerungen!"
88
+ )
89
+
90
+ @staticmethod
91
+ def get_final_sys():
92
+ return (
93
+ "Du bist ein hochadaptiver Output-Generator. Du lieferst perfekte, industriestandard-konforme Endprodukte. "
94
+ "Liefere AUSSCHLIESSLICH das finale, sofort nutzbare Endprodukt ohne KI-Geschwafel."
95
+ )
96
+
97
+ @staticmethod
98
+ def get_final_user(user_prompt, consensus_res):
99
+ return (
100
+ f"Auftrag:\n'{user_prompt}'\n\nKonsens:\n{consensus_res}\n\n"
101
+ "ANWEISUNG:\n"
102
+ "1. Analysiere den ursprünglichen Auftrag und wähle AUTOMATISCH die perfekte Tonalität und das richtige Format (z.B. Clean Code für IT, packendes Copywriting für Marketing, formell für Strategie, usw).\n"
103
+ "2. Verarbeite alle Fakten und Artefakte aus dem Konsens.\n"
104
+ "3. Liefere das nackte, copy-paste-fertige Endprodukt."
105
  )
106
 
107
  # ==========================================
 
162
  history.append({"role": "assistant", "content": self.ui.header("🎤 MODERATOR: SITZUNGSERÖFFNUNG")})
163
  yield history
164
 
165
+ kickoff_res = self.llm.ask(
166
+ MODERATOR_MODEL,
167
+ self.prompts.get_moderator_kickoff_sys(),
168
+ f"User-Anfrage: '{user_prompt}'\nBriefe das Team."
169
+ )
170
  discussion_history += f"Moderator (Kick-off): {kickoff_res}\n\n"
171
  history.append({"role": "assistant", "content": self.ui.message("🎤 Moderator", kickoff_res, "#FF5A4D")})
172
  yield history
 
178
 
179
  # Moderator Steuerung (ab Runde 2)
180
  if r > 0:
181
+ mid_res = self.llm.ask(
182
+ MODERATOR_MODEL,
183
+ self.prompts.get_moderator_mid_sys(),
184
+ f"Protokoll:\n{discussion_history}\n\nGib die Anweisung."
185
+ )
186
  discussion_history += f"Moderator (Steuerung): {mid_res}\n\n"
187
  history.append({"role": "assistant", "content": self.ui.message("🎤 Moderator (Steuerung)", mid_res, "#FF5A4D")})
188
  yield history
 
202
  history.append({"role": "assistant", "content": self.ui.header("🧠 MODERATOR: ANALYSE DER DISKUSSION")})
203
  yield history
204
 
205
+ consensus_res = self.llm.ask(
206
+ MODERATOR_MODEL,
207
+ self.prompts.get_analysis_sys(),
208
+ self.prompts.get_analysis_user(discussion_history)
209
+ )
210
  history.append({"role": "assistant", "content": f"> {consensus_res}"})
211
  yield history
212
 
 
214
  history.append({"role": "assistant", "content": self.ui.header("🏆 FINALE AUSGABE")})
215
  yield history
216
 
217
+ final_res = self.llm.ask(
218
+ MODERATOR_MODEL,
219
+ self.prompts.get_final_sys(),
220
+ self.prompts.get_final_user(user_prompt, consensus_res)
 
 
 
 
 
 
 
 
221
  )
 
 
222
  history.append({"role": "assistant", "content": final_res})
223
  yield history
 
224
 
225
  # Instanziiere den Orchestrator
226
  orchestrator = PlenumOrchestrator()
 
253
  with gr.Column(scale=4):
254
  input_text = gr.Textbox(
255
  label="Plenumsauftrag",
256
+ placeholder="z.B. 'Refaktorier dieses Python-Skript' oder 'Schreibe einen LinkedIn Post über KI'",
257
  lines=2
258
  )
259
  with gr.Column(scale=1):