2026-05-11 20:10:55 +02:00
2026-02-11 14:15:08 +01:00
2026-05-11 20:10:55 +02:00
2026-05-07 20:04:02 +02:00
2026-05-11 20:10:55 +02:00
2026-05-11 14:50:56 +02:00
2026-04-24 10:43:20 +02:00
2026-05-11 20:10:55 +02:00
2026-05-11 15:39:00 +02:00
2026-04-24 20:54:38 +02:00
2026-02-18 11:41:58 +01:00
2026-05-07 14:13:53 +02:00
2026-05-11 19:16:51 +02:00
2026-04-20 21:46:42 +02:00
2026-04-14 18:56:20 +02:00
2026-05-11 19:05:52 +02:00
p28
2026-05-04 08:38:53 +02:00
2026-05-11 19:16:51 +02:00
2026-02-26 21:28:00 +01:00
2026-05-11 19:05:52 +02:00
p64
2026-05-09 11:24:08 +02:00
2026-05-11 19:05:52 +02:00
2026-05-11 19:05:52 +02:00
2026-02-25 09:23:02 +01:00

README.md

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. Version 1.6.0 kombiniert den stabilisierten RAG-/Commerce-Kern mit einer produktionsnäheren Chat-/Admin-Architektur.

Das System beantwortet Nutzeranfragen nicht frei, sondern kombiniert:

  • versionierte Wissensdokumente
  • deterministische Ingest- und Indexierungslogik
  • 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-, Antwort- und Betriebs-Pipeline.


Technologiestack

Backend

  • PHP 8.2
  • Symfony 7.4
  • Doctrine ORM / Doctrine Migrations
  • Symfony Messenger
  • Symfony HttpClient
  • Twig

Python-Layer

  • SentenceTransformers
  • FAISS
  • FastAPI
  • uvicorn

Zusätzliche Libraries

  • fivefilters/readability.php für URL-Inhaltsauswertung
  • smalot/pdfparser für PDF-Textgewinnung
  • league/commonmark für Markdown-Rendering

Kernidee des Systems

RetrieX trennt klar zwischen:

  1. Primärquellen
    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, Shopquery-Reparatur, Prompt-Aufbau, Streaming

  4. Ausgabe
    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


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:

  • PDF
  • TXT
  • MD

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 Browser-Anfrage

Der aktuelle Chat nutzt bevorzugt den Job-basierten SSE-Flow:

  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.

Zusätzlich existiert weiterhin POST /ask-sse als direkter Streaming-Endpunkt.


Gesprächskontext

ContextService verwaltet die Konversationshistorie dateibasiert.

Eigenschaften:

  • 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.

Aktuelle Standardwerte aus config/retriex/runtime.yaml:

  • 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.

Aktuelle Eigenschaften:

  • Timeout-basiertes Laden
  • Readability-basierte Extraktion des lesbaren Inhalts
  • HTML wird entfernt
  • Whitespace wird normalisiert
  • Ausgabe wird auf maximal 5000 Zeichen begrenzt

Der extrahierte Text wird als zusätzlicher unterstützender Wissensblock in den finalen Prompt aufgenommen.


Ingest- und Indexarchitektur

Zielbild

RetrieX nutzt eine deterministische Ingest-Architektur mit NDJSON als operativer Wissensbasis und FAISS als Vektorindex.

Zentrale Dateien

  • 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

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

Dokument-Lifecycle

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.

Wichtige Eigenschaft:

  • Pro Dokument gibt es fachlich eine aktive Version.
  • Chunks sind abgeleitete Artefakte, keine Primärdaten.

Ingest-Services

GuardrailValidator

Prüft über IndexMetaManager, ob der aktuelle Index strukturell zur aktiven Konfiguration passt. Wenn relevante Strukturparameter geändert wurden, wird lokaler Ingest blockiert.

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

Retrieval

Der aktive Retriever ist:

  • App\Knowledge\Retrieval\NdjsonHybridRetriever

„Hybrid“ bedeutet im aktuellen Code 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.
  • Exakte Auswahlfragen, Tabellen-/Indikatorfragen und Grenzwertfragen haben eigene Präzisionspfade.

Vektor-Layer

Komponenten

  • 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

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 aus diesen Blöcken zusammen:

  1. SYSTEM
    Aktiver System-Prompt aus der Datenbank

  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 URL-Inhalt

  6. USER QUESTION
    Aktuelle Nutzerfrage

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 eine optionale Shopware-Store-API-Integration.

Aktivierung

Die Shop-Suche wird nur genutzt, wenn CommerceIntentLite eine passende Anfrage erkennt.

Mögliche Zustände:

  • none
  • product_search
  • advisory_product_search

Aktueller Shop-Flow

  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 Präzisionsregeln in v1.6.0

  • 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.

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

Projektstruktur

Die zentralen Verzeichnisse im aktuellen Stand sind:

  • src/
  • config/
  • templates/
  • migrations/
  • python/
  • public/
  • var/
  • bin/

Wichtige Bereiche in src/

  • Agent/
  • Commerce/
  • Config/
  • Context/
  • Controller/Chat/
  • Controller/Admin/
  • Index/
  • Ingest/
  • Intent/
  • Knowledge/
  • Routing/
  • Security/
  • 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: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

Vector-Service steuern

bin/console mto:agent:vector:control --status
bin/console mto:agent:vector:control --install --start --reload

Empfohlene Standardchecks nach Patches

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

Die YAML-only-Migration gilt als abgeschlossen, solange diese Checks grün bleiben:

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

Entwickler müssen DEVELOPER_POLICIES.md beachten.

Kernregeln:

  • 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.
Description
No description provided
Readme 26 MiB
Languages
PHP 79%
Twig 13%
HTML 2.8%
Python 2.4%
JavaScript 1.8%
Other 1%