This commit is contained in:
team 1
2026-04-15 10:49:21 +02:00
parent 21b60b8542
commit 51bc781826
5 changed files with 1374 additions and 975 deletions

View File

@@ -1,294 +1,492 @@
# RAG System CLI Command Reference
**Projektstand: rag.zip (aktueller Code-Stand)**
Namespace-Konvention: `mto:agent:*`
# RetrieX CLI Command Reference
Diese Dokumentation beschreibt alle verfügbaren Symfony-Console-Commands des Systems inklusive Zweck, Einsatzszenario und typischer Aufrufe.
**Basis:** `rag.zip` (aktueller Code-Stand vom 2026-04-15)
**Scope:** ausschließlich projektspezifische Symfony-Commands unter `src/Command`
**Namespace-Konvention:** `mto:agent:*`
Diese Referenz ist gegen den realen Codebestand abgeglichen und ersetzt die veraltete Fassung der bisherigen `COMMAND_REF.md`.
---
# 1. Agent / Chat
## 1. Überblick
## `mto:agent:chat`
| Command | Bereich | Kurzbeschreibung |
|---|---|---|
| `mto:agent:chat` | Agent / CLI | Interaktiver Terminal-Chat gegen den AgentRunner |
| `mto:agent:ingest:version` | Ingest | Startet einen Ingest für eine konkrete Dokumentversion |
| `mto:agent:ingest:run` | Ingest Jobs | Führt einen vorhandenen `IngestJob` aus |
| `mto:agent:system:rebuild` | System | Globaler Hard-Rebuild von Chunks, Vektorindex, Tags und optional Service-Reload |
| `mto:agent:vector:rebuild` | Vector | Baut den Chunk-Vektorindex aus `index.ndjson` neu |
| `mto:agent:vector:control` | Vector Service | Install, Start, Stop, Reload und Status des Python-Vector-Service |
| `mto:agent:vector:health` | Vector | Konsistenzcheck für Chunk-NDJSON und Vektorindex |
| `mto:agent:test-vector` | Debug | Führt Tag-Routing und Chunk-Retrieval für einen Testprompt aus |
| `mto:agent:tags:export` | Tags | Exportiert Tags nach `tags.ndjson` |
| `mto:agent:tags:rebuild` | Tags | Exportiert Tags und baut `vector_tags.index` neu |
| `mto:agent:tags:job:run` | Tag Jobs | Führt einen vorhandenen Tag-Rebuild-Job aus oder erstellt direkt einen neuen |
| `mto:agent:tag:health` | Tags | Konsistenzcheck für `tags.ndjson` und Tag-Vektorindex |
| `mto:agent:test:shop-search` | Commerce / Debug | Testkommando für die Shopware-Suche |
| `mto:agent:user:create` | User | Interaktive Anlage eines Users |
---
## 2. Agent / Chat
### `mto:agent:chat`
Interaktiver CLI-Chat mit dem Agenten.
**Zweck**
- Direkter Zugriff auf AgentRunner
- Streaming-Ausgabe im Terminal
- Nutzt vollständige Retrieval- und Prompt-Logik
**Signatur**
```bash
bin/console mto:agent:chat [user-id]
```
**Start**
**Argumente**
- `user-id` optional, Default: `cli`
**Reales Verhalten im Code**
- startet eine Terminal-Schleife mit `Question``Answer`
- ruft pro Eingabe `AgentRunner->run($prompt, $userId)` auf
- streamt Tokens direkt ins Terminal
- beendet sich bei EOF, leerer Eingabe oder `exit`
**Beispiel**
```bash
bin/console mto:agent:chat
bin/console mto:agent:chat admin-debug
```
**Eigenschaften**
- Streaming-first
- Think-Suppression wird im AgentRunner gesteuert
- Voller Kontext + Retrieval aktiv
---
# 2. Dokument-Ingest
## 3. Ingest / Jobs
## `mto:agent:ingest:version`
Ingest einer konkreten Dokumentversion.
### `mto:agent:ingest:version`
Startet einen Ingest für eine konkrete `DocumentVersion` mit explizitem Benutzerkontext.
**Zweck**
- Chunking
- NDJSON-Append / Compaction
- Vollständiger FAISS-Rebuild
- index_meta.json Update
**Signatur**
```bash
bin/console mto:agent:ingest:version <versionId> <userId>
```
**Argumente**
- `versionId` erforderlich, UUID einer `DocumentVersion`
- `userId` erforderlich, UUID des auslösenden Users
**Reales Verhalten im Code**
- lädt `DocumentVersion` und `User` aus Doctrine
- bricht mit Fehler ab, wenn Version oder User nicht existieren
- ruft `IngestOrchestrator->runForVersion($version, $user)` auf
- gibt nach Abschluss die erzeugte Job-ID aus
**Beispiel**
```bash
bin/console mto:agent:ingest:version <documentVersionUuid>
bin/console mto:agent:ingest:version <documentVersionUuid> <userUuid>
```
**Wichtige Korrektur zur alten Doku**
Die bisherige Referenz dokumentierte nur einen Parameter. Im aktuellen Code sind **zwei Pflichtargumente** erforderlich.
---
## `mto:agent:ingest:run`
Führt einen einzelnen IngestJob aus.
### `mto:agent:ingest:run`
Führt einen bereits existierenden `IngestJob` aus.
**Zweck**
- Job-basierte Verarbeitung (QUEUE → RUNNING → COMPLETED/FAILED)
- Wird intern bei Aktivierung einer Dokumentversion verwendet
**Signatur**
```bash
bin/console mto:agent:ingest:run <jobId> [--dry-run]
```
**Beispiel**
**Argumente / Optionen**
- `jobId` erforderlich, UUID eines `IngestJob`
- `--dry-run` optional, simuliert schwere Operationen ohne tatsächliche Ausführung
**Reales Verhalten im Code**
- lädt den Job aus der Datenbank
- bricht mit Fehler ab, wenn der Job nicht gefunden wird
- beendet sich erfolgreich, wenn der Job bereits terminal ist (`COMPLETED`, `FAILED`, `ABORTED`)
- ruft sonst `IngestOrchestrator->runExistingJob($job, $dryRun)` auf
**Beispiele**
```bash
bin/console mto:agent:ingest:run <jobUuid>
bin/console mto:agent:ingest:run <jobUuid> --dry-run
```
---
## `mto:agent:vector:rebuild`
Erzwingt vollständigen Vector-Rebuild aus `index.ndjson`.
### `mto:agent:system:rebuild`
Globaler Hard-Rebuild des Systems.
**Zweck**
- FAISS komplett neu aufbauen
- Kein Re-Chunking
- Reine Vektor-Neuerstellung
**Signatur**
```bash
bin/console mto:agent:system:rebuild --hard [--no-tags] [--no-reload] [--no-health] [--dry-run]
```
**Optionen**
- `--hard` **Pflicht-Sicherheitsschalter**; ohne diese Option bricht das Kommando ab
- `--no-tags` überspringt den Tag-Rebuild
- `--no-reload` überspringt Reload/Start des Vector-Service
- `--no-health` überspringt den abschließenden Health-Check
- `--dry-run` simuliert den Reindex ohne Schreiboperationen
**Reales Verhalten im Code**
1. erzeugt einen neuen `IngestJob` vom Typ `GLOBAL_REINDEX`
2. führt den globalen Reindex über den Orchestrator aus
3. exportiert optional `tags.ndjson` und baut `vector_tags.index` neu
4. startet bzw. reloadet optional den Python-Vector-Service
5. führt optional Chunk- und Tag-Health-Checks aus
**Beispiele**
```bash
bin/console mto:agent:system:rebuild --hard
bin/console mto:agent:system:rebuild --hard --dry-run
bin/console mto:agent:system:rebuild --hard --no-tags --no-reload
```
**Hinweis**
Dieses Kommando ist aktuell der zentrale Produktions-Entry-Point für einen vollständigen Neuaufbau des Retrieval-Stacks.
---
## 4. Vector / Retrieval
### `mto:agent:vector:rebuild`
Baut den Chunk-Vektorindex neu.
**Signatur**
```bash
bin/console mto:agent:vector:rebuild
```
**Reales Verhalten im Code**
- schreibt `Rebuilding vector index...`
- ruft `VectorIndexBuilder->rebuildFromNdjson()` auf
- schreibt anschließend `Done.`
**Beispiel**
```bash
bin/console mto:agent:vector:rebuild
```
---
# 3. Vector Service (Python / FastAPI)
### `mto:agent:vector:control`
Steuert den persistenten Python-Vector-Service über `python/vector/vector_control.py`.
## `mto:agent:vector:control`
Steuert den persistenten Python-Vector-Service.
**Signatur**
```bash
bin/console mto:agent:vector:control [optionen]
```
**Beschreibung**
Production-sicheres Management des uvicorn-FastAPI-Dienstes.
**Unterstützte Optionen**
- `--install` installiert fehlende Python-Dependencies in `.venv`
- `--start` startet den Service, falls er nicht läuft
- `--stop` stoppt den Service anhand der PID-Datei
- `--force` erzwingt einen Hard-Stop
- `--reload` triggert den `/reload`-Endpoint des Service
- `--status` gibt den aktuellen Status aus
- `--foreground` startet im Vordergrund
- `--port=8090` setzt den Port
- `--host=0.0.0.0` setzt den Host
### Optionen
**Reales Verhalten im Code**
- baut einen Prozessaufruf gegen `.venv/bin/python python/vector/vector_control.py`
- reicht gesetzte Optionen durch
- hängt immer `--port` und `--host` an
- gibt `stdout` des Python-Skripts direkt aus
| Option | Beschreibung |
|--------|--------------|
| `--install` | Fehlende Python-Dependencies installieren |
| `--start` | Service starten |
| `--stop` | Service stoppen |
| `--force` | Hard-Stop (SIGKILL) |
| `--reload` | /reload Trigger |
| `--status` | Status anzeigen |
| `--foreground` | Vordergrundstart |
| `--port=8090` | Port |
| `--host=0.0.0.0` | Host |
### Beispiele
Installieren:
**Beispiele**
```bash
bin/console mto:agent:vector:control --install
```
Starten:
```bash
bin/console mto:agent:vector:control --start
```
Status:
```bash
bin/console mto:agent:vector:control --status
```
Reload:
```bash
bin/console mto:agent:vector:control --reload
bin/console mto:agent:vector:control --stop --force
```
---
## `mto:agent:vector:health`
Gesundheitscheck von:
- index.ndjson
- vector.index
- index_meta.json
- Embedding-Dimensionen
- Konsistenz
### `mto:agent:vector:health`
Health-Check für Chunk-NDJSON und Chunk-Vektorindex.
**Signatur**
```bash
bin/console mto:agent:vector:health
```
Ausgabe erfolgt als JSON.
---
## `mto:agent:test-vector`
Testet direkte Vector-Suche.
**Reales Verhalten im Code**
- ruft `VectorIndexHealthService->check()` auf
- gibt den Report als JSON aus
- endet mit Exit-Code `0`, wenn `status` mit `OK` beginnt; sonst `1`
**Beispiel**
```bash
bin/console mto:agent:test-vector "Suchanfrage"
bin/console mto:agent:vector:health
```
---
# 4. Tag-System
### `mto:agent:test-vector`
Debug-Kommando für einen realistischen Retrieval-Test.
## `mto:agent:tags:export`
Exportiert alle Tags in `tags.ndjson`.
**Signatur**
```bash
bin/console mto:agent:test-vector <prompt>
```
**Zweck**
- Grundlage für tag-basiertes Routing
- Keine Vector-Erstellung
**Argumente**
- `prompt` erforderlich, Testanfrage für das Retrieval
**Reales Verhalten im Code**
- führt zuerst Tag-Routing über `TagVectorSearchClient` aus
- führt danach Chunk-Retrieval über `VectorSearchClient` aus
- misst Tag-, Chunk- und Gesamtdauer
- gibt beide Result-Sets als JSON aus
**Beispiel**
```bash
bin/console mto:agent:test-vector "welche dokumente behandeln den ingest-flow?"
```
---
## 5. Tag-System
### `mto:agent:tags:export`
Exportiert die Tag-Datenbasis nach `tags.ndjson`.
**Signatur**
```bash
bin/console mto:agent:tags:export
```
**Reales Verhalten im Code**
- ruft `TagNdjsonExporter->export()` auf
- gibt Pfad, Tag-Anzahl, Zeilen und Bytes aus
**Beispiel**
```bash
bin/console mto:agent:tags:export
```
---
## `mto:agent:tags:rebuild`
Vollständiger Tag-Rebuild:
### `mto:agent:tags:rebuild`
Kompletter Neuaufbau des Tag-Retrievals.
1. Export `tags.ndjson`
2. Erstellen von `vector_tags.index`
3. index_meta.json Update
**Signatur**
```bash
bin/console mto:agent:tags:rebuild
```
**Reales Verhalten im Code**
1. exportiert `tags.ndjson`
2. baut `vector_tags.index`
3. setzt einen Runtime-Marker über `IndexMetaManager->touchRuntime()`
**Beispiel**
```bash
bin/console mto:agent:tags:rebuild
```
---
## `mto:agent:tags:job:run`
Führt einen einzelnen TagRebuildJob aus.
**Mit Lock-Mechanismus.**
### `mto:agent:tags:job:run`
Führt einen Tag-Rebuild-Job mit File-Lock aus.
**Signatur**
```bash
bin/console mto:agent:tags:job:run [jobId] [--create]
```
**Argumente / Optionen**
- `jobId` optional, UUID eines bestehenden `TagRebuildJob`
- `--create` optional, erstellt und startet sofort einen neuen `TagRebuildJob`
**Regeln im Code**
- entweder `jobId` **oder** `--create`
- beides zusammen ist ungültig
- keines von beiden ist ebenfalls ungültig
**Reales Verhalten im Code**
- markiert den Job auf `RUNNING`
- sperrt parallel laufende Tag-Rebuilds per File-Lock
- exportiert `tags.ndjson`
- baut `vector_tags.index`
- markiert den Job bei Erfolg als `COMPLETED`, sonst als `FAILED`
**Beispiele**
```bash
bin/console mto:agent:tags:job:run --create
bin/console mto:agent:tags:job:run <jobUuid>
```
---
# 5. User-Management
### `mto:agent:tag:health`
Health-Check für das Tag-Retrieval.
## `mto:agent:user:create`
Erstellt einen neuen Admin-User.
**Signatur**
```bash
bin/console mto:agent:tag:health
```
Interaktiver Ablauf:
- E-Mail
- Passwort
- Rollenwahl
**Reales Verhalten im Code**
- ruft `TagVectorIndexHealthService->check()` auf
- gibt den Report als JSON aus
- endet mit Exit-Code `0`, wenn `status` mit `OK` beginnt; sonst `1`
**Beispiel**
```bash
bin/console mto:agent:tag:health
```
**Wichtige Korrektur zur alten Doku**
Der reale Command-Name ist **`tag:health` (Singular)**, nicht `tags:health`.
---
## 6. Commerce / Shopware Debug
### `mto:agent:test:shop-search`
Testkommando für die Shopware-Suche.
**Signatur**
```bash
bin/console mto:agent:test:shop-search [query]
```
**Argumente**
- `query` optional
- Default im Code: `zeige mir testomat modelle wasserhärte unter 5000 euro`
**Beabsichtigtes Verhalten**
- ruft die Shop-Suche auf
- gibt pro Treffer Produktdaten wie ID, Produktnummer, Hersteller, Preis, Verfügbarkeit, URL und Description aus
**Wichtiger Code-Hinweis**
Im aktuellen Stand von `rag.zip` ruft das Command `ShopSearchService->search($query)` mit **einem** Argument auf, die Service-Signatur erwartet aber **zwei** Argumente (`string $originalPrompt, string $commerceIntent`). Das Kommando ist daher im aktuellen Codebestand sehr wahrscheinlich **nicht lauffähig**, solange diese Signaturabweichung nicht behoben wird.
---
## 7. User-Management
### `mto:agent:user:create`
Interaktive Anlage eines Users.
**Signatur**
```bash
bin/console mto:agent:user:create
```
**Interaktiver Ablauf**
1. E-Mail eingeben
2. Passwort eingeben
3. Rolle wählen
**Validierungen im Code**
- E-Mail muss valide sein
- User mit gleicher E-Mail darf nicht bereits existieren
- Passwort muss mindestens 8 Zeichen lang sein
**Im Code auswählbare Rollen**
- `ROLE_SUPER_ADMIN`
- `ROLE_KNOWLEDGE_ADMIN`
- `ROLE_EDITOR`
- `ROLE_USER`
**Beispiel**
```bash
bin/console mto:agent:user:create
```
---
# 6. Architektur-Zusammenhang der Commands
## 8. Typische Betriebsabläufe
| Bereich | Command-Typ |
|----------|------------|
| Dokumente | ingest:version |
| Jobs | ingest:run |
| Vector Index | vector:rebuild |
| Vector Service | vector:control |
| Vector Health | vector:health |
| Tag Export | tags:export |
| Tag Rebuild | tags:rebuild |
| Tag Job | tags:job:run |
| Agent CLI | chat |
| User | user:create |
### Manueller Ingest einer Version
```bash
bin/console mto:agent:ingest:version <documentVersionUuid> <userUuid>
```
---
# 7. Typischer Produktions-Workflow
### 1⃣ Dokument aktivieren
→ erzeugt IngestJob
### 2⃣ Job ausführen
### Vorhandenen Ingest-Job ausführen
```bash
bin/console mto:agent:ingest:run <jobUuid>
```
### 3Vector-Service prüfen
### Nur Chunk-Vektorindex neu bauen
```bash
bin/console mto:agent:vector:health
bin/console mto:agent:vector:rebuild
```
### 4⃣ Optional: Service reload
### Gesamtsystem hart neu aufbauen
```bash
bin/console mto:agent:system:rebuild --hard
```
### Vector-Service prüfen und reloaden
```bash
bin/console mto:agent:vector:health
bin/console mto:agent:vector:control --reload
```
---
# 8. System-Ebenen
| Ebene | Technologie |
|--------|------------|
| Symfony | PHP / Doctrine |
| Retrieval | NDJSON + FAISS |
| Vector Service | Python FastAPI |
| Persistence | index.ndjson |
| Governance | index_meta.json |
| Streaming | SSE |
| CLI | Symfony Console |
---
# 9. Wichtige Dateien (Runtime)
```
var/
├── run/
│ └── vector.pid
├── index.ndjson
├── index_meta.json
├── vector.index
└── vector_tags.index
```
---
# 10. Sicherheit & Locks
- IngestFlow schützt mit LockService
- Tag-Rebuild verwendet File-Lock
- Vector-Service PID-basiert
- Global Rebuild atomar via `.tmp` + rename()
---
# 11. Empfohlene Admin-Checks
Regelmäßig ausführen:
### Tag-Retrieval neu aufbauen
```bash
bin/console mto:agent:vector:health
bin/console mto:agent:tags:rebuild
bin/console mto:agent:tag:health
```
Bei Änderungen am Embedding-Modell:
→ vollständiger Rebuild
---
# Ende der Command-Dokumentation
System-Stand: rag.zip (aktueller Projektzustand)
## 9. Wichtige Runtime-Dateien und Pfade
Die bisherige Doku nannte teilweise veraltete Pfade unter `var/`. Im aktuellen Code liegen die Knowledge-Artefakte primär unter `var/knowledge/`.
```text
var/
├── knowledge/
│ ├── index.ndjson
│ ├── index_meta.json
│ ├── index_runtime.json
│ ├── vector.index
│ ├── vector.index.meta.json
│ ├── tags.ndjson
│ ├── vector_tags.index
│ ├── vector_tags.index.meta.json
│ ├── uploads/
│ └── locks/
│ └── tag_rebuild.lock
├── run/
│ └── vector_service.pid
└── locks/
└── ingest.lock
```
**Herkunft im Code**
- `config/services.yaml` definiert `mto.knowledge.root = %mto.root%/var/knowledge`
- `python/vector/vector_control.py` verwendet `var/run/vector_service.pid`
- `App\Service\LockService` verwendet aktuell `var/locks/ingest.lock`
---
## 10. Wichtige Abweichungen zur alten `COMMAND_REF.md`
Die bisherige Datei war in mehreren Punkten nicht mehr codekonform. Wesentliche Korrekturen:
1. `mto:agent:system:rebuild` fehlte vollständig
2. `mto:agent:test:shop-search` fehlte vollständig
3. `mto:agent:tag:health` fehlte und war zudem leicht falsch benannt
4. `mto:agent:ingest:version` braucht aktuell **`<versionId> <userId>`**
5. Runtime-Dateien liegen nicht nur unter `var/`, sondern überwiegend unter `var/knowledge/`
6. der globale Rebuild läuft heute über `mto:agent:system:rebuild --hard`, nicht über ein dokumentiertes `ingest:global`
---
## 11. Fazit
Der aktuelle Custom-CLI-Umfang des Systems besteht aus **14 projektspezifischen Commands**. Für den operativen Betrieb sind besonders relevant:
- `mto:agent:ingest:run`
- `mto:agent:system:rebuild`
- `mto:agent:vector:control`
- `mto:agent:vector:health`
- `mto:agent:tags:rebuild`
- `mto:agent:tag:health`

View File

@@ -1,42 +1,84 @@
# RAG-System Enterprise Installationsanleitung
# RetrieX Installationsanleitung
Stand: Februar 2026
Architektur: Symfony (PHP 8.2+) + MariaDB 10.11 + Python Vector Service (FAISS) + Ollama LLM
Betriebsmodus: On-Prem / Containerfähig / CPU-basiert
Stand: 15.04.2026
Quelle: aktuelle `rag.zip` (Single Source of Truth)
Diese Anleitung beschreibt eine vollständige Neuinstallation auf sauberer Infrastruktur.
Diese Anleitung beschreibt die **codebasierte Neuinstallation** des aktuellen Systems. Sie ersetzt ältere Installationsstände. Alle Angaben unten wurden an den tatsächlich vorhandenen Dateien, Services, Commands und Pfaden aus dem ZIP ausgerichtet.
---
# 1. Systemvoraussetzungen
## 1. Architektur des aktuellen Stands
## 1.1 Betriebssystem
RetrieX besteht aktuell aus diesen Hauptbausteinen:
- **Symfony 7.4** auf **PHP 8.2+**
- **Doctrine ORM + Doctrine Migrations**
- **MariaDB/MySQL** als operative Datenbank
- **Python-Vektorlayer** mit `faiss-cpu`, `sentence-transformers`, `fastapi`, `uvicorn`
- **Ollama-kompatibler LLM-Endpunkt** über `AI_LLM_API_URL`
- **NDJSON + FAISS** im Dateisystem unter `var/knowledge`
- **Adminoberfläche** für Dokumente, Ingest-Profile, System Prompt, Modellkonfiguration und Jobs
- **SSE-Streaming** für den Browser-Chat
Wichtige Betriebsordner im aktuellen Code:
- `var/knowledge/` → NDJSON, FAISS-Indizes, Uploads
- `var/log/` → System-, Agent- und Ingest-Logs
- `var/run/` → PID-Dateien des Python-Services
- `var/locks/` → Ingest-Lock
- `python/vector/` → Python-Control-, Search- und Service-Skripte
---
## 2. Wichtige Korrekturen gegenüber älteren Installationsständen
Die frühere `INSTALL.md` passt nicht mehr zum aktuellen Code. Für den aktuellen Stand gelten insbesondere diese Punkte:
- Der Wissensspeicher liegt unter **`var/knowledge/`**, nicht unter `var/vector/`.
- Der Python-Code liegt unter **`python/vector/`**, nicht unter `vector/`.
- Die Python-Abhängigkeiten kommen aus der Datei **`requirements.txt` im Projektroot**.
- Der korrekte Rebuild-Befehl ist **`mto:agent:system:rebuild --hard`**, nicht `mto:agent:ingest:global`.
- Das LLM-Modell kommt **nicht** mehr aus einer `AI_LLM_MODEL`-Umgebungsvariable, sondern aus der **aktiven ModelGenerationConfig** in der Adminoberfläche.
- Für den Chat sind **zwingend** nötig:
- ein **aktiver System Prompt**
- eine **aktive ModelGenerationConfig**
- mindestens ein erfolgreich indexiertes Dokument für wissensbasiertes Retrieval
- Die Upload-UI erwähnt mehrere Dateitypen, der aktuelle Extractor-Code unterstützt jedoch **faktisch nur PDF**.
---
## 3. Systemvoraussetzungen
## 3.1 Betriebssystem
Empfohlen:
- Ubuntu 22.04 LTS (Server)
Alternativ:
- Debian 12
- macOS (Entwicklung)
- Windows nur via WSL2
- Ubuntu 22.04 LTS oder neuer
- Debian 12 ist ebenfalls passend
Für lokale Entwicklung sind auch macOS oder Linux-Container-Setups möglich.
---
## 1.2 PHP
## 3.2 PHP
Version:
- PHP 8.2 oder höher
Erforderlich:
Erforderliche Extensions:
- pdo
- pdo_mysql
- mbstring
- intl
- curl
- json
- zip
- **PHP 8.2 oder höher**
Prüfung:
Benötigte bzw. praktisch notwendige Extensions aus dem aktuellen Projektstand:
- `ctype`
- `curl`
- `dom`
- `iconv`
- `libxml`
- `pdo`
- `pdo_mysql`
- `mbstring`
- `zip`
Prüfen:
```bash
php -v
@@ -45,32 +87,33 @@ php -m
---
## 1.3 Composer
## 3.3 Composer
Prüfen:
```bash
composer --version
```
Falls nicht vorhanden:
```bash
sudo apt install composer
```
Falls Composer nicht global vorhanden ist, kann lokal installiert werden. Für den regulären Betrieb ist ein globaler Composer aber sinnvoll.
---
## 1.4 Datenbank
## 3.4 Datenbank
Version:
- MariaDB 10.11.x (entspricht aktueller ENV)
Der aktuelle Projektstand ist praktisch auf **MariaDB/MySQL** ausgerichtet.
Installation:
Empfohlen:
- **MariaDB 10.11.x**
Beispielinstallation:
```bash
sudo apt install mariadb-server
```
Datenbank und Benutzer anlegen:
Beispiel für Datenbank und Benutzer:
```sql
CREATE DATABASE db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
@@ -79,12 +122,18 @@ GRANT ALL PRIVILEGES ON db.* TO 'db'@'%';
FLUSH PRIVILEGES;
```
Hinweis:
Die mitgelieferte `.env` enthält derzeit noch eine PostgreSQL-Placeholder-URL. Für den realen Betrieb muss `DATABASE_URL` auf **MariaDB/MySQL** gesetzt werden.
---
## 1.5 Python
## 3.5 Python
Version:
- Python 3.10 oder höher
Erforderlich:
- **Python 3.10 oder höher**
- `python3-venv`
- `python3-pip`
Installation:
@@ -100,49 +149,63 @@ python3 --version
---
## 1.6 Ollama (LLM Backend)
## 3.6 Ollama oder kompatibler Generate-Endpunkt
Installation:
RetrieX spricht den LLM-Endpunkt über `AI_LLM_API_URL` an. Erwartet wird ein **Ollama-kompatibler `/api/generate`-Endpoint**.
Beispiel mit Ollama:
```bash
curl -fsSL https://ollama.com/install.sh | sh
```
Modell bereitstellen:
Ein Modell muss lokal vorhanden sein, zum Beispiel:
```bash
ollama pull qwen3
oder
ollama pull mto-model (Wenn eigens KI-Model erstellt wurde)
```
oder ein projektspezifisches Modell, falls vorhanden.
Verfügbarkeit prüfen:
```bash
curl http://127.0.0.1:11434/api/tags
```
---
# 2. Projektbereitstellung
## 2.1 Entpacken
```bash
unzip rag.zip
cd rag
```
oder via Git:
```bash
git clone <repository>
cd <repository>
```
Wichtig:
Welches Modell tatsächlich benutzt wird, bestimmt später die **aktive ModelGenerationConfig im Admin**, nicht eine `.env`-Variable.
---
## 2.2 PHP-Abhängigkeiten installieren
## 3.7 Optional: Shopware Store API
Der Commerce-Pfad ist im aktuellen Code **standardmäßig aktiviert**. Für produktbezogene Anfragen nutzt das System optional die Shopware Store API.
Dafür werden diese Variablen verwendet:
- `SHOPWARE_STORE_API_BASE_URL`
- `SHOPWARE_SALES_CHANNEL_ACCESS_KEY`
- `SHOPWARE_STORE_API_MAX_RESULT`
Wenn keine Shopware-Suche gewünscht ist, sollte der Commerce-Pfad vor produktivem Einsatz bewusst deaktiviert oder sauber konfiguriert werden.
---
## 4. Projekt bereitstellen
ZIP entpacken und ins Projekt wechseln:
```bash
unzip rag.zip -d retriex
cd retriex
```
Alternativ über Repository-Checkout, falls das Projekt aus Git bereitgestellt wird.
---
## 5. PHP-Abhängigkeiten installieren
```bash
composer install --no-interaction
@@ -151,121 +214,91 @@ composer install --no-interaction
Für Produktion:
```bash
composer install --no-dev --optimize-autoloader
composer install --no-dev --optimize-autoloader --no-interaction
```
Erst nach diesem Schritt funktionieren `bin/console` und die Symfony-Commands.
---
# 3. Environment-Konfiguration
## 6. Umgebung konfigurieren
Datei `.env` im Projektroot konfigurieren.
## 6.1 Grundregel
## 3.1 Symfony Core
Lokale oder serverbezogene Overrides sollten in **`.env.local`** gepflegt werden, nicht direkt in der committeten `.env`.
```env
APP_ENV=dev
APP_SECRET=09333662211af45850ff13d68a40f8e3
```
---
Produktion:
## 6.2 Minimale `.env.local`
Beispiel für einen lokalen oder servernahen MariaDB-Betrieb:
```env
APP_ENV=prod
```
APP_SECRET=change-me
---
DATABASE_URL="mysql://db:db@127.0.0.1:3306/db?serverVersion=10.11.0-mariadb&charset=utf8mb4"
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
## 3.2 AI Agent Core
```env
AI_LLM_API_URL=http://host.docker.internal:11434/api/generate
AI_LLM_MODEL=mto-model
AI_LLM_API_URL=http://127.0.0.1:11434/api/generate
AI_LLM_TIMEOUT=600
AI_HISTORY_DIR=var/agent-history
AI_CONTEXT_LINES=20
AI_CONTEXT_LINES_FULL=500
```
Hinweise:
- Timeout unter 600 Sekunden wird nicht empfohlen.
- API-URL an Infrastruktur anpassen (Docker vs. Localhost).
---
## 3.3 Debug-Konfiguration
```env
AI_DEBUG=false
AI_LOG_PROMPT=false
AI_LOG_CONTEXT=false
SHOPWARE_STORE_API_BASE_URL="https://example.invalid"
SHOPWARE_SALES_CHANNEL_ACCESS_KEY="replace-me"
SHOPWARE_STORE_API_MAX_RESULT=25
```
In Entwicklungsumgebung optional aktivieren.
Hinweise:
- `APP_ENV=prod` ist im aktuellen `.env` bereits voreingestellt.
- `DATABASE_URL` muss auf MariaDB/MySQL zeigen.
- `AI_LLM_API_URL` muss auf einen funktionierenden `/api/generate`-Endpoint zeigen.
- `AI_LLM_TIMEOUT=600` ist mit dem aktuellen Code konsistent.
- `AI_LLM_MODEL` wird **nicht** verwendet.
---
## 3.4 Datenbank (aktive Konfiguration)
## 6.3 Shopware deaktivieren, wenn nicht benötigt
Nur diese DATABASE_URL verwenden:
Im aktuellen Code ist `mto.commerce.enabled` in `config/services.yaml` auf `true` gesetzt. Wer die Shopware-Suche nicht einsetzen will, sollte vor produktivem Einsatz bewusst einen dieser Wege wählen:
```env
DATABASE_URL="mysql://db:db@db:3306/db?sslmode=disable&charset=utf8mb4&serverVersion=10.11.0-mariadb"
DATABASE_VERSION="10.11.0-mariadb"
DATABASE_DRIVER="mysql"
DATABASE_HOST="db"
DATABASE_PORT="3306"
DATABASE_USER="db"
DATABASE_PASSWORD="db"
DATABASE_NAME="db"
DATABASE_SERVER="mysql://db:3306"
```
1. gültige Shopware-Zugangsdaten hinterlegen, oder
2. `config/services.yaml` gezielt anpassen und Commerce deaktivieren.
Wichtig:
- PostgreSQL-Konfiguration entfernen.
- Nur eine DATABASE_URL definieren.
Für reine Wissens- und Dokumentinstallation ist die Shopware-Anbindung nicht zwingend, sollte aber nicht unklar halbkonfiguriert bleiben.
---
## 3.5 Messenger
## 7. Datenbank initialisieren
```env
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
```
Queue läuft über Datenbank.
---
## 3.6 Mailer (optional)
```env
MAILER_DSN="smtp://127.0.0.1:1025"
MAILER_HOST="127.0.0.1"
MAILER_PORT="1025"
MAILER_DRIVER="smtp"
MAILER_AUTH_MODE=""
MAILER_USERNAME=""
MAILER_PASSWORD=""
MAILER_CATCHER="1"
MAILER_WEB_URL="https://rag.ddev.site:8026"
```
Nur relevant wenn Mailfunktionen aktiv genutzt werden.
---
# 4. Datenbankmigration
Migrationen ausführen:
```bash
php bin/console doctrine:migrations:migrate --no-interaction
```
Damit werden unter anderem diese zentralen Tabellen angelegt:
- `user`
- `document`
- `document_version`
- `ingest_job`
- `system_prompt`
- `ingest_profile`
- `model_generation_config`
- `knowledge_tag`
- `document_tag`
- `tag_rebuild_job`
---
# 5. Python Vector Service
## 8. Python-Umgebung aufbauen
## 5.1 Virtual Environment anlegen
## 8.1 Virtuelle Umgebung anlegen
```bash
python3 -m venv .venv
@@ -274,25 +307,29 @@ source .venv/bin/activate
---
## 5.2 Abhängigkeiten installieren
## 8.2 Python-Abhängigkeiten installieren
Automatisiert:
Manuell:
```bash
pip install --upgrade pip
pip install -r requirements.txt
```
Alternativ nach angelegter `.venv` über den Symfony-Wrapper:
```bash
php bin/console mto:agent:vector:control --install
```
Alternativ manuell:
```bash
pip install fastapi uvicorn sentence-transformers faiss-cpu numpy
```
CPU-Version von FAISS ist ausreichend.
Wichtig:
Der Wrapper erwartet bereits eine existierende `.venv`. Er erzeugt sie **nicht** selbst.
---
## 5.3 Vector Service starten
## 9. Vector Service starten
Start:
```bash
php bin/console mto:agent:vector:control --start
@@ -304,99 +341,329 @@ Status prüfen:
php bin/console mto:agent:vector:control --status
```
---
# 6. Initialer Reindex
Vor produktiver Nutzung zwingend erforderlich:
Optionaler Reload:
```bash
php bin/console mto:agent:ingest:global
php bin/console mto:agent:vector:control --reload
```
Ohne Reindex ist kein Retrieval möglich.
Der Service startet aktuell standardmäßig auf:
- Host: `0.0.0.0`
- Port: `8090`
Der PHP-Code spricht standardmäßig gegen:
- `http://127.0.0.1:8090`
---
# 7. Anwendung starten
## 10. Admin-Benutzer anlegen
Entwicklung:
Ohne Admin-Benutzer lässt sich das System nicht fertig konfigurieren.
CLI-Befehl:
```bash
php bin/console mto:agent:user:create
```
Der Command fragt interaktiv ab:
- E-Mail
- Passwort
- Rolle
Für die Erstinstallation ist typischerweise sinnvoll:
- `ROLE_SUPER_ADMIN`
---
## 11. Anwendung starten
Für einen einfachen lokalen Test:
```bash
php -S 127.0.0.1:8000 -t public
```
Produktion:
- Über Nginx oder Apache bereitstellen
- APP_ENV=prod setzen
- Cache warmup durchführen
Danach sind typischerweise relevant:
- Chat-Frontend: `http://127.0.0.1:8000/`
- Admin-Login: `http://127.0.0.1:8000/admin/login`
Für Produktion sollte stattdessen ein regulärer Webserver genutzt werden, zum Beispiel Nginx + PHP-FPM.
---
## 12. Pflicht-Initialisierung im Admin
Nach der technischen Grundinstallation ist das System **noch nicht vollständig betriebsbereit**. Es müssen im Admin zwingend Inhalte angelegt werden.
## 12.1 System Prompt anlegen und aktivieren
Pfad im Admin:
- `/admin/system/prompt`
Ohne aktiven System Prompt wirft der PromptBuilder zur Laufzeit einen Fehler.
---
## 12.2 ModelGenerationConfig anlegen und aktivieren
Pfad im Admin:
- `/admin/model-config/`
Ohne aktive ModelGenerationConfig schlägt das Retrieval fehl, weil `NdjsonHybridRetriever` explizit eine aktive Konfiguration verlangt.
Sinnvolle Minimalwerte für einen stabilen Start:
- Modellname: exakt wie im Ollama-Endpunkt verfügbar, z. B. `qwen3:latest`
- Streaming: aktiv
- Temperature: `0.2` bis `0.4`
- Top K: `40`
- Top P: `0.9`
- Repeat Penalty: `1.1`
- num_ctx: `8192`
- Retrieval Max Chunks: `25`
- Retrieval Vector Top K: `25`
---
## 12.3 Optional: Ingest-Profil anlegen
Pfad im Admin:
- `/admin/ingest-profiles/`
Wenn kein Profil aktiv ist, fällt das System auf die Parameter aus `config/services.yaml` zurück:
- Chunk Size: `800`
- Chunk Overlap: `100`
- Embedding Model: `intfloat/multilingual-e5-base`
- Embedding Dimension: `768`
- Scoring Version: `1`
Das ist für einen ersten Start ausreichend. Ein eigenes Ingest-Profil ist also **optional**, solange man die Fallback-Werte bewusst akzeptiert.
---
## 13. Erste Dokumente ingestieren
## 13.1 Wichtiger Format-Hinweis
Die Upload-Maske nennt mehrere Formate, aber der aktuelle Extractor-Code enthält nur einen **`PdfExtractor`**. Für einen sicheren Erstbetrieb sollten daher aktuell **nur PDF-Dateien** hochgeladen werden.
---
## 13.2 Erstes Dokument hochladen
Pfad im Admin:
- `/admin/documents/new`
Beim Upload passiert im aktuellen Code folgendes:
1. Datei wird nach `var/knowledge/uploads` verschoben.
2. Dokument und Version 1 werden in der DB angelegt.
3. Die neue Version wird aktiv gesetzt.
4. Ein Ingest-Job vom Typ `DOCUMENT_VERSION_ACTIVATE` wird erstellt.
5. Der Job wird **asynchron per `exec()`** gestartet.
---
## 13.3 Wenn `exec()` deaktiviert ist
Der Admin-Flow für Upload, Aktivierung und Löschen setzt im aktuellen Code Hintergrundstarts über `exec()` voraus.
Ist `exec()` serverseitig deaktiviert, werden Jobs zwar angelegt, aber nicht automatisch ausgeführt. In diesem Fall muss der Job manuell gestartet werden:
```bash
php bin/console cache:clear --env=prod
php bin/console cache:warmup --env=prod
php bin/console mto:agent:ingest:run <jobId>
```
Die `jobId` ist in der Job-Ansicht im Admin nachvollziehbar.
---
## 14. Rebuild und Konsistenzprüfung
## 14.1 Vollständiger System-Rebuild
Sobald aktive Dokumente vorhanden sind, kann ein vollständiger Rebuild ausgeführt werden:
```bash
php bin/console mto:agent:system:rebuild --hard
```
Dieser Ablauf umfasst aktuell:
1. globalen Reindex der aktiven Dokumente
2. Tag-Export und Tag-Index-Rebuild
3. Reload des Vector Service
4. Health-Checks
Wichtig:
Der Befehl bricht absichtlich ab, wenn **keine aktiven Dokumente** vorhanden sind.
---
## 14.2 Vector Health prüfen
```bash
php bin/console mto:agent:vector:health
```
Mögliche gesunde Zustände:
- `OK_EMPTY` → noch keine Wissensdaten vorhanden
- `OK` → NDJSON und FAISS konsistent
---
## 14.3 Tag Health prüfen
```bash
php bin/console mto:agent:tag:health
```
---
# 8. Funktionstest
## 15. Wichtige Commands im aktuellen Stand
1. Datenbank erreichbar
2. Migration erfolgreich
3. Vector Service aktiv
4. Ollama erreichbar
5. Global Reindex durchgeführt
6. Dokument hochgeladen
7. Version aktiviert
8. Chat liefert Antwort
---
# 9. Betriebsrelevante Hinweise
## Modellwechsel
Bei Änderung von:
- AI_LLM_MODEL
Kein Reindex erforderlich.
Bei Änderung von:
- Embedding-Modell (Python-Seite)
- Embedding-Dimension
- Chunking-Parametern
Global Reindex zwingend erforderlich.
---
## NDJSON und Vector Index
Speicherort:
```
var/vector/
```bash
php bin/console mto:agent:user:create
php bin/console mto:agent:vector:control --install
php bin/console mto:agent:vector:control --start
php bin/console mto:agent:vector:control --status
php bin/console mto:agent:vector:control --reload
php bin/console mto:agent:vector:rebuild
php bin/console mto:agent:vector:health
php bin/console mto:agent:ingest:run <jobId>
php bin/console mto:agent:ingest:version <versionId> <userId>
php bin/console mto:agent:system:rebuild --hard
php bin/console mto:agent:tags:export
php bin/console mto:agent:tags:rebuild
php bin/console mto:agent:tag:health
php bin/console mto:agent:chat
php bin/console mto:agent:test:shop-search "deine Anfrage"
```
Nicht manuell verändern.
Index ist deterministisch und wird vollständig neu aufgebaut.
---
## 16. Minimaler Go-Live-Check
Eine Installation ist im aktuellen Stand erst dann wirklich lauffähig, wenn alle folgenden Punkte erfüllt sind:
- Composer-Abhängigkeiten installiert
- Datenbankmigrationen erfolgreich durchgelaufen
- `.env.local` korrekt gesetzt
- `.venv` vorhanden und Python-Abhängigkeiten installiert
- Vector Service läuft auf Port `8090`
- Admin-Benutzer existiert
- aktiver System Prompt vorhanden
- aktive ModelGenerationConfig vorhanden
- mindestens ein PDF erfolgreich ingestiert
- `mto:agent:vector:health` liefert `OK` oder `OK_EMPTY`
- Chat-Frontend und Admin-Login sind erreichbar
---
## Produktionsbetrieb
## 17. Häufige Fehlerbilder
Empfohlen:
- Reverse Proxy (Nginx)
- Systemd Service für Vector Service
- Eigener Service für Ollama
- Backup von Datenbank + var/vector/
## 17.1 `No active system prompt configured.`
Ursache:
Es existiert kein aktiver System Prompt.
Lösung:
Im Admin unter `/admin/system/prompt` eine Version speichern und aktivieren.
---
# Installation abgeschlossen
## 17.2 `No active ModelGenerationConfig found.`
Das System ist betriebsbereit für:
Ursache:
Es existiert keine aktive Modellkonfiguration.
- Versionierte Dokumentverwaltung
- Deterministischen NDJSON-Ingest
- FAISS-Vektorindex
- Hybrid Retrieval
- LLM-gestützte Antwortgenerierung
Lösung:
Im Admin unter `/admin/model-config/` eine Konfiguration anlegen und aktivieren.
---
## 17.3 Vector Service startet nicht
Typische Ursachen:
- `.venv` fehlt
- Python-Pakete fehlen
- Port `8090` ist schon belegt
- `uvicorn` ist nicht in der virtuellen Umgebung installiert
Prüfen:
```bash
php bin/console mto:agent:vector:control --status
```
---
## 17.4 Rebuild bricht mit „no active documents found“ ab
Ursache:
Es wurde noch kein aktives Dokument erfolgreich angelegt.
Lösung:
Zuerst ein PDF hochladen und ingestieren, danach den Rebuild erneut starten.
---
## 17.5 Upload klappt, Ingest startet aber nicht
Ursache:
`exec()` ist auf dem Server deaktiviert.
Lösung:
Job manuell mit `mto:agent:ingest:run <jobId>` starten oder Serverkonfiguration anpassen.
---
## 17.6 Dokument-Ingest schlägt bei Nicht-PDF fehl
Ursache:
Der aktuelle Code enthält nur einen `PdfExtractor`.
Lösung:
Für den aktuellen Stand ausschließlich PDFs ingestieren oder Extractor-Layer erweitern.
---
## 18. Empfohlene Produktionshinweise
Für stabilen produktiven Betrieb sind sinnvoll:
- Nginx oder Apache vor Symfony/PHP-FPM
- eigener Service-Start für den Python-Vector-Service
- eigener Service für Ollama
- Backup von Datenbank und `var/knowledge/`
- Monitoring der Logs unter `var/log/`
- bewusstes Governance-Handling für Ingest-Profile, System Prompts und Model-Konfigurationen
---
## 19. Ergebnis
Nach erfolgreicher Installation bietet der aktuelle Stand von RetrieX:
- dokumentenbasierte Wissensverwaltung
- versionierte Dokumente
- asynchronen Ingest über Jobs
- NDJSON als Wissensspeicher
- FAISS-basiertes Retrieval
- optionales Tag-Routing
- optionalen Shopware-Commerce-Pfad
- browserbasierten SSE-Chat
- Symfony-Adminoberfläche für Betrieb und Governance

View File

@@ -1,38 +1,142 @@
# Alle Parameter, die Retrieval beeinflussen (mit Kurz-Erklärung)
# MATRIX_PARAMS.md
| Ebene | Ort | Parameter | Standard / aktuell | Zweck / Einfluss |
|---|---|---|---:|---|
| **Config** | ModelGenerationConfig | retrievalMaxChunks | (dein Wert) | Wie viele Chunks maximal ans LLM gehen (Output-Limit). |
| **Config** | ModelGenerationConfig | retrievalVectorTopK | (dein Wert) | Wie viele Vector-Hits initial geholt werden (Recall-Breite). |
| **Retriever** | NdjsonHybridRetriever | HARD_MAX_CHUNKS | 200 | Harte Obergrenze für retrievalMaxChunks (Safety-Limit). |
| **Retriever** | NdjsonHybridRetriever | HARD_MAX_VECTORK | 200 | Harte Obergrenze für retrievalVectorTopK/topK (Safety-Limit). |
| **Retriever** | NdjsonHybridRetriever | VECTOR_SCORE_THRESHOLD | 0.40 | Qualitäts-Gate: Vector-Treffer darunter werden verworfen (stärkster Präzisionshebel). |
| **Retriever** | NdjsonHybridRetriever | List-Mode TopK | max(vectorTopKBase*3, 80) | Bei Listenfragen wird TopK stark erhöht für bessere Dokumentabdeckung. |
| **Retriever** | NdjsonHybridRetriever | isListQuery() | Heuristik | Aktiviert Dokument-Ranking statt reinem Chunk-Ranking. |
| **Retriever** | NdjsonHybridRetriever | Dedup-Normalisierung | whitespace-normalized | Entfernt Duplikate im finalen Chunk-Set. |
| **Tags** | TagRoutingService | DEFAULT_TOPK | 8 | Anzahl der geprüften Tag-Vector-Hits. |
| **Tags** | TagRoutingService | MIN_BEST_SCORE | 0.10 (empf. 0.25) | Ab welchem Tag-Score ein Bonus aktiviert wird. |
| **Tags** | TagRoutingService | MAX_CANDIDATE_DOCS | 200 | Maximale Anzahl Dokumente, die als Tag-Kandidaten gelten dürfen. |
| **Tags** | NdjsonHybridRetriever | TAG_SCORE_BONUS | z. B. 0.08 | Bonus auf Vector-Score bei Tag-Match (nur Ranking, kein Gate). |
| **Query** | QueryCleaner | clean($prompt) | implizit | Beeinflusst Embedding stark (Token-Normalisierung/Entfernung). |
| **Vector** | VectorSearchClient | search($query, topK) | implizit | Liefert Roh-Scores und Trefferverteilung (Basis des Rankings). |
| **Tag Vector** | TagVectorSearchClient | search($query, DEFAULT_TOPK) | implizit | Bestimmt, ob und welche Tags matchen (Bonus-Aktivierung). |
# Retrieval-Matrix: alle relevanten Parameter und ihr realer Einfluss
## Zweck dieser Datei
# Tabelle 2: Auswirkungen bei Änderung der Parameter
Diese Datei beschreibt die **realen Retrieval-Parameter im aktuellen Code-Stand** von RetrieX auf Basis der aktuellen `rag.zip`.
Wichtig:
- Die Datei beschreibt **Code-Defaults, Hard Limits und effektive Laufzeitlogik**
- Die **aktiven DB-Werte** der `ModelGenerationConfig` sind aus dem Repository allein **nicht sicher ableitbar**
- Wo kein aktiver DB-Wert aus dem ZIP belegbar ist, wird zwischen **Code-Default**, **Admin-Default** und **effektivem Clamp** unterschieden
---
# 1. Die wichtigsten Hebel in Kurzform
Die Retrieval-Qualität wird im aktuellen Stand vor allem durch diese Hebel bestimmt:
1. **`retrievalMaxChunks`**
bestimmt, wie viele finale Chunks maximal ans LLM gehen
2. **`retrievalVectorTopK`**
bestimmt, wie breit die initiale Vektorsuche sucht
3. **effektiver Score-Threshold im Retriever**
bestimmt, welche Vector-Hits überhaupt in die Fusion gelangen
4. **Tag-Routing**
bestimmt, ob zusätzlich eine dokumentgescopte Suche ausgeführt wird
5. **List-Intent / Sales-Intent**
verändert TopK, Auswahlmodus und Scoping-Verhalten
6. **Selektionsregeln pro Dokument**
begrenzen Redundanz und Nachbarschaft ähnlicher Chunks
---
# 2. Matrix der Retrieval-Parameter
| Ebene | Ort | Parameter / Konstante | Aktueller Wert | Effektiver Einfluss |
|---|---|---:|---:|---|
| **DB / Config** | `ModelGenerationConfig` | `retrievalMaxChunks` | Constructor-Default: `25` | Maximalzahl finaler Chunks vor Retriever-internem Clamp |
| **DB / Config** | `ModelGenerationConfig` | `retrievalVectorTopK` | Constructor-Default: `25` | Basisbreite der initialen Vektorsuche vor Retriever-internem Clamp |
| **DB / Guardrail** | `ModelGenerationConfig` | `MAX_RETRIEVAL_CHUNKS` | `200` | Harte Obergrenze beim Setzen des DB-Werts |
| **DB / Guardrail** | `ModelGenerationConfig` | `MAX_VECTOR_TOPK` | `200` | Harte Obergrenze beim Setzen des DB-Werts |
| **Admin-Erzeugung** | `ModelGenerationConfigAdminService` | `retrieval_max_chunks` | Fallback: `25` | Standardwert beim Anlegen neuer Configs im Admin |
| **Admin-Erzeugung** | `ModelGenerationConfigAdminService` | `retrieval_vector_top_k` | Fallback: `25` | Standardwert beim Anlegen neuer Configs im Admin |
| **Fallback ohne aktive DB-Config** | `ModelGenerationConfigProvider` | `retrievalMaxChunks` | implizit `25` | Greift nur, wenn keine aktive Config existiert |
| **Fallback ohne aktive DB-Config** | `ModelGenerationConfigProvider` | `retrievalVectorTopK` | implizit `25` | Greift nur, wenn keine aktive Config existiert |
| **Retriever** | `NdjsonHybridRetriever` | `HARD_MAX_CHUNKS` | `90` | Zusätzlicher harter Retriever-Clamp für finale Chunk-Zahl |
| **Retriever** | `NdjsonHybridRetriever` | `HARD_MAX_VECTORK` | `250` | Zusätzlicher harter Retriever-Clamp für TopK; effektiv meist unter DB-Clamp |
| **Retriever** | `NdjsonHybridRetriever` | `VECTOR_SCORE_THRESHOLD` | `0.75` | Formale Basisschwelle vor zusätzlichem Floor/Ceil |
| **Retriever** | `NdjsonHybridRetriever` | `THRESHOLD_FLOOR` | `0.83` | Effektive Mindestschwelle; dominiert aktuell den Basisschwellenwert |
| **Retriever** | `NdjsonHybridRetriever` | `THRESHOLD_CEIL` | `0.92` | Effektive Maximalschwelle |
| **Retriever** | `NdjsonHybridRetriever` | `LIST_BONUS` | `1.25` | Erhöht `topK` bei Listenfragen auf `round(base * 1.25)` |
| **Retriever** | `NdjsonHybridRetriever` | `MAX_CHUNKS_PER_DOC` | `2` | Maximal zwei finale Chunks pro Dokument im Sales-Modus |
| **Retriever** | `NdjsonHybridRetriever` | `MIN_CHUNK_DISTANCE` | `2.5` | Verhindert zu nahe Chunk-Nachbarn aus demselben Dokument |
| **Retriever** | `NdjsonHybridRetriever` | `RRF_K` | `60` | Steuert die Reciprocal-Rank-Fusion |
| **Retriever** | `NdjsonHybridRetriever` | Scoped RRF Boost | `1.2` | Scoped Hits werden nur in bestimmten Fällen stärker gewichtet |
| **Retriever** | `NdjsonHybridRetriever` | `EMPTY_RRF_FALLBACK_TOPN` | `1` | Falls Fusion leer bleibt, wird maximal ein Top-Hit in Fallback-RRF überführt |
| **Intent** | `IntentLite` | `LIST_THRESHOLD` | `4` | Ab Score 4 wird Listenmodus aktiviert |
| **Intent** | `SalesIntentLite` | `MIN_SCORE_THRESHOLD` | `3` | Mindestscore, damit ein Nicht-Discovery-Intent akzeptiert wird |
| **Intent** | `SalesIntentLite` | `DOMINANCE_DELTA` | `2` | Top-Intent muss den zweiten Intent um mindestens 2 Punkte schlagen |
| **Vector Client** | `VectorSearchClient` | `MIN_SCORE` | `0.30` | Vorfilter im PHP-Client für Chunk-Vektortreffer |
| **Vector Client** | `VectorSearchClient` | `MAX_LIMIT` | `200` | Hard Clamp für Anfragen an den Chunk-Vector-Service |
| **Tag Vector Client** | `TagVectorSearchClient` | `MIN_SCORE` | `0.72` | Vorfilter für Tag-Vektortreffer |
| **Tag Vector Client** | `TagVectorSearchClient` | `MAX_LIMIT` | `50` | Hard Clamp für Anfragen an den Tag-Vector-Service |
| **Tag Routing** | `TagRoutingService` | `DEFAULT_TOPK` | `8` | Anzahl der Tag-Treffer, die initial geprüft werden |
| **Tag Routing** | `TagRoutingService` | `MIN_BEST_SCORE` | `0.25` | Zusätzliche Gate-Schwelle nach Tag-Search; aktuell praktisch nicht limitierend |
| **Tag Routing** | `TagRoutingService` | `MAX_CANDIDATE_DOCS` | `200` | Maximalzahl an Dokumenten, die aus Tags als Kandidatenmenge entstehen dürfen |
| **Query-Aufbereitung** | `QueryCleaner` | Stopword-Filter | aktiv | Entfernt Stopwörter vor der Suche |
| **Query-Aufbereitung** | `QueryCleaner` | Zahlen bleiben erhalten | aktiv | Zahlen werden nicht entfernt |
| **Query-Aufbereitung** | `QueryCleaner` | Bindestrich/Slash-Splitting | aktiv | `-` und `/` werden als Worttrenner behandelt |
| **Query-Aufbereitung** | `QueryEnricher` | Synonym-/Pseudonym-Anreicherung | Mapping-basiert | Hängt erkannte Pseudonyme als Zusatz an die Query |
| **Auswahlmodus** | `NdjsonHybridRetriever` | `selectListChunkIds()` | dedup-basiert | Listenmodus dedupliziert Textfragmente statt hart pro Dokument zu begrenzen |
| **Auswahlmodus** | `NdjsonHybridRetriever` | `selectSalesChunkIds()` | dokumentbegrenzt | Sales-/Normalmodus begrenzt pro Dokument und nach Chunk-Abstand |
---
# 3. Effektive Laufzeitlogik der wichtigsten Parameter
## 3.1 `retrievalMaxChunks`
Effektive Formel:
```
limit = min(activeConfig.retrievalMaxChunks, HARD_MAX_CHUNKS)
```
---
# 4. Parameteränderungen und ihre typische Wirkung
| Parameter | Wenn erhöht | Wenn gesenkt | Typischer Effekt / Risiko |
|---|---|---|---|
| retrievalMaxChunks | Mehr Kontext, höhere Antworttiefe | Kompaktere Antworten, evtl. Wissensverlust | Zu hoch → Token/Noise-Risiko |
| HARD_MAX_CHUNKS | Erlaubt größere Kontexte | Strenger Kontext-Limit | Sicherheitsparameter |
| retrievalVectorTopK | Mehr Recall, breitere Kandidatenbasis | Weniger Recall, präziser aber evtl. Lücken | Zu hoch → mehr Noise |
| HARD_MAX_VECTORK | Größere Suchräume möglich | Strenger begrenzt | Sicherheitsparameter |
| VECTOR_SCORE_THRESHOLD | Höhere Präzision, weniger schwache Treffer | Mehr Treffer, aber mehr Rauschen | Zu niedrig → Bonus wirkt stärker |
| List-Mode TopK | Bessere Listenabdeckung | Listen evtl. unvollständig | Zu hoch → Noise |
| isListQuery | Häufigerer Dokumentmodus | Seltener Dokumentmodus | Fehlklassifikation möglich |
| QueryCleaner Aggressivität | Stabilere Suche, weniger Noise | Mehr Originalbegriffe | Zu aggressiv → Informationsverlust |
| DEFAULT_TOPK (Tags) | Mehr Tag-Kandidaten | Weniger Tag-Kandidaten | Zu hoch → Bonus häufiger aktiv |
| MIN_BEST_SCORE | Bonus seltener (nur starke Tag-Matches) | Bonus häufiger (auch schwache Matches) | Haupthebel gegen „Tags zu mächtig“ |
| MAX_CANDIDATE_DOCS | Mehr Dokumente erhalten Bonus | Weniger Dokumente erhalten Bonus | Zu hoch → Bonus verwässert |
| TAG_SCORE_BONUS | Tags pushen Ranking stärker | Tags pushen kaum | Zu hoch → Dominanz-Risiko |
| Dedup-Normalisierung | Weniger Dopplungen | Mehr Redundanz | Beeinflusst Vielfalt, nicht Relevanz |
| `retrievalMaxChunks` | mehr finaler Kontext | kompakterer Kontext | zu hoch: mehr Noise und Tokenverbrauch |
| `retrievalVectorTopK` | breitere Kandidatenbasis | engere Kandidatenbasis | zu hoch: mehr Streuung, zu niedrig: Recall-Verlust |
| effektiver Threshold | präzisere Treffer | mehr schwache Treffer | zu niedrig: Rauschen, zu hoch: Leertreffer |
| `LIST_BONUS` | stärkere Listenabdeckung | schmalere Listenabdeckung | zu hoch: unnötig breite Listen-Suche |
| `MAX_CHUNKS_PER_DOC` | mehr Tiefe je Dokument | mehr Diversität zwischen Dokumenten | zu hoch: Dominanz einzelner Dokumente |
| `MIN_CHUNK_DISTANCE` | weniger Nachbarschaftsduplikate | mehr lokale Ballung | zu hoch: zusammenhängende Argumente können verloren gehen |
| `RRF_K` | flachere Rangunterschiede | stärkere Dominanz der Top-Ränge | beeinflusst Fusionscharakter |
| Scoped Boost `1.2` | stärkt Routing-Dokumente | schwächt Routing-Dokumente | zu hoch: Routing dominiert globale Suche |
| Tag `DEFAULT_TOPK` | mehr Tag-Kandidaten | weniger Tag-Kandidaten | zu hoch: größere Kandidatenmengen |
| `MAX_CANDIDATE_DOCS` | breiteres Tag-Scoping | engeres Tag-Scoping | zu hoch: Scoping verliert Fokus |
| VectorClient `MIN_SCORE` | präzisere Rohhits | mehr Rohrauschen | Vorfilter vor Retriever-Fusion |
| TagVectorClient `MIN_SCORE` | strengere Tag-Erkennung | großzügigere Tag-Erkennung | sehr sensibel für Routing-Verhalten |
| `LIST_THRESHOLD` | Listenmodus seltener | Listenmodus häufiger | Fehlklassifikation möglich |
| `MIN_SCORE_THRESHOLD` (`SalesIntent`) | Discovery häufiger | Spezial-Intents häufiger | beeinflusst Objection/Pricing-Steuerung |
| `DOMINANCE_DELTA` | Intent muss klarer dominieren | Intent springt leichter um | beeinflusst Spezialisierung der Retrieval-Logik |
# 5. Praktische Lesart für Tuning
Wenn man im aktuellen Stand Retrieval-Tuning betreiben will, sind diese Hebel am wichtigsten:
## Für mehr Recall
- `retrievalVectorTopK` erhöhen
- `QueryEnrichment` gezielt erweitern
- Tag-Routing nicht zu streng machen
- effektiven Threshold bewusst überprüfen
## Für mehr Präzision
- effektiven Threshold sauber justieren
- `retrievalMaxChunks` nicht unnötig hoch setzen
- `MAX_CHUNKS_PER_DOC` niedrig halten
- Tag-Kandidatenmenge fokussiert halten
## Für bessere Listenantworten
- `LIST_THRESHOLD` und Listenheuristik prüfen
- `LIST_BONUS` gezielt feinjustieren
- dedup-basierte List-Auswahl beobachten
## Für bessere Sales-/Beratungsantworten
- `MAX_CHUNKS_PER_DOC`
- `MIN_CHUNK_DISTANCE`
- SalesIntent-Erkennung
- Scoped-Boost-Logik

View File

@@ -1,356 +0,0 @@
# TECHNISCHER AUDIT-BERICHT
## RAG-System Enterprise Architektur
**Stand:** 26.02.2026
**Audit-Basis:** vollständig neu entpackte und indexierte `rag.zip` (159 Dateien)
**Architektur-Level:** NDJSON + FAISS + Job-Orchestrierung + Tag-System + Persistenter Vector-Service
---
# 1. Executive Summary
Das System befindet sich auf einem **fortgeschrittenen Enterprise-Niveau** mit klarer Governance-Architektur, deterministischer Index-Strategie und sauberer Trennung zwischen:
- Domain
- Runtime
- Vector Layer (Python)
- Admin-Governance
- Job-Orchestrierung
Die Architektur ist:
- deterministisch
- drift-sicher
- skalierbar (>100k Chunks)
- concurrency-geschützt
- versionierungsfähig
**Enterprise-Readiness Score: 8.8 / 10**
Kein struktureller Architekturbruch erkennbar.
Optimierungspotenzial liegt in Phase B/C (Service-Entkopplung & Failure-Isolation).
---
# 2. Systemübersicht
## Komponenten
### PHP (Symfony Core)
- IngestFlow
- IngestOrchestrator
- ChunkManager
- IndexMetaManager
- VectorIndexBuilder
- TagService
- TagRoutingService
- Job-System
- LockService
- PromptBuilder
- Admin-Controller
### Python Layer
- vector_ingest.py
- vector_search.py
- vector_ingest_tags.py
- vector_search_tags.py
- vector_service.py (FastAPI persistent)
- vector_control.py
### Speicher
- index.ndjson (Single Source of Truth)
- vector.index (FAISS)
- tag_vector.index
- index_meta.json
---
# 3. Architekturmodell
## Retrieval Architektur
Hybrid:
1. Keyword-Retrieval (führend)
2. FAISS Vector Retrieval (ergänzend)
3. Score-Fusion
Tags:
- Separater Tag-Vektorindex
- Optionales Routing
- Soft-Gate Scoring
Saubere Layer-Trennung vorhanden.
---
# 4. Ingest-Pipeline Analyse
## Flow
DocumentVersionActivate
→ IngestJob
→ IngestOrchestrator
→ IngestFlow
→ ChunkManager (NDJSON streaming append)
→ VectorIndexBuilder (vollständiger Rebuild)
→ IndexMetaManager (Versionierung)
### Positiv
- deterministischer Rebuild
- kein inkrementeller Vektor-Diff (verhindert Drift)
- atomare Rename-Switches
- Guardrail gegen Embedding-Dimension-Änderung
- CHUNK_LIMIT_HARD = 120000
### Risiko
- Vollständiger FAISS-Rebuild bei jedem lokalen Ingest
→ bei 120k Chunks CPU-lastig, aber deterministisch korrekt.
Bewertung: Architektur bewusst konservativ und stabil.
---
# 5. NDJSON Architektur
## Vorteile
- streamingfähig
- kein Full-RAM JSON-Load
- skalierbar >200k Chunks
- kompatibel mit Append + Compaction
## Validierung
- document_id Compaction korrekt
- Rebuild basiert ausschließlich auf NDJSON
- Keine parallelen Index-Quellen
Single Source of Truth eingehalten.
---
# 6. Vector-Service (Persistent)
vector_service.py:
- FastAPI
- einmaliges Laden von:
- Embedding Model
- Chunk Index
- Tag Index
Endpoints:
- /search-chunks
- /search-tags
- Reload über vector_control.py
### Bewertung
Sehr sauber:
- Runtime entkoppelt
- CLI-Fallback vorhanden
- reload steuerbar
- PID-Handling robust
---
# 7. Tag-System
Vorhanden:
- knowledge_tag
- document_tag
- TagService
- TagVectorIndexBuilder
- TagVectorSearchClient
Automatische:
- Tag-Vektor-Rebuilds
- Routing-Möglichkeiten
Semantische Routing-Fehler wurden behoben (keine Association-Fehler mehr).
Bewertung: solide, nicht überengineert.
---
# 8. Job-System
Job-Typen:
- DOCUMENT_VERSION_ACTIVATE
- DOCUMENT_DELETE
- TAG_REBUILD
- GLOBAL_REINDEX
Mechanik:
- QUEUED
- RUNNING
- COMPLETED
- FAILED
exec-basierter Hintergrundstart
LockService schützt vor Parallel-Ingest.
Sehr robust umgesetzt.
---
# 9. Concurrency & Locking
LockService + Orchestrator-Gating.
Keine doppelte Ingest-Ausführung möglich.
Kein Parallel-Rebuild möglich.
Kein Index-Drift-Risiko bei Race Conditions.
---
# 10. Prompt & LLM Layer
PromptBuilder:
- SystemPromptRepository
- History Integration
- Knowledge Chunks
- URL Content
- ContextService
Sauber getrennt von Retrieval.
Keine Logik-Leakage ins Model.
---
# 11. Skalierungsanalyse
### Ziel: 120.000 Chunks
| Bereich | Bewertung |
|----------|------------|
| NDJSON | ✔ geeignet |
| FAISS RAM | ✔ bei 120k unkritisch |
| Rebuild Zeit | mittel |
| CPU Last | temporär hoch |
| Query Speed | stabil |
System wird bei 120k nicht kollabieren.
Ab 300k sollte Sharding evaluiert werden.
---
# 12. Sicherheitsbewertung
Positiv:
- Keine direkte Python-PHP Kopplung
- Keine offenen Shell-Pipes
- Atomare Dateiswitches
- Rollenmodell im Adminbereich
Offen:
- Kein Rate-Limit im Vector-Service
- Kein Auth im FastAPI Layer
Empfehlung:
lokal-only oder Reverse Proxy mit Auth.
---
# 13. Drift- & Inkonsistenzrisiken
Abgedeckt durch:
- index_meta.json
- embedding_dimension Check
- scoring_version
- Hard-Rebuild bei Strukturänderung
Sehr gut umgesetzt.
---
# 14. Identifizierte Schwachstellen
1. Vollständiger FAISS-Rebuild bei jedem Ingest
2. Keine automatische Index-Korruptionsprüfung
3. Kein Backpressure bei mehreren Ingest-Jobs
Keine strukturelle Schwäche.
---
# 15. Optimierungsempfehlungen (Priorisiert)
## Phase B
- IngestFlow in:
- GuardrailValidator
- ChunkWriteService
- VectorRebuildService
- Timeout-Absicherung beim Reload
## Phase C
- Optionaler inkrementeller Tag-Index-Rebuild
- Monitoring Hooks
- Vector-Service Auto-Restart bei Memory Spike
---
# 16. Architektur-Reifegrad
| Kategorie | Bewertung |
|------------|------------|
| Daten-Governance | sehr hoch |
| Determinismus | sehr hoch |
| Skalierbarkeit | hoch |
| Runtime-Stabilität | hoch |
| Wartbarkeit | hoch |
| Enterprise-Fähigkeit | sehr hoch |
---
# 17. Gesamtbewertung
Das System ist:
- nicht experimentell
- nicht fragil
- nicht prototypisch
- keine "KI-Spielerei"
Es ist:
✔ deterministisch
✔ governance-stabil
✔ reproduzierbar
✔ skalierbar
✔ administrierbar
Es erfüllt Enterprise-Anforderungen im KMU- bis Mid-Scale-Bereich vollständig.
---
# 18. Abschlussbewertung
Das System kann mit ruhigem Gewissen:
- produktiv betrieben
- Kunden ausgerollt
- erweitert
- eingefroren und inkrementell entwickelt
werden.
---
# OFFIZIELLER STATUS
**Phase A abgeschlossen.**
System kann eingefroren und nur noch inkrementell erweitert werden.

574
README.md
View File

@@ -1,298 +1,484 @@
# RAG-System Technische Projektdokumentation
# README.md
Version: 2.0
Stand: Februar 2026
Status: Code-validierte Referenzarchitektur
# RetrieX
> Hinweis: Das System wird fachlich als **RetrieX** bezeichnet.
> Im Repository existieren aus historischen Gründen noch einzelne Bezeichner wie `RAG`, `rag.zip` oder `RAG_SYSTEM_OVERVIEW.md`.
## Überblick
RetrieX ist ein dokumentenbasiertes Assistenzsystem auf Basis von Retrieval-Augmented Generation.
Das System beantwortet Nutzeranfragen nicht rein frei, sondern kombiniert:
- versionierte Wissensdokumente
- deterministische Ingest- und Indexierungslogik
- hybrides Retrieval mit Routing
- optionale Shopware-Live-Produktsuche
- LLM-basierte Antwortformulierung
- SSE-Streaming für die Browserausgabe
Der aktuelle Stand ist kein generischer Chatbot, sondern eine kontrollierte Wissens- und Antwortpipeline.
---
# 1. Ziel des Systems
## Technologiestack
Das System implementiert ein deterministisches Retrieval-Augmented-Generation (RAG) Framework auf Basis versionierter Dokumente.
### Backend
Leitprinzip:
- PHP 8.2
- Symfony 7.4
- Doctrine ORM / Doctrine Migrations
- Symfony Messenger
- Symfony HttpClient
- Twig
> „Wir nutzen KI nicht, um kreativ zu raten, sondern um verlässlich auf Basis Ihres Wissens zu antworten.“
### Python-Layer
Das System stellt sicher:
- SentenceTransformers
- FAISS
- FastAPI
- uvicorn
- Versionierte Dokumentverwaltung
- Deterministisches Chunking
- Streamingfähige NDJSON Source of Truth
- Vollständiger FAISS-Rebuild bei strukturellen Änderungen
- Persistenter Python Vector-Service
- Governance-stabile Ingest- und Reindex-Mechanik
### Zusätzliche Libraries
- `fivefilters/readability.php` für URL-Inhaltsauswertung
- `smalot/pdfparser` für PDF-Textgewinnung
- `league/commonmark` für Markdown-Rendering
---
# 2. Architekturüberblick
## Kernidee des Systems
## 2.1 Hauptkomponenten
RetrieX trennt klar zwischen:
Symfony (PHP)
- Dokumentverwaltung
- Versionierung
- Ingest-Orchestrierung
- Job-System
- Admin-Oberfläche
- PromptBuilder
- VectorSearchClient
1. **Primärquellen**
Dokumente, Dokumentversionen, aktive System-Prompts, Modellkonfigurationen, optionale Shopdaten
Python Layer
- Embedding-Modell (SentenceTransformers)
- FAISS Index
- Vector-Service (FastAPI + uvicorn)
- CLI-Fallback Scripts
2. **Index- und Retrieval-Ebene**
`index.ndjson`, `index_meta.json`, `index_runtime.json`, `vector.index`, `tags.ndjson`, `vector_tags.index`
Persistenz
- index.ndjson (Single Source of Truth)
- index_meta.json (Struktur-Metadaten)
- vector.index (FAISS)
- tags.ndjson (optional)
- vector_tags.index (optional)
3. **Orchestrierung**
Anfrageannahme, Kontextaufbau, URL-Analyse, Retrieval, Commerce-Erkennung, Prompt-Aufbau, Streaming
4. **Ausgabe**
Token-Streaming an das Frontend über Server-Sent Events
---
# 3. Verzeichnisstruktur (verifiziert)
## Aktuell unterstützte Dokumentformate
bin/
config/
migrations/
public/
python/
src/
templates/
var/
Der verifizierte aktuelle Loader unterstützt:
Python-Vektorlayer:
- PDF
- TXT
- MD
python/
vector_service.py
vector_control.py
vector_ingest.py
vector_search.py
vector_ingest_tags.py
vector_search_tags.py
Wichtig:
Im aktuellen Code-Stand ist **kein produktiver DOCX-Loader** in der eigentlichen Ingest-Pipeline sichtbar. Die README sollte deshalb bewusst nur die real verifizierten Formate nennen.
---
# 4. Source of Truth Konzept
## Laufzeitfluss einer Anfrage
## 4.1 index.ndjson
Der zentrale Browser-Endpunkt ist:
Streamingfähiges NDJSON-Format:
- `POST /ask-sse`
- Eine JSON-Zeile pro Chunk
- Kein JSON-Array
- Append-fähig
- Speicheroptimiert für >200k Chunks
Die Anfrage läuft im aktuellen Stand vereinfacht so:
## 4.2 index_meta.json
Beinhaltet:
- index_version
- embedding_model
- embedding_dimension
- chunk_size
- overlap
- scoring_version
- index_format
Bei strukturellen Änderungen wird ein Global Reindex erzwungen.
1. `AskSseController` nimmt die Anfrage entgegen
2. `ClientIdResolver` bestimmt eine stabile Client-ID
3. Antwort wird als **SSE-Stream** geöffnet
4. `AgentRunner` orchestriert den kompletten Ablauf
5. Optional wird URL-Inhalt aus dem Prompt extrahiert
6. `RetrieverInterface` bzw. `NdjsonHybridRetriever` holt Wissenskontext
7. Optional wird Commerce-Intent erkannt und Shopware durchsucht
8. `PromptBuilder` baut den finalen LLM-Prompt
9. `OllamaClient` streamt die Modellantwort
10. Die Antwort wird chunkweise ins Frontend gesendet
11. Der Turn wird in der Gesprächshistorie persistiert
---
# 5. Dokument-Lifecycle
## Gesprächskontext
Dokument
→ Version
→ Aktivierung
→ IngestJob (QUEUE)
→ Chunking
→ NDJSON Compaction by document_id
→ Full FAISS Rebuild
→ Status INDEXED
`ContextService` verwaltet die Konversationshistorie dateibasiert.
Wichtige Regel:
Eigenschaften:
Es existiert immer nur eine aktive Version pro Dokument.
- Nutzerhistorie wird pro Client-ID in einer Textdatei gespeichert
- abgeschlossene Turns werden append-only geschrieben
- regulärer Kontext und Full-Context sind getrennt vorgesehen
- der aktuelle SSE-Flow ruft `AgentRunner->run(..., true)` auf und nutzt damit **vollen Kontext**
Standardlogik im aktuellen Stand:
- normale Historie: letzte 20 Zeilen
- voller Kontext: letzte 500 Zeilen
---
# 6. Ingest-System
## URL-Auswertung
## 6.1 Job-Typen
Wenn im Prompt eine URL vorkommt, extrahiert `UrlAnalyzer` den Inhalt der **ersten** URL.
- DOCUMENT_UPLOAD
- DOCUMENT_VERSION_ACTIVATE
- GLOBAL_REINDEX
Aktuelle Eigenschaften:
## 6.2 Aktivierung
- Timeout-basiertes Laden
- `Readability`-basierte Extraktion des lesbaren Inhalts
- HTML wird entfernt
- Whitespace wird normalisiert
- Ausgabe wird auf maximal 5000 Zeichen begrenzt
Beim Aktivieren einer Version:
- DB-Status wird geändert
- IngestStatus → PENDING
- IngestJob wird erzeugt
- CLI-Execution via:
```
bin/console mto:agent:ingest:run <jobId>
```
LockService verhindert Parallel-Ingest.
Der extrahierte Text wird als zusätzlicher unterstützender Wissensblock in den finalen Prompt aufgenommen.
---
# 7. Retrieval
## Ingest- und Indexarchitektur
## 7.1 Architektur
### Zielbild
Hybrid im Sinne von:
RetrieX nutzt eine deterministische Ingest-Architektur mit NDJSON als operativer Wissensbasis und FAISS als Vektorindex.
- FAISS Vektor-Retrieval
- Optionales Tag-Routing (separater Tag-Index)
### Zentrale Dateien
Kein klassisches Keyword-Retrieval mehr aktiv.
- `var/knowledge/index.ndjson`
- `var/knowledge/index_meta.json`
- `var/knowledge/index_runtime.json`
- `var/knowledge/vector.index`
- `var/knowledge/vector.index.meta.json`
- `var/knowledge/tags.ndjson`
- `var/knowledge/vector_tags.index`
- `var/knowledge/vector_tags.index.meta.json`
## 7.2 Ablauf
### Bedeutung
1. Anfrage
2. VectorSearchClient → Python Service
3. FAISS Similarity Search
4. Top-K Chunks
5. PromptBuilder
6. LLM Response
#### `index.ndjson`
Operative Chunk-Basis des Systems:
- eine JSON-Zeile pro Chunk
- streamingfähig
- geeignet für append und full rewrite
- Grundlage für den Vector-Rebuild
#### `index_meta.json`
Struktur-Metadaten des Index, u. a.:
- `index_version`
- `created_at`
- `chunk_size`
- `chunk_overlap`
- `embedding_model`
- `embedding_dimension`
- `scoring_version`
- weitere Strukturfelder aus der aktiven Index-Konfiguration
#### `index_runtime.json`
Laufzeitdaten, u. a.:
- `chunk_count`
- `last_rebuild_at`
- optionale Commit-Marker wie `last_tags_rebuild_at`
---
# 8. Python Vector Service
## Dokument-Lifecycle
FastAPI Service mit uvicorn.
Der aktuelle Dokumentfluss ist technisch so aufgebaut:
Steuerung über:
1. Dokumentversion wird aktiviert oder ingestiert
2. Guardrails prüfen die Strukturverträglichkeit
3. alte Chunks des Dokuments werden entfernt
4. neue Chunks werden streamingfähig geschrieben
5. der komplette Vektorindex wird neu gebaut
6. Runtime-Stats werden atomar aktualisiert
7. Status der Version wird auf `INDEXED` gesetzt
```
bin/console mto:agent:vector:control
```
Wichtige Eigenschaft:
Mögliche Aktionen:
- --install
- --start
- --stop
- --reload
- --status
Service lädt:
- Embedding-Modell einmalig
- FAISS Index einmalig
- Hält alles persistent im RAM
CLI-Fallback bleibt verfügbar.
- Pro Dokument gibt es fachlich eine aktive Version
- Chunks sind abgeleitete Artefakte, keine Primärdaten
---
# 9. Embedding
## Ingest-Services im aktuellen Stand
Verwendetes Modell ist konfigurierbar.
### `GuardrailValidator`
Embedding-Dimension wird aus Modell bestimmt und im index_meta.json gespeichert.
Prüft über `IndexMetaManager`, ob der aktuelle Index strukturell zur aktiven Konfiguration passt.
Bei Dimensionsänderung:
Wenn sich relevante Strukturparameter geändert haben, wird lokaler Ingest blockiert.
→ Guardrail blockiert lokalen Ingest
→ Global Reindex erforderlich
### `ChunkWriteService`
Kapselt die Schreibzugriffe auf den Chunk-Bestand:
- Gesamtanzahl zählen
- Chunks nach `document_id` kompaktieren
- neue Chunks anhängen
- vollständigen Rewrite durchführen
### `VectorRebuildService`
Führt den vollständigen FAISS-Rebuild aus und aktualisiert anschließend die Runtime-Metadaten.
### `IngestFlow`
Orchestriert:
- Dokument-Ingest
- Global Reindex
- Dokumentlöschung inklusive Rebuild
---
# 10. Reindex-Strategie
## Guardrails
## 10.1 Lokaler Re-Ingest
RetrieX schützt sich gegen strukturellen Drift.
- Compaction nur für document_id
- Neue Chunks append
- Danach vollständiger FAISS-Rebuild
Lokaler Ingest darf nicht weiterlaufen, wenn sich z. B. diese Strukturparameter geändert haben:
## 10.2 Global Reindex
- Embedding-Modell
- Embedding-Dimension
- Chunk-Größe
- Chunk-Overlap
- Scoring-Version
- Index-Strukturkonfiguration
- Alle aktiven Dokumente neu ingestieren
- index.ndjson komplett neu schreiben
- index_version++
- FAISS neu bauen
Dann ist ein **Global Reindex** erforderlich.
---
# 11. Rollenmodell
## Retrieval im aktuellen Stand
- SUPER_ADMIN
- KNOWLEDGE_ADMIN
- Wissensredaktion
- Frontend-User
Der aktive Retriever ist:
Dokumente sind immutable.
Chunks sind niemals manuell editierbar.
- `App\Knowledge\Retrieval\NdjsonHybridRetriever`
Wichtig:
„Hybrid“ bedeutet hier im verifizierten Code nicht einfach „Keyword + Vektor“, sondern eine orchestrierte Kombination aus mehreren Retrieval-Schritten.
### Aktuelle Retrieval-Pipeline
1. Query Cleaning
2. Query Enrichment
3. Intent-Erkennung
4. Katalog-/Listenrouting
5. Tag-Routing auf Kandidatendokumente
6. globale Vektorsuche
7. optionale gescopte Vektorsuche auf Kandidatendokumente
8. Fusion der Treffer
9. Selektion der finalen Chunk-IDs
10. Laden der finalen Chunk-Texte aus NDJSON
### Verwendete Bausteine
- `QueryCleaner`
- `QueryEnricher`
- `IntentLite`
- `SalesIntentLite`
- `CatalogIntentLite`
- `IntentRouteResolver`
- `TagRoutingService`
- `VectorSearchClient`
- `NdjsonChunkLookup`
### Besondere Logiken
- Listenfragen werden gesondert erkannt
- Kataloganfragen können direkt einen Katalogblock statt regulärer Chunks liefern
- globale und gescopte Treffer werden gefused
- Chunk-Selektion ist dokument- und abstandsbegrenzt
---
# 12. Guardrails
## Vektor-Layer
Verhindert:
### Komponenten
- Embedding-Modell-Drift
- Chunking-Parameter-Drift
- Index-Format-Drift
- Parallele Ingest-Jobs
- Live-Änderung aktiver Ingest-Profile
- `python/vector/vector_ingest.py`
- `python/vector/vector_search.py`
- `python/vector/vector_service.py`
### Betriebsmodus
Der produktive Zugriff erfolgt primär über den HTTP-basierten Vector-Service.
Service-URL im aktuellen Default:
- `http://127.0.0.1:8090`
### Aufgaben des Vector-Service
- Embedding-Modell laden
- FAISS-Hauptindex laden
- Tag-Index laden
- Suchanfragen für Chunks beantworten
- Suchanfragen für Tags beantworten
- Reloads auf neue Indexstände ermöglichen
### Wichtige Eigenschaft
Der Python-Service hält Modell und Indizes persistent im RAM, um wiederholte Suchanfragen deutlich schneller zu bedienen.
---
# 13. Wichtige Symfony Commands (validiert)
## Prompt-Aufbau
mto:agent:ingest:run
mto:agent:vector:control
mto:agent:vector:ingest
mto:agent:vector:search
`PromptBuilder` setzt den finalen LLM-Prompt im aktuellen Stand aus diesen Blöcken zusammen:
Namespace ist durchgehend:
1. **SYSTEM**
Aktiver System-Prompt aus der Datenbank
mto:agent:*
2. **CONVERSATION CONTEXT (authoritative)**
Gesprächshistorie des Nutzers
3. **LIVE SHOP RESULTS (authoritative for products)**
Shopware-Treffer, falls Commerce aktiv ist
4. **RETRIEVED KNOWLEDGE (supporting)**
Wissens-Chunks aus dem Retriever
5. **CONTENT FROM URL (supporting)**
Optional extrahierter Webinhalt
6. **USER QUESTION**
Aktuelle Nutzerfrage
Wichtig:
Für Produktfragen behandelt das System Shopdaten explizit als **führende Quelle**.
---
# 14. Systemgrenzen
## Commerce- und Shopware-Integration
Das System ist ausgelegt für:
RetrieX besitzt im aktuellen Stand eine optionale Shopware-Store-API-Integration.
- >200.000 Chunks
- Deterministische Reproduzierbarkeit
- Enterprise-Governance
- Drift-Sicherheit
- Skalierbare Erweiterung
### Aktivierung
Die Shop-Suche wird nur genutzt, wenn `CommerceIntentLite` eine passende Anfrage erkennt.
Mögliche Zustände:
- `none`
- `product_search`
- `advisory_product_search`
### Signale für Commerce
Der Intent-Detektor reagiert u. a. auf:
- Such- und Produktbegriffe
- SKU-/Zahlenmuster
- Preisangaben
- Größenangaben
- Farbangaben
- beratende Formulierungen wie „passt“, „besser“, „empfiehl“
### Aktueller Shop-Flow
1. Commerce-Intent erkennen
2. LLM erzeugt zunächst eine kurze Shop-Suchphrase
3. `ShopSearchService` ruft `CommerceQueryParser` auf
4. `ShopwareCriteriaBuilder` baut Suchkriterien
5. `StoreApiClient` ruft `/store-api/search` auf
6. Ergebnisse werden zu `ShopProductResult` gemappt
7. Ergebnisse fließen in den Prompt ein
### Wichtige Anmerkung
Der aktuelle Code kombiniert also:
- **heuristische Intent-Erkennung**
- **LLM-unterstützte Kurzsuchphrase**
- **deterministische Nachverarbeitung im Parser**
- **Store-API-Suche**
### Aktuelle Shop-Parameter
In `services.yaml` sind u. a. konfiguriert:
- `mto.commerce.enabled`
- `mto.commerce.max_shop_results`
- `mto.commerce.shop_timeout`
- `mto.commerce.store_api_base_url`
- `mto.commerce.sales_channel_access_key`
---
# 15. Nicht Bestandteil
## Antwort-Streaming
- Kein manuelles Chunk-Editing
- Kein Keyword-Retrieval
- Kein partieller FAISS-Rebuild
- Kein In-Place Index Update
Die Browserausgabe erfolgt per **Server-Sent Events**.
Immer vollständiger Rebuild.
### Eigenschaften des aktuellen SSE-Flows
- Output Buffer werden aktiv geleert
- Cookies werden vor Streamstart weitergereicht
- Chunks werden direkt als SSE `data:`-Zeilen übertragen
- Zeilenumbrüche bleiben erhalten
- am Ende wird ein `done`-Event gesendet
Das ist im aktuellen System die bevorzugte Streaming-Variante für den Browser.
---
# 16. Zusammenfassung
## Projektstruktur
Das System implementiert eine deterministische, governance-stabile RAG-Architektur mit:
Die zentralen Verzeichnisse im aktuellen Stand sind:
- NDJSON als Streaming-Single-Source
- Vollständigem FAISS-Rebuild
- Persistenter Vector-Service-Schicht
- Versionierter Dokumentverwaltung
- Strikter Guardrail-Logik
- `src/`
- `config/`
- `templates/`
- `migrations/`
- `python/`
- `public/`
- `var/`
- `bin/`
Diese README entspricht vollständig dem aktuellen Code-Stand der rag.zip.
### Wichtige Bereiche in `src/`
- `Agent/`
- `Commerce/`
- `Context/`
- `Controller/`
- `Index/`
- `Ingest/`
- `Intent/`
- `Knowledge/`
- `Routing/`
- `Shopware/`
- `Tag/`
- `Vector/`
---
## Wichtige Commands
Verifizierte relevante Commands im aktuellen Stand:
- `mto:agent:chat`
- `mto:agent:ingest:run`
- `mto:agent:ingest:version`
- `mto:agent:vector:control`
- `mto:agent:vector:rebuild`
- `mto:agent:vector:health`
- `mto:agent:tags:export`
- `mto:agent:tags:rebuild`
- `mto:agent:tags:job:run`
- `mto:agent:tag:health`
- `mto:agent:system:rebuild`
- `mto:agent:test:shop-search`
- `mto:agent:test-vector`
- `mto:agent:user:create`
### Besonders wichtig
#### Vector-Service steuern
```bash
bin/console mto:agent:vector:control --status
bin/console mto:agent:vector:control --install --start --reload