2026-05-06 18:57:11 +02:00
2026-02-11 14:15:08 +01:00
2026-05-06 18:25:56 +02:00
2026-05-06 14:41:37 +02:00
2026-05-06 18:57:11 +02:00
2026-04-24 10:43:20 +02:00
2026-05-06 18:57:11 +02:00
2026-04-20 16:36:28 +02:00
2026-04-24 20:54:38 +02:00
2026-02-18 11:41:58 +01:00
2026-02-25 09:23:02 +01:00
2026-05-01 19:29:01 +02:00
2026-04-20 21:46:42 +02:00
2026-04-14 18:56:20 +02:00
2026-05-05 09:33:35 +02:00
p28
2026-05-04 08:38:53 +02:00
2026-04-15 10:49:21 +02:00
2026-02-26 21:28:00 +01:00
2026-04-15 09:44:14 +02:00
2026-04-15 09:42:36 +02:00
2026-05-01 11:08:02 +02:00
2026-02-25 09:23:02 +01:00

README.md

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.


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 Shopdaten

  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

  4. Ausgabe
    Token-Streaming an das Frontend über Server-Sent Events


Aktuell 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. Die README sollte deshalb bewusst nur die real verifizierten Formate nennen.


Laufzeitfluss einer Anfrage

Der zentrale Browser-Endpunkt ist:

  • POST /ask-sse

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

Gesprächskontext

ContextService verwaltet die Konversationshistorie dateibasiert.

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

Standardlogik im aktuellen Stand:

  • normale Historie: letzte 20 Zeilen
  • voller Kontext: 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

Bedeutung

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 im aktuellen Stand

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.

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

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

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.

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

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

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:

  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 Webinhalt

  6. USER QUESTION
    Aktuelle Nutzerfrage

Wichtig:
Für Produktfragen behandelt das System Shopdaten explizit als führende Quelle.


Commerce- und Shopware-Integration

RetrieX besitzt im aktuellen Stand 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

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

Antwort-Streaming

Die Browserausgabe erfolgt per Server-Sent Events.

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.


Projektstruktur

Die zentralen Verzeichnisse im aktuellen Stand sind:

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

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:config:validate
  • mto:agent:config:audit-source
  • 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

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


Developer Policies / Governance

The YAML-only migration is treated as completed after Patch 11.0a, as long as these checks stay green:

php bin/console mto:agent:config:validate
php bin/console mto:agent:config:audit-source --details
php bin/console mto:agent:regression:test

From now on, developers must follow DEVELOPER_POLICIES.md.

Core rules:

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