shinkan-jinkendo/.claude/docs/technical/KI_FEATURES_SPEC.md
Lars e4451e1362
Some checks failed
Test Suite / playwright-tests (push) Waiting to run
Deploy Development / deploy (push) Successful in 43s
Test Suite / pytest-backend (push) Failing after 1s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 13s
Test Suite / k6 /health Baseline (push) Has been cancelled
Enhance Exercise Management and AI Integration
- Updated the exercise form to include a tabbed navigation structure, improving user experience with sections for Stammdaten, Anleitung, Einordnung, Varianten, and Medien & Mehr.
- Introduced the concept of **Freigabelevel** (visibility level) in the UI, replacing previous terminology for clarity and consistency across components.
- Implemented new AI endpoints for exercise suggestions and regeneration, allowing for dynamic content generation without direct database writes.
- Removed the legacy `is_primary` flag from exercise skills in the UI, ensuring that intensity levels (`niedrig`, `mittel`, `hoch`) are the primary focus for skill management.
- Enhanced the variant management process with improved saving mechanisms and UI updates to reflect changes more intuitively.
2026-05-22 07:52:31 +02:00

374 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# KI-Funktionen Specification Exercises
**Version:** 1.1
**Datum:** 2026-04-24
**Status:** DRAFT
**Autor:** Claude Code
**Änderungen v1.1:** Prompts sind nicht hardcoded sie werden aus der DB geladen (AI_PROMPT_SYSTEM_SPEC.md)
**Verwandte Specs:** AI_PROMPT_SYSTEM_SPEC.md (Prompt-DB + Platzhalter), SKILLS_MATRIX_SPEC.md (Fähigkeitsmatrix)
**Übergeordnete Produkt-Vision** (breiter Scope: Zielausbau, bereichsweise vs. Gesamtüberarbeitung, Varianten, Planungs-/Nachbereitungskontext, Admin-Masse):
`functional/AI_EXERCISE_ASSISTANT_VISION.md`
---
## 1. Übersicht
KI-gestützte Assistenzfunktionen beim Anlegen und Bearbeiten von Übungen (Mindestpaket dieser Spec):
**Hinweis:** Die beiden folgenden Zeilen entsprechen **P0** der Phasierung in **`AI_EXERCISE_ASSISTANT_VISION.md`**; spätere Funkteile sind dort beschrieben.
| Funktion | Ziel |
|---------|------|
| **KI-Zusammenfassung** | Generiert `summary` aus `goal` + `execution` (für Listen + Trainingspläne) |
| **KI-Skill-Empfehlung** | Schlägt passende Fähigkeiten + Stufen vor (reduziert manuelle Zuordungsarbeit) |
**Abhängigkeit:** OpenRouter API (`OPENROUTER_API_KEY` in `.env`).
Ist der Key nicht gesetzt, sind alle KI-Funktionen deaktiviert Formular funktioniert ohne KI normal.
---
## 2. UX-Prinzip: Manual First, Auto als Fallback
```
Trainer gibt goal + execution ein
├─► [KI-Vorschlag]-Button sichtbar
│ │
│ ▼ (Klick)
│ KI generiert sofort Vorschlag
│ → Trainer sieht Vorschlag inline
│ → Kann akzeptieren / bearbeiten / ablehnen
└─► Kein Klick bis zum Speichern?
▼ (automatisch beim POST/PUT)
KI läuft im Hintergrund
→ summary + skill_suggestions werden gesetzt
→ Trainer kann danach noch bearbeiten
```
**Regel:** Manuell generierte Werte (wo Trainer aktiv bestätigt hat) werden
beim Auto-Fallback NICHT überschrieben. Auto-generierte Werte werden als
`ai_generated: true` markiert und können jederzeit neu generiert oder überschrieben werden.
---
## 3. KI-Zusammenfassung (`summary`)
### 3.1 Was wird generiert
Aus `title` + `goal` + `execution` generiert die KI eine **kurze Zusammenfassung**
(2-4 Sätze, max. 200 Zeichen) für:
- Übungslisten (Karten-Ansicht)
- Trainingsplan-Darstellung (kompakte Anzeige)
- Export-Berichte
### 3.2 Prompt-Logik (Backend)
**Prompt ist NICHT hardcoded** er wird aus der `ai_prompts` Tabelle geladen
(Slug: `exercise_summary`). Admins können das Template anpassen.
```python
# Aufruf via zentralem AI-Service (siehe AI_PROMPT_SYSTEM_SPEC.md)
result = await ai_service.run_ai_prompt(
slug="exercise_summary",
context_data={"exercise": exercise_data},
db=db,
openrouter_key=settings.openrouter_api_key
)
```
**Default-Template** (in Migration 020 als `default_template` gespeichert):
Siehe `AI_PROMPT_SYSTEM_SPEC.md` §2.1 Prompt `exercise_summary`.
### 3.3 DB-Feld
Kein neues Feld nötig `exercises.summary` nimmt den generierten Text auf.
Zusätzliches Tracking-Feld: `summary_ai_generated BOOLEAN DEFAULT false`
---
## 4. KI-Skill-Empfehlung
### 4.1 Was wird empfohlen
Aus `title` + `goal` + `execution` + Katalog aller verfügbaren Skills empfiehlt die KI:
- **Welche Skills** relevant sind (aus dem bestehenden Skill-Katalog)
- **Erforderliche Stufe** (`required_level`) was der Trainierende mitbringen muss
- **Ziel-Stufe** (`target_level`) was durch regelmäßige Ausführung erreicht wird
- **Intensität** (`intensity`) wie stark diese Fähigkeit trainiert wird
### 4.2 Prompt-Logik (Backend)
**Prompt ist NICHT hardcoded** Slug: `exercise_skill_suggestions`.
Der `{{skills_catalog}}`-Platzhalter wird vom Backend automatisch mit der aktuellen
Skill-Liste aus der DB aufgelöst.
Admins können den Prompt anpassen (z.B. die Anweisung zur Auswahl verschärfen oder
fachliche Hinweise ergänzen). Siehe `AI_PROMPT_SYSTEM_SPEC.md`.
### 4.3 Bestätigungsflow (UX)
```
KI gibt Vorschläge
┌─────────────────────────────────────────┐
│ KI-Vorschläge (3 Fähigkeiten) │
│ ─────────────────────────────────────── │
│ ✓ Distanzgefühl │
│ Voraussetzung: Grundlagen │
│ Ziel: Aufbau · Intensität: Hoch │
│ [✓ Übernehmen] [Stufe ändern ▼] [✕] │
│ ─────────────────────────────────────── │
│ ✓ Reaktionsschnelligkeit │
│ Voraussetzung: Einsteiger │
│ Ziel: Grundlagen · Intensität: Mittel │
│ [✓ Übernehmen] [Stufe ändern ▼] [✕] │
│ ─────────────────────────────────────── │
│ ◦ Gleichgewicht (optional) │
│ Voraussetzung: Grundlagen │
│ Ziel: Grundlagen · Intensität: Niedrig│
│ [✓ Übernehmen] [Stufe ändern ▼] [✕] │
│ ─────────────────────────────────────── │
│ [Alle übernehmen] [Verwerfen] │
└─────────────────────────────────────────┘
```
- Jeder Vorschlag kann **einzeln** übernommen, angepasst oder abgelehnt werden
- „Alle übernehmen" nimmt alle aktuell angezeigten Vorschläge
- Stufen können per Dropdown direkt angepasst werden bevor sie übernommen werden
- Abgelehnte Vorschläge werden nicht gespeichert
---
## 5. API-Endpoints
### 5.1 Endpoints Overview
| Method | Endpoint | Beschreibung |
|--------|----------|--------------|
| POST | `/exercises/ai/suggest` | Vorschläge für neue Übung (vor dem Speichern) |
| POST | `/exercises/{id}/ai/regenerate` | Neu generieren für bestehende Übung |
---
### 5.2 `POST /exercises/ai/suggest`
Liefert KI-Vorschläge auf Basis von Eingabe-Text, **bevor** die Übung gespeichert wurde.
Wird beim Klick auf „KI-Vorschlag" im Formular aufgerufen.
**Request Body:**
```json
{
"title": "Maai - Distanzübung",
"goal": "Distanzgefühl entwickeln durch Partnerübungen...",
"execution": "1. Partnerwahl\n2. Ausgangsstellung..."
}
```
**Required Fields:** mindestens `goal` ODER `execution` (je länger, desto besser)
**Response:** `200 OK`
```json
{
"summary": {
"text": "Partnerübung zur Entwicklung des Distanzgefühls. Trainiert werden räumliche Wahrnehmung und reaktives Verhalten in der Kumite-Distanz.",
"ai_generated": true,
"model": "anthropic/claude-sonnet-4"
},
"skills": [
{
"skill_id": 10,
"skill_name": "Distanzgefühl",
"skill_category": "Kumite",
"required_level": "grundlagen",
"target_level": "aufbau",
"intensity": "hoch",
"confidence": 0.92
},
{
"skill_id": 15,
"skill_name": "Reaktionsschnelligkeit",
"skill_category": "Athletik",
"required_level": "einsteiger",
"target_level": "grundlagen",
"intensity": "mittel",
"confidence": 0.74
}
]
}
```
**Errors:**
- `400` - Zu wenig Text (goal und execution leer)
- `503` - KI nicht verfügbar (OPENROUTER_API_KEY fehlt)
---
### 5.3 `POST /exercises/{id}/ai/regenerate`
Generiert summary und/oder skill-Empfehlungen für eine bestehende Übung neu.
Verwendet die aktuellen gespeicherten Felder als Input.
**Request Body:**
```json
{
"regenerate": ["summary", "skills"]
}
```
**Werte:** `"summary"` | `"skills"` (oder beide)
**Response:** `200 OK` (gleiche Struktur wie `/ai/suggest`)
**Hinweis:** Regenerieren überschreibt NICHT Felder, die manuell gesetzt wurden
(`summary_ai_generated = false`). Es wird nur der Vorschlag zurückgegeben,
Trainer muss aktiv übernehmen.
---
## 6. Datenbank
### 6.1 Neues Feld: `summary_ai_generated`
```sql
-- Als Teil von Migration 014 ergänzen:
ALTER TABLE exercises
ADD COLUMN IF NOT EXISTS summary_ai_generated BOOLEAN DEFAULT false;
```
**Semantik:**
- `false` (default) = Zusammenfassung manuell geschrieben oder noch leer
- `true` = Zuletzt von KI generiert (kann überschrieben werden)
Beim manuellen Überschreiben durch den Trainer: `summary_ai_generated = false` setzen.
### 6.2 Kein Feld für Skill-Empfehlungen
Skill-Vorschläge der KI werden **nicht** persistent gespeichert sie erscheinen
nur im Formular-UI und werden erst bei expliziter Bestätigung als reguläre
`exercise_skills`-Einträge gespeichert.
---
## 7. Integration in Speicher-Flow
### 7.1 Auto-Fallback beim Speichern (POST/PUT exercises)
```python
# In backend/routers/exercises.py
async def create_exercise(data, session):
# 1. Übung normal speichern
exercise_id = db.insert_exercise(data)
# 2. Auto-KI nur wenn:
# - OPENROUTER_API_KEY gesetzt
# - summary noch leer
# - goal oder execution vorhanden
if settings.openrouter_api_key and not data.summary and (data.goal or data.execution):
# Background Task (non-blocking)
background_tasks.add_task(
auto_generate_summary,
exercise_id=exercise_id,
title=data.title,
goal=data.goal,
execution=data.execution
)
return exercise_id
```
### 7.2 Skill-Auto-Suggestion
Skill-Empfehlungen werden beim Auto-Fallback **NICHT** automatisch gespeichert
(wegen Bestätigungs-Pflicht). Sie werden nur beim manuellen Trigger angeboten.
---
## 8. Frontend-Integration
### 8.1 ExerciseFormPage KI-Buttons
```
┌──────────────────────────────────────┐
│ Ziel der Übung * │
│ ┌────────────────────────────────┐ │
│ │ Distanzgefühl entwickeln... │ │
│ └────────────────────────────────┘ │
│ │
│ Durchführung * │
│ ┌────────────────────────────────┐ │
│ │ 1. Partnerwahl... │ │
│ └────────────────────────────────┘ │
│ ↓ │
│ Zusammenfassung (für Listen) │
│ ┌────────────────────────────────┐ │
│ │ [Leer] │ │
│ └────────────────────────────────┘ │
│ [✨ KI-Vorschlag] ← Button │
│ │
│ ─────────────────────────────────── │
│ Fähigkeiten │
│ [Keine zugeordnet] │
│ [+ Manuell hinzufügen] │
│ [✨ KI-Empfehlungen] ← Button │
└──────────────────────────────────────┘
```
### 8.2 KI-Vorschlag für Summary (Inline)
Beim Klick auf „✨ KI-Vorschlag":
```
┌──────────────────────────────────────┐
│ ✨ KI-Vorschlag │
│ ─────────────────────────────────── │
│ "Partnerübung zur Entwicklung des │
│ Distanzgefühls. Trainiert räumliche │
│ Wahrnehmung und reaktives Verhalten."│
│ ─────────────────────────────────── │
│ [✓ Übernehmen] [✕ Verwerfen] │
└──────────────────────────────────────┘
```
Nach „Übernehmen": Text landet im Summary-Feld, Button zeigt „↺ Neu generieren".
### 8.3 Anzeige KI-generierter Inhalte
Felder die KI-generiert sind, werden mit einem kleinen Badge markiert:
```
Zusammenfassung ✨ KI-generiert [bearbeiten]
```
Nach manuellem Bearbeiten verschwindet der Badge.
---
## 9. Konfiguration
```env
OPENROUTER_API_KEY=sk-or-...
OPENROUTER_MODEL=anthropic/claude-sonnet-4 # Für Zusammenfassung
OPENROUTER_MODEL_FAST=anthropic/claude-haiku-4-5 # Für Skill-Empfehlungen (billiger)
```
---
## 10. Fehlerbehandlung
| Szenario | Verhalten |
|----------|-----------|
| OPENROUTER_API_KEY nicht gesetzt | KI-Buttons nicht anzeigen, kein Auto-Fallback |
| API-Timeout (> 10s) | Fehlermeldung inline: "KI momentan nicht verfügbar. Bitte manuell ausfüllen." |
| API-Fehler (5xx) | Gleiche Meldung, kein Absturz |
| Unbekannte Skills in Empfehlung | Backend filtert Skills die nicht im Katalog sind heraus |
| Summary zu lang generiert | Backend kürzt auf 200 Zeichen |
---
**Version:** 1.0
**Datum:** 2026-04-24
**Status:** DRAFT