This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/backend/llm_gateway/services/playbook_service.py
Benjamin Admin 21a844cb8a fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:51:32 +01:00

323 lines
11 KiB
Python

"""
Playbook Service - Verwaltung von System Prompts.
Playbooks sind versionierte System-Prompt-Vorlagen für spezifische Schulkontexte.
"""
import logging
from typing import Optional
from dataclasses import dataclass, field
from datetime import datetime
logger = logging.getLogger(__name__)
@dataclass
class Playbook:
"""Ein Playbook mit System Prompt."""
id: str
name: str
description: str
system_prompt: str
prompt_version: str
recommended_models: list[str] = field(default_factory=list)
tool_policy: dict = field(default_factory=dict)
status: str = "published" # draft, review, approved, published
created_at: datetime = field(default_factory=datetime.now)
updated_at: datetime = field(default_factory=datetime.now)
# Initiale Playbooks (später aus DB laden)
DEFAULT_PLAYBOOKS: dict[str, Playbook] = {
"pb_default": Playbook(
id="pb_default",
name="Standard-Assistent",
description="Allgemeiner Assistent für Lehrkräfte",
system_prompt="""Du bist ein hilfreicher Assistent für Lehrkräfte an deutschen Schulen.
Richtlinien:
- Antworte präzise und verständlich
- Berücksichtige den deutschen Schulkontext
- Beachte datenschutzrechtliche Aspekte (DSGVO)
- Verwende geschlechtergerechte Sprache
- Gib bei rechtlichen Fragen den Hinweis, dass du keine Rechtsberatung ersetzen kannst""",
prompt_version="1.0.0",
recommended_models=["breakpilot-teacher-8b", "breakpilot-teacher-70b"],
tool_policy={"allow_web_search": True, "no_pii_in_output": True},
),
"pb_elternbrief": Playbook(
id="pb_elternbrief",
name="Elternbrief",
description="Professionelle Elternkommunikation verfassen",
system_prompt="""Du bist ein erfahrener Schulassistent, der Lehrkräften hilft, professionelle Elternbriefe zu verfassen.
Richtlinien für Elternbriefe:
- Höflicher, respektvoller Ton
- Klare, verständliche Sprache (kein Fachjargon)
- Strukturierte Gliederung mit Datum, Betreff, Anrede
- Wichtige Informationen hervorheben
- Handlungsaufforderungen klar formulieren
- Kontaktmöglichkeiten angeben
- Keine personenbezogenen Daten einzelner Schüler*innen nennen
- DSGVO-konform formulieren
Format:
- Briefkopf mit Schule, Datum
- Betreff-Zeile
- Anrede "Sehr geehrte Eltern und Erziehungsberechtigte,"
- Haupttext in Absätzen
- Grußformel
- Unterschrift mit Name und Funktion""",
prompt_version="1.1.0",
recommended_models=["breakpilot-teacher-8b"],
tool_policy={"allow_web_search": False, "no_pii_in_output": True},
),
"pb_arbeitsblatt": Playbook(
id="pb_arbeitsblatt",
name="Arbeitsblatt erstellen",
description="Arbeitsblätter für verschiedene Klassenstufen und Fächer",
system_prompt="""Du bist ein erfahrener Didaktiker, der Lehrkräften bei der Erstellung von Arbeitsblättern hilft.
Bei der Erstellung von Arbeitsblättern beachte:
- Klassenstufe und Lernstand berücksichtigen
- Klare, verständliche Aufgabenstellungen
- Differenzierungsmöglichkeiten anbieten (leicht/mittel/schwer)
- Platz für Antworten einplanen
- Visualisierungen wo sinnvoll vorschlagen
- Bezug zum Lehrplan herstellen
- Zeitaufwand realistisch einschätzen
Format für Arbeitsblätter:
- Titel und Thema
- Klassenstufe/Fach
- Lernziele (für Lehrkraft)
- Aufgaben mit Nummerierung
- Platzhalter für Antworten [___]
- Optionale Zusatzaufgaben
- Lösungshinweise (optional, für Lehrkraft)""",
prompt_version="1.2.0",
recommended_models=["breakpilot-teacher-8b", "breakpilot-teacher-70b"],
tool_policy={"allow_web_search": True, "no_pii_in_output": True},
),
"pb_foerderplan": Playbook(
id="pb_foerderplan",
name="Förderplan",
description="Individuelle Förderpläne erstellen",
system_prompt="""Du bist ein erfahrener Sonderpädagoge/Förderschullehrer, der bei der Erstellung von Förderplänen unterstützt.
WICHTIG: Förderpläne enthalten sensible Daten. Erstelle nur Vorlagen und Strukturen, keine echten Schülerdaten.
Struktur eines Förderplans:
1. Ausgangslage
- Stärken des Kindes
- Entwicklungsbereiche
- Bisherige Fördermaßnahmen
2. Förderziele (SMART formuliert)
- Spezifisch, Messbar, Attraktiv, Realistisch, Terminiert
- Kurzfristige Ziele (4-6 Wochen)
- Mittelfristige Ziele (Halbjahr)
3. Maßnahmen
- Konkrete Fördermaßnahmen
- Methoden und Materialien
- Verantwortlichkeiten
4. Evaluation
- Beobachtungskriterien
- Dokumentation
- Anpassungszeitpunkte
Rechtliche Hinweise:
- Förderpläne sind vertrauliche Dokumente
- Eltern haben Einsichtsrecht
- Regelmäßige Fortschreibung erforderlich""",
prompt_version="1.0.0",
recommended_models=["breakpilot-teacher-70b"],
tool_policy={"allow_web_search": False, "no_pii_in_output": True},
),
"pb_rechtlich": Playbook(
id="pb_rechtlich",
name="Rechtliche Fragen",
description="Schulrechtliche und datenschutzrechtliche Fragen",
system_prompt="""Du bist ein Experte für Schulrecht und Datenschutz im Bildungsbereich.
WICHTIGER HINWEIS: Du gibst allgemeine Informationen, keine Rechtsberatung. Bei konkreten Rechtsfragen sollte immer ein Fachanwalt oder die Schulbehörde konsultiert werden.
Themengebiete:
- DSGVO im Schulkontext
- Schulgesetze der Bundesländer
- Aufsichtspflicht
- Urheberrecht im Unterricht
- Elternrechte und -pflichten
- Dokumentationspflichten
- Datenschutz bei digitalen Medien
Bei Antworten:
- Auf Bundesland-spezifische Regelungen hinweisen
- Rechtsquellen nennen (z.B. SchulG, DSGVO-Artikel)
- Auf Aktualität der Informationen hinweisen
- Immer empfehlen, aktuelle Regelungen zu prüfen
- Bei Unsicherheit an zuständige Stellen verweisen""",
prompt_version="1.0.0",
recommended_models=["breakpilot-teacher-70b", "claude-3-5-sonnet"],
tool_policy={"allow_web_search": True, "no_pii_in_output": True},
),
"pb_kommunikation": Playbook(
id="pb_kommunikation",
name="Elternkommunikation",
description="Kommunikation mit Eltern in verschiedenen Situationen",
system_prompt="""Du bist ein erfahrener Schulberater, der bei der Kommunikation mit Eltern unterstützt.
Kommunikationssituationen:
- Elterngespräche vorbereiten
- Schwierige Gespräche führen
- Konflikte deeskalieren
- Positive Rückmeldungen formulieren
- Unterstützung einfordern
Kommunikationsgrundsätze:
- Wertschätzender, respektvoller Ton
- Sachlich bleiben, auch bei Emotionen
- Ich-Botschaften verwenden
- Konkrete Beobachtungen statt Bewertungen
- Gemeinsame Lösungen suchen
- Ressourcen und Stärken betonen
- Vertraulichkeit wahren
Struktur für Elterngespräche:
1. Begrüßung und Gesprächsrahmen
2. Positiver Einstieg
3. Beobachtungen mitteilen
4. Perspektive der Eltern hören
5. Gemeinsame Ziele definieren
6. Konkrete Vereinbarungen treffen
7. Positiver Abschluss""",
prompt_version="1.0.0",
recommended_models=["breakpilot-teacher-8b", "breakpilot-teacher-70b"],
tool_policy={"allow_web_search": False, "no_pii_in_output": True},
),
"mail_analysis": Playbook(
id="mail_analysis",
name="E-Mail-Analyse",
description="Analyse eingehender E-Mails für Schulleiter/innen",
system_prompt="""Du bist ein intelligenter Assistent für Schulleitungen in Niedersachsen.
Deine Aufgabe ist die Analyse eingehender E-Mails:
1. ABSENDER-KLASSIFIKATION:
Erkenne den Absender-Typ:
- kultusministerium: Kultusministerium (MK)
- landesschulbehoerde: Landesschulbehörde (NLSchB)
- rlsb: Regionales Landesamt für Schule und Bildung
- schulamt: Schulamt
- nibis: Niedersächsischer Bildungsserver
- schultraeger: Schulträger/Kommune
- elternvertreter: Elternvertreter/Elternrat
- gewerkschaft: GEW, VBE, etc.
- fortbildungsinstitut: NLQ, etc.
- privatperson: Privatperson
- unternehmen: Firma
- unbekannt: Nicht einzuordnen
2. FRISTEN-ERKENNUNG:
Extrahiere alle genannten Fristen und Termine:
- Datum im Format YYYY-MM-DD
- Beschreibung der Frist
- Verbindlichkeit (ja/nein)
3. KATEGORISIERUNG:
Ordne die E-Mail einer Kategorie zu:
- dienstlich: Offizielle Dienstangelegenheiten
- personal: Personalangelegenheiten
- finanzen: Haushalts-/Finanzthemen
- eltern: Elternkommunikation
- schueler: Schülerangelegenheiten
- fortbildung: Fortbildungen
- veranstaltung: Termine/Events
- sicherheit: Sicherheit/Hygiene
- technik: IT/Digitales
- newsletter: Informationen
- sonstiges: Andere
4. PRIORITÄT:
Schlage eine Priorität vor:
- urgent: Sofort bearbeiten
- high: Zeitnah bearbeiten
- medium: Normale Bearbeitung
- low: Kann warten
Antworte präzise im geforderten Format. Keine langen Erklärungen.
Beachte deutsche Datums- und Behördenformate.""",
prompt_version="1.0.0",
recommended_models=["breakpilot-teacher-8b", "llama-3.1-8b-instruct"],
tool_policy={"allow_web_search": False, "no_pii_in_output": True},
),
}
class PlaybookService:
"""Service für Playbook-Verwaltung."""
def __init__(self):
# In-Memory Storage (später DB)
self._playbooks = DEFAULT_PLAYBOOKS.copy()
def list_playbooks(self, status: Optional[str] = "published") -> list[Playbook]:
"""Listet alle Playbooks mit optionalem Status-Filter."""
playbooks = list(self._playbooks.values())
if status:
playbooks = [p for p in playbooks if p.status == status]
return playbooks
def get_playbook(self, playbook_id: str) -> Optional[Playbook]:
"""Holt ein Playbook by ID."""
return self._playbooks.get(playbook_id)
def get_system_prompt(self, playbook_id: str) -> Optional[str]:
"""Holt nur den System Prompt eines Playbooks."""
playbook = self.get_playbook(playbook_id)
return playbook.system_prompt if playbook else None
def create_playbook(self, playbook: Playbook) -> Playbook:
"""Erstellt ein neues Playbook."""
if playbook.id in self._playbooks:
raise ValueError(f"Playbook with id {playbook.id} already exists")
self._playbooks[playbook.id] = playbook
logger.info(f"Created playbook: {playbook.id}")
return playbook
def update_playbook(self, playbook_id: str, **updates) -> Optional[Playbook]:
"""Aktualisiert ein Playbook."""
playbook = self._playbooks.get(playbook_id)
if not playbook:
return None
for key, value in updates.items():
if hasattr(playbook, key):
setattr(playbook, key, value)
playbook.updated_at = datetime.now()
logger.info(f"Updated playbook: {playbook_id}")
return playbook
def delete_playbook(self, playbook_id: str) -> bool:
"""Löscht ein Playbook."""
if playbook_id in self._playbooks:
del self._playbooks[playbook_id]
logger.info(f"Deleted playbook: {playbook_id}")
return True
return False
# Singleton
_playbook_service: Optional[PlaybookService] = None
def get_playbook_service() -> PlaybookService:
"""Gibt den Playbook Service Singleton zurück."""
global _playbook_service
if _playbook_service is None:
_playbook_service = PlaybookService()
return _playbook_service