# RetrieX Patch 20 - LLM-assisted Input Normalization before Routing ## Ziel Patch 20 ersetzt den p19-Symptom-Fix fuer einzelne Preis-Tippfehler (`kpstet`, `ksotet`) durch eine generische, LLM-gestuetzte Eingabe-Normalisierung vor der Intent-/Commerce-/Retrieval-Erkennung. Der Ausloeser war der Flow: 1. `Was ist der niedrigste Grenzwert fuer die Wasserhaerte, welcher mit einem Testomaten ueberwacht werden kann?` 2. `mit welchem indikator wird der wert gemessen` 3. `was kpstet der indikator` p19 konnte diesen konkreten Tippfehler per YAML-Liste auffangen, skaliert aber nicht. p20 normalisiert die Nutzereingabe vorher, z. B. `was kpstet der indikator` -> `was kostet der indikator`, ohne Produktkontext fachlich aufzufuellen. ## Architektur Der Normalisierungsschritt sitzt in `AgentRunner::run()` direkt nach `analyze_request` und vor: - URL-/Quellenpruefung - CommerceIntentLite-Erkennung - Knowledge-Retrieval-Prompt-Bau - Shop-Query-Optimierung - finalem PromptBuilder-Aufruf Das LLM ist ueber den bereits vorhandenen `final class OllamaClient` angebunden und nutzt analog zur Shop-Query-Optimierung: ```php foreach ($this->ollamaClient->stream($normalizationPrompt) as $token) { ... } ``` Die Originalfrage bleibt erhalten und wird weiterhin in die Conversation History geschrieben. Die normalisierte Frage wird nur als effektive Eingabe fuer Routing, Intent, Retrieval, Shop-Optimierung und Antwortgenerierung genutzt. ## Guardrails Die Normalisierung darf nur offensichtliche Tippfehler korrigieren. Sie darf nicht fachlich interpretieren. Konkrete Schutzmechanismen: - YAML-konfigurierbarer Normalizer-Prompt in `config/retriex/agent.yaml` - keine fachliche Kontextauflösung im Normalizer - keine Produktnamen, Modellnummern, Messwerte, Artikelnummern oder Einsatzbereiche hinzufuegen - vage Referenzen wie `der indikator` bleiben vage und werden erst spaeter ueber bestehende Kontextlogik aufgeloest - URL-/Code-aehnliche Eingaben werden uebersprungen - maximale Eingabe-/Ausgabelaenge - maximale Laengenvergroesserung - maximale Token-Zunahme - neue Zahlen in der normalisierten Eingabe werden verworfen - bei Fehlern, leerer Ausgabe oder unsicherem Ergebnis faellt RetrieX auf die Originalfrage zurueck ## Geaenderte Dateien - `src/Agent/AgentRunner.php` - `src/Config/AgentRunnerConfig.php` - `src/Config/RetriexEffectiveConfigProvider.php` - `config/retriex/agent.yaml` - `config/retriex/intent.yaml` - `config/retriex/commerce.yaml` ## Entfernt aus p19-Symptomlisten Die expliziten Tippfehler `kpstet` und `ksotet` wurden entfernt aus: - `intent.yaml` strong/non-product/price/explicit-commerce Listen - `commerce.yaml` stopword- und correction-Listen Damit ist p20 nicht mehr auf diese konkreten Fehlerlisten angewiesen. ## Erwartetes Verhalten Eingabe: ```text was kpstet der indikator ``` Interne Normalisierung: ```text was kostet der indikator ``` Danach sollte der bestehende Commerce-/Shop-Follow-up-Flow greifen: - Commerce Intent wird erkannt - Shop-Suche wird angefragt - referenzieller Kontext `Indikatortyp 300` kann durch bestehende Shop-Query-Context-Anchor-Logik ergaenzt werden ## Lokal ausgefuehrte Pruefungen Im Container ausgefuehrt: ```bash php -l src/Agent/AgentRunner.php php -l src/Config/AgentRunnerConfig.php php -l src/Config/RetriexEffectiveConfigProvider.php python3 - <<'PY' import yaml from pathlib import Path for rel in ['config/retriex/agent.yaml','config/retriex/intent.yaml','config/retriex/commerce.yaml']: with (Path('.') / rel).open() as f: yaml.safe_load(f) PY php -r '$patterns=["/^(?:normalisiert|korrigiert|corrected|normalized)\\s*:\\s*/iu","/https?:\\/\\//iu","/\\bwww\\./iu","/```/u"]; foreach($patterns as $p){ if(@preg_match($p, "was kpstet der indikator")===false){ exit(1); } } echo "OK\n";' grep -R "kpstet\|ksotet" -n config src || true ``` Ergebnis: - PHP-Syntax: OK - YAML-Parse: OK - Regex-Smoke-Test: OK - `kpstet` / `ksotet`: nicht mehr in `config` oder `src` ## Nicht lokal ausfuehrbar Die Symfony-/Composer-basierten Pflichtchecks konnten im Container nicht ausgefuehrt werden, weil im ZIP keine installierten Vendor-Dependencies enthalten sind. Bitte nach dem Einspielen ausfuehren: ```bash bin/console mto:agent:config:validate bin/console mto:agent:regression:test bin/console mto:agent:config:audit-source --details bin/console mto:agent:config:audit-patterns --details ``` ## Empfohlene Regressionstests 1. Stabiler v1.5.1-Flow: ```text Was ist der niedrigste Grenzwert fuer die Wasserhaerte, welcher mit einem Testomaten ueberwacht werden kann? mit welchem indikator wird der wert gemessen was kostet der indikator ``` 2. Tippfehler-Flow: ```text Was ist der niedrigste Grenzwert fuer die Wasserhaerte, welcher mit einem Testomaten ueberwacht werden kann? mit welchem indikator wird der wert gemessen was kpstet der indikator ``` Erwartung fuer beide Preisfragen: - Shop-Suche wird angefragt - Shop-Treffer werden genutzt - keine Rueckkehr in RAG-only mit Testomat-2000-Indikatoren 3. Guardrail-Test: ```text was kpstet der indikator 300 ``` Erwartung: - Normalisierung darf `300` erhalten - keine neue Modellnummer / Artikelnummer hinzufuegen 4. URL-Skip-Test: ```text pruefe https://example.com/test?x=kpstet ``` Erwartung: - Normalisierung wird uebersprungen - URL bleibt unveraendert