This commit is contained in:
team 1
2026-05-10 11:06:56 +02:00
parent b2bd9f89e0
commit fad07ce734
3 changed files with 112 additions and 6 deletions

View File

@@ -1166,6 +1166,9 @@ parameters:
- brauerei - brauerei
- brauereien - brauereien
- brauwasser - brauwasser
- schwimmbad
- schwimmbecken
- pool
- 0,02 - 0,02
stopword_cleanup: stopword_cleanup:
origin: genre_native origin: genre_native
@@ -1259,6 +1262,9 @@ parameters:
- brauerei - brauerei
- brauereien - brauereien
- brauwasser - brauwasser
- schwimmbad
- schwimmbecken
- pool
- redox - redox
- orp - orp
- ph - ph

View File

@@ -0,0 +1,66 @@
# RetrieX Patch p83 - Shop Query Token Correction Preservation
## Ziel
Direkte Shop-Suchanfragen sollen Tippfehler-Korrekturen aus `commerce.search_token_corrections` auch dann behalten, wenn die finale Agent-Shopquery vorher durch LLM-Optimierung oder positive Token-Filterung stark reduziert wurde.
Konkreter Regression-Guard:
```text
ich würde gern chlor im schwinnbad messen
```
soll nicht mehr auf die zu breite Shopquery
```text
chlor
```
reduziert werden, sondern den korrigierten Anwendungskontext behalten:
```text
chlor schwimmbad
```
## Änderungen
- `src/Agent/AgentRunner.php`
- injiziert `CommerceQueryParserConfig`, um die bestehende zentrale `search_token_corrections`-Liste wiederzuverwenden.
- wendet diese Korrekturen vor der finalen Shopquery-Stopword-/Positive-Token-Filterung an.
- korrigiert auch den Prompt-Kontext in `preserveCurrentInputShopQueryTerms()`, damit ein Tippfehler wie `schwinnbad` als konfigurierter Preservation-Term `schwimmbad` erkannt wird.
- `config/retriex/genre.yaml`
- ergänzt `schwimmbad`, `schwimmbecken` und `pool` als erhaltenswerte Shop-Kontexttokens.
- ergänzt dieselben Begriffe in der kleinen positiven Shopquery-Allowlist, damit die finale Query nicht wieder auf `chlor` reduziert wird.
## Nicht geändert
- Kein Retrieval-/Scoring-/Ranking-Fix.
- Keine Shop-Matching-Änderung.
- Keine neue harte Tippfehlerliste im PHP-Core.
- Die bestehende `commerce.search_token_corrections`-Liste bleibt Source of Truth für Korrekturen wie `schwinnbad -> schwimmbad`.
## Erwartete Wirkung
```text
ich würde gern chlor im schwinnbad messen
=> chlor schwimmbad
```
```text
ich würde gern chlor im schwimmbad messen
=> chlor schwimmbad
```
Breite Chlor-Suchen ohne Pool-/Schwimmbad-Kontext bleiben unverändert möglich.
## Empfohlene Prüfungen
```bash
php -l src/Agent/AgentRunner.php
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
```

View File

@@ -9,6 +9,7 @@ use App\Commerce\ProductRoleResolver;
use App\Commerce\SearchRepairService; use App\Commerce\SearchRepairService;
use App\Commerce\ShopSearchService; use App\Commerce\ShopSearchService;
use App\Config\AgentRunnerConfig; use App\Config\AgentRunnerConfig;
use App\Config\CommerceQueryParserConfig;
use App\Config\LanguageCleanupConfig; use App\Config\LanguageCleanupConfig;
use App\Context\ContextService; use App\Context\ContextService;
use App\Context\UrlAnalyzer; use App\Context\UrlAnalyzer;
@@ -33,6 +34,7 @@ final readonly class AgentRunner
private SearchRepairService $searchRepairService, private SearchRepairService $searchRepairService,
private ReferenceAnchorExtractor $referenceAnchorExtractor, private ReferenceAnchorExtractor $referenceAnchorExtractor,
private CommerceIntentLite $commerceIntentLite, private CommerceIntentLite $commerceIntentLite,
private CommerceQueryParserConfig $commerceQueryParserConfig,
private OllamaClient $ollamaClient, private OllamaClient $ollamaClient,
private LoggerInterface $agentLogger, private LoggerInterface $agentLogger,
private AgentRunnerConfig $agentRunnerConfig, private AgentRunnerConfig $agentRunnerConfig,
@@ -1651,6 +1653,7 @@ final readonly class AgentRunner
: $this->preserveCurrentInputShopQueryTerms($prompt, $shopSearchQuery); : $this->preserveCurrentInputShopQueryTerms($prompt, $shopSearchQuery);
$query = $this->cleanupDirectProductAttributeShopQuery($prompt, $query); $query = $this->cleanupDirectProductAttributeShopQuery($prompt, $query);
$query = $this->applyConfiguredShopSearchTokenCorrections($query);
return $this->cleanupShopQueryStopwords($query); return $this->cleanupShopQueryStopwords($query);
} }
@@ -1988,14 +1991,17 @@ final readonly class AgentRunner
$shopSearchQuery = trim($shopSearchQuery); $shopSearchQuery = trim($shopSearchQuery);
if ($shopSearchQuery === '' || !$this->agentRunnerConfig->isShopQueryCurrentInputPreservationEnabled()) { if ($shopSearchQuery === '' || !$this->agentRunnerConfig->isShopQueryCurrentInputPreservationEnabled()) {
return $shopSearchQuery; return $this->applyConfiguredShopSearchTokenCorrections($shopSearchQuery);
} }
$promptTokens = array_fill_keys($this->tokenizeShopQueryCandidate($prompt), true); $correctedPrompt = $this->applyConfiguredShopSearchTokenCorrections($prompt);
$queryTokens = array_fill_keys($this->tokenizeShopQueryCandidate($shopSearchQuery), true); $correctedShopSearchQuery = $this->applyConfiguredShopSearchTokenCorrections($shopSearchQuery);
$promptTokens = array_fill_keys($this->tokenizeShopQueryCandidate($correctedPrompt), true);
$queryTokens = array_fill_keys($this->tokenizeShopQueryCandidate($correctedShopSearchQuery), true);
if ($promptTokens === [] || $queryTokens === []) { if ($promptTokens === [] || $queryTokens === []) {
return $shopSearchQuery; return $correctedShopSearchQuery;
} }
$appendTokens = []; $appendTokens = [];
@@ -2023,10 +2029,38 @@ final readonly class AgentRunner
} }
if ($appendTokens === []) { if ($appendTokens === []) {
return $shopSearchQuery; return $correctedShopSearchQuery;
} }
return trim($shopSearchQuery . ' ' . implode(' ', array_values($appendTokens))); return trim($correctedShopSearchQuery . ' ' . implode(' ', array_values($appendTokens)));
}
private function applyConfiguredShopSearchTokenCorrections(string $text): string
{
$text = trim($text);
if ($text === '') {
return '';
}
foreach ($this->commerceQueryParserConfig->getSearchTokenCorrections() as $from => $to) {
$from = trim((string) $from);
$to = trim((string) $to);
if ($from === '' || $to === '') {
continue;
}
$text = preg_replace(
'/\b' . preg_quote($from, '/') . '\b/u',
$to,
$text
) ?? $text;
}
$text = preg_replace('/\s+/u', ' ', $text) ?? $text;
return trim($text);
} }
/** /**