KI-Backend: Umfangs-Umschalter + Prompt Caching (4.5.15/4.5.16)

Umfangs-Umschalter: Checkbox "Auch bestehende Stundeninhalte anpassen" im
AiAssistDialog steuert, ob die KI bestehende Stunden inhaltlich ändern darf oder
die Einheit nur um neue Stunden erweitern soll. Zweifach durchgesetzt (Systemprompt
+ hartes client-seitiges Verwerfen in ApplyResponse), nicht nur der KI-Antwort
vertraut. Dabei auch einen Bug gefixt: eine bereits "Durchgeführt" markierte Stunde
wurde durch eine übernommene KI-Änderung stillschweigend auf "Geplant" zurückgesetzt.

Prompt Caching: der Systemprompt ist jetzt vollständig statisch (Voraussetzung für
Caching) und wird von AnthropicProvider.php als "cache_control: ephemeral" markiert
— wiederholte Anfragen innerhalb der 5-Minuten-TTL zahlen nur den reduzierten
Cache-Read-Preis. transactions-Tabelle und Preistabelle um Cache-Token-Spalten
erweitert, Migration für bereits deployte Installationen beigelegt.
This commit is contained in:
2026-08-16 16:06:52 +02:00
parent 4437f951d9
commit 1928916eac
14 changed files with 328 additions and 38 deletions
+30
View File
@@ -55,6 +55,33 @@ macht der Nutzer selbst — dieses README beschreibt die nötigen Schritte.
7. In der App unter Einstellungen → KI-Unterstützung aktivieren und mit dem angelegten Nutzer
anmelden.
## Update für bereits deployte Installationen (Prompt-Caching-Nachtrag)
Falls `ai-backend/` schon einmal deployt wurde (schema.sql lief bereits, `config.php` existiert
schon): zwei Schritte nötig, damit Abrechnung und `plan.php` mit dem neuen Prompt Caching
funktionieren.
1. Migration einmalig einspielen (ergänzt zwei neue, nicht-destruktive Spalten):
```bash
mysql -u <user> -p <datenbankname> < migrations/2026-08-add-cache-tokens.sql
```
2. In der bestehenden `config.php` bei jedem Preistabellen-Eintrag `cache_write`/`cache_read`
ergänzen (siehe `config.example.php` für aktuelle Richtwerte) — ohne diese Ergänzung wird der
Cache-Anteil einfach mit 0 USD abgerechnet (kein Fehler, aber auch keine Kostenersparnis).
Danach alle geänderten Dateien (`plan.php`, `db.php`, `providers/`, `.htaccess`, falls noch nicht
aktuell) erneut hochladen.
## Prompt Caching
Der Systemprompt in `plan.php` ist vollständig statisch (identisch bei jeder Anfrage, jedes
Nutzers). `AnthropicProvider.php` markiert ihn deshalb als cacheable — wiederholte Anfragen
innerhalb der Anthropic-Cache-TTL (Standard: 5 Minuten) zahlen für diesen Anteil nur den stark
reduzierten "Cache-Read"-Preis statt des vollen Input-Preises; der erste Aufruf nach TTL-Ablauf
zahlt einen kleinen Aufpreis fürs Neuschreiben des Caches. Das passiert automatisch, ohne
Zutun — nichts an der Bedienung der App ändert sich dadurch. Beobachtbar ist der Effekt in der
`transactions`-Tabelle (`cache_creation_input_tokens` vs. `cache_read_input_tokens`).
## Smoke-Test ohne echten API-Key
`plan.php` liest die Umgebungsvariable `AI_BACKEND_FAKE_PROVIDER` — bei `1` wird statt eines
@@ -101,6 +128,9 @@ grundsätzlich nicht) — dann hilft nur eine serverseitige Konfiguration durch
- Ob die berechneten Kosten exakt mit der tatsächlichen Anthropic-Abrechnung übereinstimmen.
- TLS/`.htaccess`-Wirksamkeit und PHP-Version/Erweiterungen auf dem tatsächlichen Hosting.
- Die komplette Kette Desktop → dieses Backend → Anthropic unter echten Netzwerkbedingungen.
- Ob Prompt Caching tatsächlich greift (`cache_read_input_tokens` > 0 bei einer zweiten Anfrage
innerhalb von 5 Minuten) — der `FakeProvider` simuliert kein Caching, das lässt sich nur gegen
die echte Anthropic-API beobachten (z.B. per Blick in die `transactions`-Tabelle).
## Guthaben aufladen