feat(memory): automatische Erinnerungs-Extraktion aus Gespraechen

- app/core/memory_extractor.py: LLM destilliert nach je N Turns dauerhafte
  Fakten/Vorlieben aus dem Verlauf, dedupliziert gegen vorhandene Erinnerungen
  und legt sie ab - best-effort, nicht-blockierend (Hintergrund-Task), eigener
  Extraktions-Prompt (JSON, Reasoning aus), Cap-Begrenzung
- Trigger in /api/chat und /ws/voice nach dem Persistieren des Turns
- Konfig: MEMORY_EXTRACTION_ENABLED/_EVERY_N_TURNS/_MAX/_PROVIDER
- Tests: Extraktion, Dedup, kaputtes JSON, Cap, leeres Gespraech, Scheduling
- Doku: README + Architektur-Roadmap (Punkt 3 erledigt)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-18 03:15:08 +02:00
commit aa64ccf585
8 changed files with 326 additions and 1 deletions

View file

@ -226,6 +226,13 @@ curl -X POST http://localhost:8080/api/me/memories \
-H 'Content-Type: application/json' -d '{"content":"Mag morgens Kamillentee."}'
```
**Automatische Erinnerungen:** Zusätzlich zur manuellen Pflege destilliert das LLM
nach je N Turns (Default 3) dauerhafte Fakten/Vorlieben aus dem Gespräch und legt sie
dedupliziert als Erinnerungen ab — best-effort und **nicht-blockierend** (Hintergrund-Task,
erhöht die Antwortlatenz nicht). Steuerung über `MEMORY_EXTRACTION_*` (siehe `.env.example`);
`MEMORY_EXTRACTION_ENABLED=false` schaltet es ab. Sinnvoll mit einem lokalen LLM, da pro
Turn ein zusätzlicher (kostenloser) Modellaufruf anfällt.
## Echtzeit-Chat (WebSocket)
`/ws/chat` bietet einen dauerhaften, bidirektionalen Kanal. Der Client sendet pro