shinkan-jinkendo/.claude/docs/technical/KI_FEATURES_SPEC.md

374 lines
13 KiB
Markdown
Raw Normal View History

# 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