Phase 8: Lokale KI

Wiki mit semantischer Suche ueber pgvector, Diktat ueber faster-whisper,
Berichtsassistent und Belegerfassung — alles gegen selbst betriebene
Modelle. Dazu zwei Protokollansichten: was die Maschine getan hat und was
Menschen getan haben.

Nichts, was ein Modell erzeugt, gelangt ungeprueft in einen Nachweis. Jede
Ausgabe ist zuerst ein eigener Datensatz, gekennzeichnet, mit zwei gleich
grossen Knoepfen davor. Die Datenbank haelt gegen: Eingabe, Ausgabe und
Modell sind unveraenderlich, geloescht wird nicht, entschieden wird einmal.

Kein Rueckfall auf einen Anbieter: fehlen die Container, fehlt die Funktion.
Dafuer bleibt alles andere ohne Modell vollstaendig benutzbar — geprueft von
vierzehn E2E-Tests, die ohne laufendes Modell durchlaufen.

Postgres bringt jetzt PostGIS und pgvector mit (eigenes Image), Ollama und
faster-whisper stehen im Compose-Profil "ki".

73 neue Unit-Tests, 14 neue E2E-Tests, Version 0.9.0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-09-04 11:06:03 +02:00
co-authored by Claude Opus 5
parent 12243f177d
commit f7ccd9a908
134 changed files with 8624 additions and 72 deletions
+107 -1
View File
@@ -8,7 +8,113 @@ Die Regeln dazu stehen in [docs/VERSIONIERUNG.md](docs/VERSIONIERUNG.md).
## [Unveröffentlicht]
Nächster Schritt ist Phase 8 (Lokale KI).
Nächster Schritt ist Phase 9 (Kassenverwaltung).
---
## [0.9.0] — 2026-09-04
Phase 8: Lokale KI. Ein Wiki mit semantischer Suche, Diktat, Berichtsassistent
und Belegerfassung — alles gegen selbst betriebene Modelle.
**Nichts, was ein Modell erzeugt, gelangt ungeprüft in einen Nachweis.** Jede
KI-Ausgabe ist zuerst ein eigener Datensatz und nicht ein Feld im
Zieldokument. Sie ist gekennzeichnet, sie steht daneben statt mittendrin, und
sie braucht zwei gleich große Knöpfe, bevor etwas mit ihr geschieht.
**Es läuft alles im Haus.** Ollama und faster-whisper als Container daneben,
kein Anbieter, kein Schlüssel. Es gibt keinen Rückfall auf einen Cloud-Dienst:
fehlen die Container, fehlt die Funktion.
### Hinzugefügt
**Datenmodell**
- `KiVorgang` — jede Befragung eines Modells mit Eingabe, Ausgabe, Modell,
Dauer und der Entscheidung darüber. Auch Fehlschläge: ein Modell, das
dreimal am Tag in eine Zeitüberschreitung läuft, ist eine Information.
- `Wikiseite`, `Wikiabschnitt` (mit `vector(768)`) und `Wikiversion`.
- `Diktat` mit Aufnahme in MinIO, `Belegentwurf` mit allen Feldern optional —
ein Modell, das den Betrag nicht findet, soll nichts erfinden.
**Postgres mit pgvector**
- Eigenes Image (`docker/postgres/Dockerfile`), weil FLORIAN PostGIS **und**
pgvector braucht und es kein offizielles Image mit beidem gibt.
- HNSW-Index statt IVFFlat: IVFFlat muss auf gefülltem Bestand trainiert
werden, HNSW ist ab der ersten Zeile brauchbar. Ein Wiki wächst Seite für
Seite — es gibt nie den Moment, an dem man den Index einmal aufbaut.
**Wiki**
- Markdown, selbst gerendert **ohne HTML**: der Text kommt von Anwendern, und
jeder Weg über `dangerouslySetInnerHTML` wäre ein Weg für ein `<script>` in
einer Dienstvorschrift.
- Zwei Suchen: Wortsuche (immer, mit Textstelle) und Frage ans Modell
(semantisch, mit Fundstellen). Steht die Antwort nicht in den Unterlagen,
sagt FLORIAN das — ohne passende Auszüge wird gar nicht erst gefragt.
- Zerlegt wird an den Überschriften, mit der Überschriftenkette im
Einbettungstext: ein Abschnitt über „Rückzugsdruck" ohne das Wort
„Atemschutz" darüber findet sich sonst nicht.
- Jede Änderung schreibt die vorherige Fassung weg.
**Diktat, Bericht, Beleg**
- Aufnahme im Browser, Erkennung über faster-whisper im Hintergrund. Die
Aufnahme bleibt, solange nicht entschieden ist — sie ist das einzige
Original.
- Berichtsentwurf aus Stichpunkten. Zeitstempel und Einsatznummer bekommt das
Modell **nicht**: sie stehen schon als Felder im Bericht.
- Belegerfassung mit Vision-Modell. Nicht erkannte Felder bleiben leer und
gelb hinterlegt statt geraten zu werden.
**Zwei Protokolle**
- `/ki-protokoll` — was die Maschine getan hat, mit Kennzahlen und
aufklappbarer Eingabe/Ausgabe.
- `/protokoll` — das Audit-Log. Wird seit Phase 0 geschrieben; die Ansicht
dazu kam jetzt, weil beides nebeneinander gehört: was hat ein Mensch getan,
was die Maschine.
### Geändert
- `lib/integrations/llm.ts` kann jetzt drei Dinge statt einem: Text,
Einbettungen und Bilder — mit je eigenem Modell, weil ein Rechner ohne
Grafikkarte das Einbettungsmodell noch schafft und das Vision-Modell nicht.
- Der Datei-Upload nimmt Tonaufnahmen an (webm, ogg, mp4, wav).
- Neue Rechte: `wiki.lesen` als Grundrecht (eine Wehr, in der nur die Führung
nachschlagen darf, hat kein Wiki, sondern einen Aktenschrank),
`wiki.bearbeiten`, `ki.nutzen`, `ki.protokoll`, `beleg.erfassen`.
- Der Aufbewahrungslauf zieht nebenbei Wiki-Seiten nach, deren Suchstand
veraltet ist.
### Behoben
- Beim Zerlegen einer Wiki-Seite wurde ein kurzer Abschnitt an den vorherigen
gehängt, auch wenn er unter einer anderen Überschrift stand. Unter einer
Antwort hätte dann eine Fundstelle gestanden, in der der zitierte Satz gar
nicht vorkommt. Gefunden hat es der Test, nicht das Ausprobieren.
### Sicherheit
- Row Level Security für die sechs neuen Tabellen — auch für die Vektorsuche:
ein perfekt passender Abschnitt einer fremden Wehr taucht nicht auf.
- Eingabe, Ausgabe, Modell und Art eines KI-Vorgangs sind nach dem Anlegen
unveränderlich (Trigger). Über einen Vorschlag wird genau einmal
entschieden. `REVOKE DELETE ON "ki_vorgang"`.
- `REVOKE UPDATE, DELETE ON "wikiversion"`: eine Dienstvorschrift, deren
Vorgeschichte sich bereinigen lässt, ist als Nachweis wertlos.
- Prüfbedingungen: keine Entscheidung ohne Zeitpunkt, kein Fehlschlag ohne
Grund, kein negativer Betrag auf einer Quittung.
### Tests
- 73 neue Unit-Tests: Zerlegen einer Seite (Überschriftenketten, Codeblöcke,
Teilung an Absatzgrenzen), Auswerten einer Modellantwort auf ein Belegfoto
(deutsche Zahlen, Tausenderpunkt, unmögliche Daten), die Anweisungen an das
Modell und die Datenbankregeln samt Vektorsuche über Mandanten hinweg.
- 14 neue E2E-Tests, die **ohne laufendes Modell** prüfen, dass alles andere
vollständig benutzbar bleibt und ehrlich sagt, was fehlt.
---