From a4903104b5e77276688fb5e2b60fecdb82512c08 Mon Sep 17 00:00:00 2001 From: team 1 Date: Sun, 3 May 2026 10:40:47 +0200 Subject: [PATCH] patch 20j --- ...ONE_SHOP_OPTIMIZER_CONTEXT_GUARD_README.md | 75 +++++++++++++++++++ src/Agent/AgentRunner.php | 42 +++++++++++ 2 files changed, 117 insertions(+) create mode 100644 RETRIEX_PATCH_20J_STANDALONE_SHOP_OPTIMIZER_CONTEXT_GUARD_README.md diff --git a/RETRIEX_PATCH_20J_STANDALONE_SHOP_OPTIMIZER_CONTEXT_GUARD_README.md b/RETRIEX_PATCH_20J_STANDALONE_SHOP_OPTIMIZER_CONTEXT_GUARD_README.md new file mode 100644 index 0000000..4b67718 --- /dev/null +++ b/RETRIEX_PATCH_20J_STANDALONE_SHOP_OPTIMIZER_CONTEXT_GUARD_README.md @@ -0,0 +1,75 @@ +# RetrieX Patch p20j - Standalone Shop Optimizer Context Guard + +## Ziel +Verhindert, dass die LLM-gestützte Shop-Query-Optimierung bei eigenständigen neuen Shop-Suchen alten oder nicht im aktuellen Prompt enthaltenen Kontext in die Suchquery übernimmt. + +## Reproduzierter Fehler +Nach vorherigen Testomat-808-/Indikator-Kontexten wurde bei der neuen Anfrage: + +```text +zeige mir Anschlusskabel für pH/Redox +``` + +als gesendete Shop-Suchquery fälschlich erzeugt: + +```text +testomat 808 +``` + +Dadurch lieferte der Shop Testomat-808- und Indikator-Produkte statt Anschlusskabeln für pH/Redox. + +## Ursache +Der Shop-Router selbst war nicht mehr das Problem: Shop wurde korrekt angefragt. Der Fehler entstand im Ausgang der LLM-Shop-Query-Optimierung. Bei einem eigenständigen neuen Prompt ohne zulässigen History-Kontext durfte der Optimizer eine Query erzeugen, die keine Token-Überschneidung mit dem aktuellen Prompt hatte und sogar eine Modellnummer enthielt, die im aktuellen Prompt nicht vorkam. + +## Änderung +Geändert wurde nur: + +- `src/Agent/AgentRunner.php` + +Neu abgesichert: + +- Bei eigenständigen Shop-Suchen ohne History-Kontext wird die optimierte Query validiert. +- Der Optimizer darf Suchbegriffe entfernen oder verdichten. +- Er darf aber keine Modell-/Artikelnummern hinzufügen, die nicht im aktuellen Prompt stehen. +- Wenn die optimierte Query keinerlei Token-Überschneidung mit dem aktuellen Prompt hat, wird sie als Kontextsubstitution verworfen. +- In diesem Fall fällt RetrieX auf den aktuellen Prompt zurück; der vorhandene CommerceQueryParser bereinigt ihn anschließend regulär. + +## Erwartung + +```text +zeige mir Anschlusskabel für pH/Redox +``` + +soll nicht mehr zu `testomat 808` optimiert werden. Erwartbar ist eine Shop-Suchquery im Bereich: + +```text +anschlusskabel ph redox +``` + +oder ein sauber aus dem aktuellen Prompt abgeleiteter äquivalenter Suchtext. + +Bestehende Follow-ups bleiben erlaubt: + +```text +die tabelle mit preisen +``` + +nutzt weiterhin History-Kontext, weil es explizit referenziell ist. + +## Prüfungen lokal + +- `php -l src/Agent/AgentRunner.php` OK + +Symfony-Console-Checks konnten in der ChatGPT-Umgebung nicht vollständig ausgeführt werden, weil die Laufzeit-/Composer-Dependencies nicht installiert sind. + +## Nach dem Einspielen prüfen + +```bash +bin/console cache:clear +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 +``` + +Falls OPcache/PHP-FPM aktiv ist, PHP-FPM bzw. Container neu laden. diff --git a/src/Agent/AgentRunner.php b/src/Agent/AgentRunner.php index 9eeb9de..f8b3fbe 100644 --- a/src/Agent/AgentRunner.php +++ b/src/Agent/AgentRunner.php @@ -1469,6 +1469,15 @@ final readonly class AgentRunner return $optimizedShopQuery; } + if ($this->standaloneOptimizedShopQueryIntroducesUnsupportedContext($prompt, $optimizedShopQuery)) { + $this->agentLogger->info('Ignored optimized shop query because it introduced unsupported standalone context', [ + 'prompt' => $prompt, + 'optimizedShopQuery' => $optimizedShopQuery, + ]); + + return $prompt; + } + if ($this->extractFirstTestomatModelAnchor($prompt) === '') { return $optimizedShopQuery; } @@ -1489,6 +1498,39 @@ final readonly class AgentRunner return $prompt; } + private function standaloneOptimizedShopQueryIntroducesUnsupportedContext( + string $prompt, + string $optimizedShopQuery + ): bool { + $promptTokens = array_fill_keys($this->tokenizeShopQueryCandidate($prompt), true); + $optimizedTokens = $this->tokenizeShopQueryCandidate($optimizedShopQuery); + + if ($optimizedTokens === [] || $promptTokens === []) { + return false; + } + + $overlap = 0; + + foreach ($optimizedTokens as $token) { + if (isset($promptTokens[$token])) { + $overlap++; + continue; + } + + // A standalone query optimizer may remove words, but it must not add + // model numbers or article-like numbers that are absent from the + // current user input. Otherwise old context can leak into new shop + // searches, for example "Anschlusskabel pH/Redox" -> "testomat 808". + if (preg_match('/\d/u', $token) === 1) { + return true; + } + } + + // If the optimized query has no token overlap with the current standalone + // input, it is not a safe optimization but a context substitution. + return $overlap === 0 && !$this->isMetaOnlyShopQuery($prompt); + } + private function resolveShopSearchQuery( string $prompt, string $optimizedShopQuery,