diff --git a/COMMAND_REF.md b/COMMAND_REF.md index cf2817c..da4d93c 100644 --- a/COMMAND_REF.md +++ b/COMMAND_REF.md @@ -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 +``` + +**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 +bin/console mto:agent:ingest:version ``` +**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 [--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 +bin/console mto:agent:ingest:run --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 +``` -**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 ``` --- -# 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 +``` ---- - -# 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 ``` -### 3️⃣ Vector-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) \ No newline at end of file +## 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 **` `** +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` diff --git a/INSTALL.md b/INSTALL.md index fbad37e..fc19a91 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -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 -cd -``` +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 +``` + +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 +php bin/console mto:agent:ingest:version +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 \ No newline at end of file +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 ` 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 diff --git a/MATRIX_PARAMS.md b/MATRIX_PARAMS.md index f1aee9f..a48e970 100644 --- a/MATRIX_PARAMS.md +++ b/MATRIX_PARAMS.md @@ -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 | \ No newline at end of file +| `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 \ No newline at end of file diff --git a/PHASE_A_AUDIT.md b/PHASE_A_AUDIT.md deleted file mode 100644 index 93f6277..0000000 --- a/PHASE_A_AUDIT.md +++ /dev/null @@ -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. diff --git a/README.md b/README.md index a585f03..7832376 100644 --- a/README.md +++ b/README.md @@ -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 -``` - -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. \ No newline at end of file +### 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 \ No newline at end of file