Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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
|
| 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
|
| 16 |
REGELN:
|
| 17 |
- Beginne mit: "[STRUKTUR] "
|
| 18 |
-
-
|
| 19 |
-
-
|
| 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
|
| 25 |
REGELN:
|
| 26 |
- Beginne mit: "[DETAILS] "
|
| 27 |
-
-
|
| 28 |
-
-
|
| 29 |
-
- Du darfst deinen Vorrednern zustimmen und darauf aufbauen. Widersprich nur, wenn es inhaltlich wirklich nötig ist."""
|
| 30 |
},
|
| 31 |
-
"🛠️ Fachexperte für Praxis
|
| 32 |
-
|
| 33 |
-
|
| 34 |
REGELN:
|
| 35 |
- Beginne mit: "[PRAXIS] "
|
| 36 |
-
-
|
| 37 |
-
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
}
|
| 41 |
}
|
| 42 |
|
| 43 |
class PromptManager:
|
| 44 |
-
"""Verwaltet alle dynamischen Prompts
|
| 45 |
|
| 46 |
@staticmethod
|
| 47 |
def get_moderator_kickoff_sys():
|
| 48 |
return (
|
| 49 |
-
"Du bist der Lead-Moderator eines
|
| 50 |
-
"
|
| 51 |
-
"
|
|
|
|
| 52 |
)
|
| 53 |
|
| 54 |
@staticmethod
|
| 55 |
def get_moderator_mid_sys():
|
| 56 |
return (
|
| 57 |
-
"Du bist der Lead-Moderator.
|
| 58 |
-
"
|
| 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:
|
| 67 |
-
"Arbeitet
|
| 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"
|
| 76 |
f"Bisheriges Protokoll:\n{discussion_history}\n\n"
|
| 77 |
f"ANWEISUNG FÜR DICH ({name}):\n"
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 175 |
-
|
| 176 |
-
|
| 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 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 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. '
|
| 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):
|