update .md

This commit is contained in:
team 1
2026-05-11 19:05:52 +02:00
parent f098a1a244
commit f79062c336
5 changed files with 1042 additions and 857 deletions

314
README.md
View File

@@ -1,24 +1,27 @@
# README.md
# RetrieX
# RetrieX v1.6.0
> 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.
RetrieX ist ein dokumentenbasiertes Assistenzsystem auf Basis von Retrieval-Augmented Generation. Version 1.6.0 kombiniert den stabilisierten RAG-/Commerce-Kern mit einer produktionsnäheren Chat-/Admin-Architektur.
Das System beantwortet Nutzeranfragen nicht rein frei, sondern kombiniert:
Das System beantwortet Nutzeranfragen nicht frei, sondern kombiniert:
- versionierte Wissensdokumente
- deterministische Ingest- und Indexierungslogik
- hybrides Retrieval mit Routing
- hybrides Retrieval mit Tag-Routing
- optionale Shopware-Live-Produktsuche
- YAML-gestützte Intent-, Language-, Vocabulary-, Prompt- und Commerce-Regeln
- LLM-basierte Antwortformulierung
- SSE-Streaming für die Browserausgabe
- getrennte Chat- und Adminbereiche mit Rollenmodell
- Admin-Benutzerverwaltung und Access-Denied-/Fehlerseiten
Der aktuelle Stand ist kein generischer Chatbot, sondern eine kontrollierte Wissens- und Antwortpipeline.
Der aktuelle Stand ist kein generischer Chatbot, sondern eine kontrollierte Wissens-, Antwort- und Betriebs-Pipeline.
---
@@ -53,20 +56,89 @@ Der aktuelle Stand ist kein generischer Chatbot, sondern eine kontrollierte Wiss
RetrieX trennt klar zwischen:
1. **Primärquellen**
Dokumente, Dokumentversionen, aktive System-Prompts, Modellkonfigurationen, optionale Shopdaten
Dokumente, Dokumentversionen, aktive System-Prompts, Modellkonfigurationen, optionale Shopware-Daten
2. **Index- und Retrieval-Ebene**
`index.ndjson`, `index_meta.json`, `index_runtime.json`, `vector.index`, `tags.ndjson`, `vector_tags.index`
3. **Orchestrierung**
Anfrageannahme, Kontextaufbau, URL-Analyse, Retrieval, Commerce-Erkennung, Prompt-Aufbau, Streaming
Anfrageannahme, Kontextaufbau, URL-Analyse, Retrieval, Commerce-Erkennung, Shopquery-Reparatur, Prompt-Aufbau, Streaming
4. **Ausgabe**
Token-Streaming an das Frontend über Server-Sent Events
Chat-Frontend, SSE-Stream, Statuskarten, Shopkarten, Quellenchips und kontextsensitive Folgeaktionen
5. **Betrieb und Governance**
Chat-/Admin-Security, Rollenmatrix, Userverwaltung, Fehlerseiten, Konfigurationsvalidierung, Source-Audits und Regressionstests
---
## Aktuell unterstützte Dokumentformate
## Version 1.6.0 wesentliche Neuerungen gegenüber 1.5.x
### Chat- und Admin-Architektur
- Der Chat läuft über `App\Controller\Chat\ChatController`.
- `/` und `/chat` rendern `templates/chat/index.html.twig`.
- Die frühere statische `public/index.html` ist entfernt.
- Admin-Routen bleiben unter `/admin...` getrennt.
- Chat-Login und Chat-Logout laufen über `/chat/login` und `/chat/logout`.
### Rollen und Security
RetrieX nutzt weiterhin eine gemeinsame User-Entity, trennt aber die Bereichsrechte:
| Rolle | Zweck |
| --- | --- |
| `ROLE_CHAT_USER` | Zugriff auf Chat, Ask/SSE, History und Frontend-Messages |
| `ROLE_ADMIN_AREA` | Zugriff auf Adminbasis, Dashboard, Guides und Jobübersicht |
| `ROLE_EDITOR` | Dokumente, Versionen, Tags und Dokument-Ingest |
| `ROLE_KNOWLEDGE_ADMIN` | Modell-/Retrieval-Konfiguration lesen/testen und Ingest-Profile ansehen |
| `ROLE_SUPER_ADMIN` | Userverwaltung, Systembereiche, Logs, Reset/Delete, Global Reindex und kritische Umschaltungen |
Die Hierarchie ist in `config/packages/security.yaml` definiert. `ROLE_USER` ist nur technische Basisrolle und schaltet keinen Bereich allein frei.
### Admin-Benutzerverwaltung
`ROLE_SUPER_ADMIN` kann Benutzer im Adminbereich verwalten:
- Benutzerliste
- Benutzer anlegen
- Benutzer bearbeiten
- Rollen zuweisen
- Passwort setzen/zurücksetzen
- Benutzer aktivieren/deaktivieren
- Schutz gegen Selbst-Aussperren
- Schutz des letzten aktiven Super-Admins
Deaktivierte Benutzer werden beim Login über `ActiveUserChecker` blockiert und bestehende Sessions über `ActiveUserSessionSubscriber` beendet.
### Fehler- und Access-Denied-UX
Version 1.6.0 enthält konsistente Fehlerseiten für:
- 403 / fehlende Rolle
- 404 / Route nicht gefunden
- 500 / Serverfehler
- generische Fehlerfälle
Der `AccessDeniedHandler` zeigt bei falschem Bereich die benötigte Rolle, den aktuellen Benutzer und sinnvolle Rücksprung- bzw. Logout-Optionen.
### Commerce- und Follow-up-Präzision
Die Commerce-Logik wurde weiter gehärtet:
- Shopqueries entfernen stärker Sprach-, Satz- und Relationsrauschen.
- Tippfehlerkorrekturen aus `commerce.yaml` bleiben in der finalen Query erhalten.
- Direkte Produktnamen wie `chlor select sensor` bleiben erhalten.
- Modellkürzel wie `Testomat LAB CL` werden nicht mehr auf `testomat` reduziert.
- Exakte Zubehör-/Indikatorcodes wie `300` werden nicht mit Varianten wie `300 S` vermischt.
- Mehrprodukt-Follow-ups werden in Einzelqueries aufgeteilt.
- Preis-Folgeaktionen nutzen sichtbare Produktidentitäten inklusive Produktnummern.
- Schwache referenzielle Shopfragen wie „suche im Shop nach der Information“ können auf den letzten konkreten Produktanker aus der History zurückfallen.
- Wiederholende Folgeaktions-Loops werden unterdrückt, wenn die materialisierte Query identisch mit der aktuellen Query ist.
---
## Unterstützte Dokumentformate
Der verifizierte aktuelle Loader unterstützt:
@@ -74,30 +146,28 @@ Der verifizierte aktuelle Loader unterstützt:
- TXT
- MD
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.
Wichtig: Im aktuellen Code-Stand ist kein produktiver DOCX-Loader in der eigentlichen Ingest-Pipeline sichtbar. Dokumentation und Tests sollten deshalb bewusst nur die real verifizierten Formate nennen.
---
## Laufzeitfluss einer Anfrage
## Laufzeitfluss einer Browser-Anfrage
Der zentrale Browser-Endpunkt ist:
Der aktuelle Chat nutzt bevorzugt den Job-basierten SSE-Flow:
- `POST /ask-sse`
1. Frontend sendet `POST /ask-jobs` mit Prompt und optionalem Kontextflag.
2. `AskSseController` legt einen Antwort-Job an.
3. Frontend öffnet `GET /ask-sse/{jobId}`.
4. `AgentRunner` orchestriert die Anfrage.
5. Optional wird URL-Inhalt aus der Nutzerfrage extrahiert.
6. `NdjsonHybridRetriever` holt Wissenskontext.
7. Optional erkennt `CommerceIntentLite` Commerce-/Shop-Intent.
8. Shopquery wird optimiert, bereinigt, ggf. repariert und über Shopware gesucht.
9. `PromptBuilder` baut den finalen LLM-Prompt.
10. `OllamaClient` streamt die Modellantwort.
11. Chunks werden als SSE-Events ins Frontend gesendet.
12. Der Turn wird in der Gesprächshistorie persistiert.
Die Anfrage läuft im aktuellen Stand vereinfacht so:
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
Zusätzlich existiert weiterhin `POST /ask-sse` als direkter Streaming-Endpunkt.
---
@@ -107,21 +177,22 @@ Die Anfrage läuft im aktuellen Stand vereinfacht so:
Eigenschaften:
- 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**
- Historie wird pro stabiler Client-ID gespeichert.
- abgeschlossene Turns werden append-only geschrieben.
- regulärer Kontext und Full-Context sind getrennt vorgesehen.
- Browser-Anfragen nutzen standardmäßig budgetierten bzw. regulären Kontext.
- Full-Context muss explizit über `fullContext` angefordert werden.
Standardlogik im aktuellen Stand:
Aktuelle Standardwerte aus `config/retriex/runtime.yaml`:
- normale Historie: letzte 20 Zeilen
- voller Kontext: letzte 500 Zeilen
- regulärer sichtbarer Kontext: letzte 25 Zeilen
- Full-Context: letzte 500 Zeilen
---
## URL-Auswertung
Wenn im Prompt eine URL vorkommt, extrahiert `UrlAnalyzer` den Inhalt der **ersten** URL.
Wenn im Prompt eine URL vorkommt, extrahiert `UrlAnalyzer` den Inhalt der ersten URL.
Aktuelle Eigenschaften:
@@ -152,9 +223,7 @@ RetrieX nutzt eine deterministische Ingest-Architektur mit NDJSON als operativer
- `var/knowledge/vector_tags.index`
- `var/knowledge/vector_tags.index.meta.json`
### Bedeutung
#### `index.ndjson`
### `index.ndjson`
Operative Chunk-Basis des Systems:
@@ -163,7 +232,7 @@ Operative Chunk-Basis des Systems:
- geeignet für append und full rewrite
- Grundlage für den Vector-Rebuild
#### `index_meta.json`
### `index_meta.json`
Struktur-Metadaten des Index, u. a.:
@@ -176,7 +245,7 @@ Struktur-Metadaten des Index, u. a.:
- `scoring_version`
- weitere Strukturfelder aus der aktiven Index-Konfiguration
#### `index_runtime.json`
### `index_runtime.json`
Laufzeitdaten, u. a.:
@@ -190,28 +259,26 @@ Laufzeitdaten, u. a.:
Der aktuelle Dokumentfluss ist technisch so aufgebaut:
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
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.
Wichtige Eigenschaft:
- Pro Dokument gibt es fachlich eine aktive Version
- Chunks sind abgeleitete Artefakte, keine Primärdaten
- Pro Dokument gibt es fachlich eine aktive Version.
- Chunks sind abgeleitete Artefakte, keine Primärdaten.
---
## Ingest-Services im aktuellen Stand
## Ingest-Services
### `GuardrailValidator`
Prüft über `IndexMetaManager`, ob der aktuelle Index strukturell zur aktiven Konfiguration passt.
Wenn sich relevante Strukturparameter geändert haben, wird lokaler Ingest blockiert.
Prüft über `IndexMetaManager`, ob der aktuelle Index strukturell zur aktiven Konfiguration passt. Wenn relevante Strukturparameter geändert wurden, wird lokaler Ingest blockiert.
### `ChunkWriteService`
@@ -236,31 +303,13 @@ Orchestriert:
---
## Guardrails
RetrieX schützt sich gegen strukturellen Drift.
Lokaler Ingest darf nicht weiterlaufen, wenn sich z. B. diese Strukturparameter geändert haben:
- Embedding-Modell
- Embedding-Dimension
- Chunk-Größe
- Chunk-Overlap
- Scoring-Version
- Index-Strukturkonfiguration
Dann ist ein **Global Reindex** erforderlich.
---
## Retrieval im aktuellen Stand
## Retrieval
Der aktive Retriever ist:
- `App\Knowledge\Retrieval\NdjsonHybridRetriever`
Wichtig:
„Hybrid“ bedeutet hier im verifizierten Code nicht einfach „Keyword + Vektor“, sondern eine orchestrierte Kombination aus mehreren Retrieval-Schritten.
„Hybrid“ bedeutet im aktuellen Code eine orchestrierte Kombination aus mehreren Retrieval-Schritten.
### Aktuelle Retrieval-Pipeline
@@ -289,10 +338,11 @@ Wichtig:
### 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
- 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.
- Exakte Auswahlfragen, Tabellen-/Indikatorfragen und Grenzwertfragen haben eigene Präzisionspfade.
---
@@ -321,15 +371,13 @@ Service-URL im aktuellen Default:
- 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.
---
## Prompt-Aufbau
`PromptBuilder` setzt den finalen LLM-Prompt im aktuellen Stand aus diesen Blöcken zusammen:
`PromptBuilder` setzt den finalen LLM-Prompt aus diesen Blöcken zusammen:
1. **SYSTEM**
Aktiver System-Prompt aus der Datenbank
@@ -344,19 +392,18 @@ Der Python-Service hält Modell und Indizes persistent im RAM, um wiederholte Su
Wissens-Chunks aus dem Retriever
5. **CONTENT FROM URL (supporting)**
Optional extrahierter Webinhalt
Optional extrahierter URL-Inhalt
6. **USER QUESTION**
Aktuelle Nutzerfrage
Wichtig:
Für Produktfragen behandelt das System Shopdaten explizit als **führende Quelle**.
Für Produktfragen behandelt das System Shopdaten explizit als führende Produktquelle. Fachliche Eignungsaussagen bleiben dennoch an RAG-/Kontextbelege und Prompt-Guardrails gebunden.
---
## Commerce- und Shopware-Integration
RetrieX besitzt im aktuellen Stand eine optionale Shopware-Store-API-Integration.
RetrieX besitzt eine optionale Shopware-Store-API-Integration.
### Aktivierung
@@ -368,62 +415,46 @@ Mögliche Zustände:
- `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
1. Commerce-Intent erkennen.
2. LLM erzeugt zunächst eine kurze Shop-Suchphrase.
3. `CommerceQueryParser` normalisiert und bereinigt die Query.
4. Follow-up-/History-/RAG-Anker können die Query ergänzen.
5. `SearchRepairService` kann fehlende oder zu enge Shopqueries reparieren.
6. `ShopwareCriteriaBuilder` baut Suchkriterien.
7. `StoreApiClient` ruft `/store-api/search` auf.
8. Ergebnisse werden zu `ShopProductResult` gemappt.
9. Ergebnisidentität und Rollenlogik filtern zu breite Treffer.
10. Ergebnisse fließen in Prompt, Statuskarten und Folgeaktionen ein.
### Wichtige Anmerkung
### Wichtige Präzisionsregeln in v1.6.0
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`
- Exakte Artikelnummern und Produktnummern werden bevorzugt.
- Exakte Zubehörcodes bleiben exakt.
- Produktlisten-Follow-ups werden in Einzelqueries aufgeteilt.
- Produktidentität wird über Name, URL, Artikelnummer und sichtbare Antwortprodukte abgesichert.
- Schwache Shop-Meta-Fragen dürfen auf konkrete History-Anker zurückfallen.
- Shop-only Antworten bleiben vorsichtig, wenn keine belastbare technische Eignung belegt ist.
---
## Antwort-Streaming
Die Browserausgabe erfolgt per **Server-Sent Events**.
Die Browserausgabe erfolgt per Server-Sent Events.
### Eigenschaften des aktuellen SSE-Flows
- Job-basierter Stream über `/ask-jobs` und `/ask-sse/{jobId}`
- direkter Legacy-Stream über `POST /ask-sse`
- Reconnect-/Replay-Unterstützung über Event-IDs
- Stale-Job-Erkennung
- 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.
---
## Projektstruktur
@@ -443,13 +474,16 @@ Die zentralen Verzeichnisse im aktuellen Stand sind:
- `Agent/`
- `Commerce/`
- `Config/`
- `Context/`
- `Controller/`
- `Controller/Chat/`
- `Controller/Admin/`
- `Index/`
- `Ingest/`
- `Intent/`
- `Knowledge/`
- `Routing/`
- `Security/`
- `Shopware/`
- `Tag/`
- `Vector/`
@@ -473,41 +507,51 @@ Verifizierte relevante Commands im aktuellen Stand:
- `mto:agent:system:rebuild`
- `mto:agent:config:validate`
- `mto:agent:config:audit-source`
- `mto:agent:config:audit-patterns`
- `mto:agent:config:dump-effective`
- `mto:agent:regression:test`
- `mto:agent:test:shop-search`
- `mto:agent:test-vector`
- `mto:agent:user:create`
### Besonders wichtig
#### Vector-Service steuern
### Vector-Service steuern
```bash
bin/console mto:agent:vector:control --status
bin/console mto:agent:vector:control --install --start --reload
```
### Empfohlene Standardchecks nach Patches
```bash
php bin/console cache:clear
php bin/console lint:yaml config/packages/security.yaml config/retriex
php bin/console lint:twig templates
php bin/console mto:agent:config:validate
php bin/console mto:agent:regression:test
php bin/console mto:agent:config:audit-source --details
php bin/console mto:agent:config:audit-patterns --details
```
---
## Developer Policies / Governance
The YAML-only migration is treated as completed after Patch 11.0a, as long as these checks stay green:
Die YAML-only-Migration gilt als abgeschlossen, solange diese Checks grün bleiben:
```bash
php bin/console mto:agent:config:validate
php bin/console mto:agent:config:audit-source --details
php bin/console mto:agent:config:audit-patterns --details
php bin/console mto:agent:regression:test
```
From now on, developers must follow `DEVELOPER_POLICIES.md`.
Entwickler müssen `DEVELOPER_POLICIES.md` beachten.
Core rules:
Kernregeln:
- YAML under `config/retriex/` is the source of truth for configurable behavior.
- No new PHP-only semantic defaults, token lists, prompt texts, matching rules or business fallbacks.
- New configurable behavior must be added through YAML and wired explicitly.
- Regression-sensitive flows from the 1.4.2/1.5.0 baseline must remain protected.
- Strict YAML validation is deferred and must remain disabled by default when introduced later.
- YAML unter `config/retriex/` ist die Source of Truth für konfigurierbares Verhalten.
- Keine neuen PHP-only-semantischen Defaults, Tokenlisten, Prompttexte, Matching-Regeln oder Business-Fallbacks.
- Neues konfigurierbares Verhalten muss über YAML ergänzt und explizit verdrahtet werden.
- Regression-sensitive Flows aus den stabilen 1.4.x/1.5.x/1.6.0-Baselines müssen geschützt bleiben.
- Core-Pattern- und Source-Audits sollen Domainlisten im PHP-Core verhindern.