feat(agent): add index bootstrap and answer feedback

This commit is contained in:
2026-09-16 22:40:06 +02:00
parent fc656188cf
commit c005b9b306
19 changed files with 757 additions and 41 deletions
+71 -18
View File
@@ -2,14 +2,14 @@
Der Compose-Stack betreibt Test-Frontend und FastAPI-Agent gemeinsam. Er startet
keinen zweiten Ollama-Container, sondern verbindet sich mit dem vorhandenen
externen Docker-Netz `ollama-default`.
externen Docker-Netz `ollama_default`.
## Voraussetzungen
Auf dem Zielhost müssen vorhanden sein:
- Docker Engine mit Compose-Plugin;
- das externe Netz `ollama-default`;
- das externe Netz `ollama_default`;
- ein darin erreichbarer Ollama-Container;
- die Modelle `qwen3.8:27b` und `bge-m3` in dieser Ollama-Instanz;
- `wissensbasis/` und entweder ein vorhandenes `data/index.db` oder genügend
@@ -18,7 +18,7 @@ Auf dem Zielhost müssen vorhanden sein:
Das Netz und seine Container/Aliase prüfen:
```bash
docker network inspect ollama-default
docker network inspect ollama_default
```
Der Compose-Beispielwert nimmt den DNS-Namen `ollama` und den internen
@@ -47,12 +47,24 @@ Dann `.env` anpassen:
3. `OLLAMA_URL` anhand des Netzwerk-Alias prüfen;
4. `PUID`/`PGID` auf den Besitzer von `data/` setzen.
Vor dem ersten Start das gitignored Bind-Mount mit diesen IDs anlegen (Beispiel
für `1000:1000`):
```bash
mkdir -p data
sudo chown 1000:1000 data
```
Ohne diesen Schritt kann Docker ein fehlendes Verzeichnis als `root` anlegen;
der absichtlich unprivilegierte Agent könnte dann weder `index.db` noch
`audit.db` schreiben.
`.env` ist gitignored und darf nicht committed werden. Compose verwendet die
Datei nur zur Interpolation der ausdrücklich in `compose.yaml` aufgelisteten
Variablen; sonstige lokale Secrets werden nicht pauschal in den Container
durchgereicht.
## Start mit vorhandenem Index
## Start und automatischer Index-Bootstrap
```bash
docker compose build
@@ -61,6 +73,21 @@ docker compose ps
docker compose logs --follow pv-agent
```
Vor dem API-Start führt das Image automatisch `python -m agent.bootstrap` aus.
Der Bootstrap prüft, ob `data/index.db` Chunks und vollständige Vektoren für das
konfigurierte Embedding-Modell enthält. Fehlt der Index oder ist er
unvollständig, wird er aus dem read-only eingebundenen `wissensbasis/` über
Ollama neu erzeugt. Erst danach startet FastAPI. Schlägt die Einbettung fehl,
beendet sich der Container bewusst mit Fehler, statt einen unvollständigen
Produktionsindex zu verwenden.
Der Index wird absichtlich beim **ersten Containerstart**, nicht in einem
Dockerfile-`RUN` erzeugt: Nur zur Laufzeit ist das externe Netz
`ollama_default` zuverlässig verfügbar, und der Index bleibt als Hostdatenstand
in `./data`, statt veraltet im Image zu liegen. Beim ersten Lauf kann der Start
mehrere Minuten dauern; der Healthcheck hat dafür eine Startfrist von 15
Minuten.
Aufruf im Tailscale-Netz:
```text
@@ -69,25 +96,16 @@ http://100.103.83.12:8080/
Im Frontend denselben Wert wie `PV_API_KEY` als Service-Key eingeben.
## Initialen Index im Container bauen
Falls `data/index.db` auf dem Zielhost noch fehlt:
```bash
mkdir -p data
docker compose run --rm pv-agent python -m agent.cli ingest
```
Der Lauf verwendet `bge-m3` über `OLLAMA_URL` und schreibt den Index in das
Bind-Mount `./data`. Danach den Dienst starten:
Der Prozess läuft als `PUID:PGID`. `data/` muss für diese IDs schreibbar sein,
damit Bootstrap, Audit-Log und `/v1/reindex` funktionieren. Ein manueller,
erzwungener Neuaufbau bleibt möglich:
```bash
docker compose down
rm data/index.db
docker compose up -d
```
Der Prozess läuft als `PUID:PGID`. `data/` muss für diese IDs schreibbar sein,
insbesondere wenn `/v1/reindex` verwendet werden soll.
## Smoke-Tests
```bash
@@ -103,6 +121,41 @@ curl --fail \
der Regel, dass der Index fehlt oder Ollama unter dem konfigurierten
Container-DNS-Namen nicht erreichbar ist.
## Fragen-, Antwort- und Bewertungsprotokoll
Compose aktiviert standardmäßig ein detailliertes Audit:
- `data/audit.db`: persistente SQLite-Datenbank mit Request-ID, Frage, Antwort,
Status, Zitaten, Quellen, Konflikten, Suchplan, Modell, Laufzeit und
Regenerierungen;
- Tabelle `ratings`: Daumen hoch/runter plus optionaler Kommentar;
- `docker compose logs --follow pv-agent`: dieselben Ereignisse als mit
`AUDIT ` präfixierte JSON-Zeilen für die Betriebsdiagnose; Docker rotiert
diese Logs bei 50 MB und behält fünf Dateien.
Letzte Einträge strukturiert anzeigen:
```bash
docker compose exec pv-agent python -m agent.cli audit --limit 20
```
Standardaufbewahrung: 30 Tage; Bereinigung erfolgt beim Öffnen des Audit-Stores.
Konfiguration:
```dotenv
PV_AUDIT_ENABLED=true
PV_AUDIT_LOG_CONTENT=true
PV_AUDIT_STDOUT=true
PV_AUDIT_RETENTION_DAYS=30
```
Fragen und Antworten können sensible Freitexte enthalten. Zugriff auf
`data/audit.db`, Backups und Docker-Logs ist deshalb auf Administratoren zu
beschränken. Mit `PV_AUDIT_LOG_CONTENT=false` bleiben nur technische Metadaten
und KB-IDs erhalten; Frage, Antwort, Quellenbeschreibungen, Konflikttext,
Suchplan und Bewertungskommentar werden dann nicht gespeichert oder nach stdout
geschrieben. API-Keys und Authorization-Header werden nie protokolliert.
## Sicherheitsprofil
- Port `8080` wird nur an die Tailscale-Adresse `100.103.83.12` gebunden.