p74
This commit is contained in:
@@ -243,14 +243,20 @@ parameters:
|
|||||||
- label: Preis anzeigen
|
- label: Preis anzeigen
|
||||||
prompt: Zeige mir die Preise zu {shop_query}.
|
prompt: Zeige mir die Preise zu {shop_query}.
|
||||||
action_type: price_details
|
action_type: price_details
|
||||||
|
hide_when_answer_matches_any:
|
||||||
|
- '/\bkeine?\s+(?:passende[nrs]?\s+)?(?:produktbezeichnung|shop-?treffer|treffer|produkte?)\b/iu'
|
||||||
- label: Nur Zubehör anzeigen
|
- label: Nur Zubehör anzeigen
|
||||||
prompt: Suche im Shop nach {shop_query} und zeige daraus nur Zubehör.
|
prompt: Suche im Shop nach {shop_query} und zeige daraus nur Zubehör.
|
||||||
action_type: role_filter
|
action_type: role_filter
|
||||||
target_role: accessory_or_consumable
|
target_role: accessory_or_consumable
|
||||||
|
hide_when_answer_matches_any:
|
||||||
|
- '/\bkeine?\s+(?:passende[nrs]?\s+)?(?:produktbezeichnung|shop-?treffer|treffer|produkte?)\b/iu'
|
||||||
- label: Nur Geräte anzeigen
|
- label: Nur Geräte anzeigen
|
||||||
prompt: Suche im Shop nach {shop_query} und zeige daraus nur Geräte.
|
prompt: Suche im Shop nach {shop_query} und zeige daraus nur Geräte.
|
||||||
action_type: role_filter
|
action_type: role_filter
|
||||||
target_role: main_device
|
target_role: main_device
|
||||||
|
hide_when_answer_matches_any:
|
||||||
|
- '/\bkeine?\s+(?:passende[nrs]?\s+)?(?:produktbezeichnung|shop-?treffer|treffer|produkte?)\b/iu'
|
||||||
knowledge:
|
knowledge:
|
||||||
- label: Technische Details anzeigen
|
- label: Technische Details anzeigen
|
||||||
prompt: Zeige nur zusätzliche technische Details zu {answer_anchor}.
|
prompt: Zeige nur zusätzliche technische Details zu {answer_anchor}.
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# RetrieX Patch p74 - Accessory Identity Shop Result Guard
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
|
||||||
|
p73 lädt bei generischen Zubehör-Suchanfragen zusätzliche Shopdaten nach, zum Beispiel für:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Suche im Shop nach Testomat Resthärte Indikator
|
||||||
|
```
|
||||||
|
|
||||||
|
Im Test wurden danach zwar Shop-Treffer gefunden, die Antwort blieb aber zu defensiv und sagte sinngemäß, dass keine passende Produktbezeichnung gefunden wurde. Gleichzeitig wurde weiterhin die Folgeaktion `Preis anzeigen` angeboten. Das ist für den Nutzer verwirrend: Wenn das System keine passende sichtbare Produktauswahl nennt, darf keine Preisaktion erscheinen; wenn Shop-Treffer mit passender Zubehör-Identität vorhanden sind, sollen diese bevorzugt als Produktliste genutzt werden.
|
||||||
|
|
||||||
|
## Änderung
|
||||||
|
|
||||||
|
- `AgentRunnerConfig::getDirectShopResultProductIdentityTerms()` ergänzt eine generische Produktidentitäts-Terminologie für direkte Shop-Ergebnisguards.
|
||||||
|
- Diese Terminologie bleibt vollständig YAML-/Genre-basiert:
|
||||||
|
- bestehende Direct-Attribute-Produkttypen
|
||||||
|
- `product_roles.accessory_product_terms.terms`
|
||||||
|
- `product_roles.requested_accessory_code_terms.terms`
|
||||||
|
- `AgentRunner::extractRequestedDirectProductTerms()` nutzt diese erweiterte Identitäts-Terminologie.
|
||||||
|
- Direkte Zubehör-/Produkt-Suchen wie `... Indikator` können dadurch Shop-Treffer mit passender Primary Identity bevorzugen und deterministisch als Shop-Ergebnisliste ausgeben.
|
||||||
|
- Gemischte Anfragen nach Geräten **und** Zubehör werden bewusst nicht auf Zubehör verengt.
|
||||||
|
- Follow-up-Actions der Shop-Ergebnisgruppe werden per YAML ausgeblendet, wenn die Antwort selbst einen No-Match-Zustand formuliert, zum Beispiel `keine Produktbezeichnung`, `keine Treffer`, `keine Produkte`.
|
||||||
|
|
||||||
|
## Warum generisch?
|
||||||
|
|
||||||
|
Der Patch enthält keine Testomat-, Resthärte- oder Indikator-300-Sonderlogik. Er erweitert nur die bestehende direkte Produktidentitätsprüfung um vorhandene Genre-/YAML-Begriffe für Zubehör und Zubehör-Codes.
|
||||||
|
|
||||||
|
## Erwartete Wirkung
|
||||||
|
|
||||||
|
Für:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Suche im Shop nach Testomat Resthärte Indikator
|
||||||
|
```
|
||||||
|
|
||||||
|
soll die Antwort nicht mehr primär Geräte empfehlen oder eine No-Match-Aussage mit Preisaktion erzeugen. Wenn passende Indikator-/Reagenz-Shoptreffer vorhanden sind, sollen diese direkt mit Shopfeldern wie Produktnummer, Preis, Verfügbarkeit und URL gelistet werden.
|
||||||
|
|
||||||
|
## Checks
|
||||||
|
|
||||||
|
Lokal geprüft:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php -l src/Agent/AgentRunner.php
|
||||||
|
php -l src/Config/AgentRunnerConfig.php
|
||||||
|
python3 YAML parse für config/retriex/chat-messages.yaml, agent.yaml, genre.yaml
|
||||||
|
python3 Smoke: `Indikator` wird als direkte Produktidentität erkannt; No-Match-Action-Pattern matched
|
||||||
|
```
|
||||||
|
|
||||||
|
In der Zielumgebung zusätzlich ausführen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bin/console mto:agent:config:validate
|
||||||
|
bin/console mto:agent:regression:test
|
||||||
|
bin/console mto:agent:config:audit-source --details
|
||||||
|
```
|
||||||
@@ -3321,6 +3321,10 @@ final readonly class AgentRunner
|
|||||||
return $shopResults;
|
return $shopResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->isMixedDeviceAndAccessoryProductRequest($prompt, $shopSearchQuery)) {
|
||||||
|
return $shopResults;
|
||||||
|
}
|
||||||
|
|
||||||
$primaryMatches = [];
|
$primaryMatches = [];
|
||||||
$corpusMatches = [];
|
$corpusMatches = [];
|
||||||
|
|
||||||
@@ -3379,6 +3383,10 @@ final readonly class AgentRunner
|
|||||||
return $emptyResult;
|
return $emptyResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->isMixedDeviceAndAccessoryProductRequest($prompt, $shopSearchQuery)) {
|
||||||
|
return $emptyResult;
|
||||||
|
}
|
||||||
|
|
||||||
$repairQuery = $this->buildDirectProductPrimaryIdentityRepairQuery(
|
$repairQuery = $this->buildDirectProductPrimaryIdentityRepairQuery(
|
||||||
shopSearchQuery: $shopSearchQuery,
|
shopSearchQuery: $shopSearchQuery,
|
||||||
requestedTerms: $requestedTerms
|
requestedTerms: $requestedTerms
|
||||||
@@ -4062,7 +4070,7 @@ final readonly class AgentRunner
|
|||||||
}
|
}
|
||||||
|
|
||||||
$terms = [];
|
$terms = [];
|
||||||
foreach ($this->agentRunnerConfig->getShopQueryProductAttributeCleanupProductTypeTerms() as $term) {
|
foreach ($this->agentRunnerConfig->getDirectShopResultProductIdentityTerms() as $term) {
|
||||||
if ($this->containsAllShopQueryTokens($combined, $term)) {
|
if ($this->containsAllShopQueryTokens($combined, $term)) {
|
||||||
$terms[] = $term;
|
$terms[] = $term;
|
||||||
}
|
}
|
||||||
@@ -4071,6 +4079,17 @@ final readonly class AgentRunner
|
|||||||
return array_values(array_unique($terms));
|
return array_values(array_unique($terms));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function isMixedDeviceAndAccessoryProductRequest(string $prompt, string $shopSearchQuery): bool
|
||||||
|
{
|
||||||
|
$combined = mb_strtolower($this->normalizeOneLine($prompt . ' ' . $shopSearchQuery), 'UTF-8');
|
||||||
|
if ($combined === '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->containsAnyConfiguredTerm($combined, $this->agentRunnerConfig->getNoLlmMainDeviceRequestRoleKeywords())
|
||||||
|
&& $this->containsAnyConfiguredTerm($combined, $this->agentRunnerConfig->getNoLlmAccessoryProductRoleKeywords());
|
||||||
|
}
|
||||||
|
|
||||||
private function containsAllShopQueryTokens(string $text, string $term): bool
|
private function containsAllShopQueryTokens(string $text, string $term): bool
|
||||||
{
|
{
|
||||||
$tokens = array_fill_keys($this->tokenizeShopQueryCandidate($text), true);
|
$tokens = array_fill_keys($this->tokenizeShopQueryCandidate($text), true);
|
||||||
@@ -4216,6 +4235,7 @@ final readonly class AgentRunner
|
|||||||
|| !$shopSearchAttempted
|
|| !$shopSearchAttempted
|
||||||
|| $shopSearchHadSystemFailure
|
|| $shopSearchHadSystemFailure
|
||||||
|| $this->extractRequestedDirectProductTerms($prompt, $shopSearchQuery) === []
|
|| $this->extractRequestedDirectProductTerms($prompt, $shopSearchQuery) === []
|
||||||
|
|| $this->isMixedDeviceAndAccessoryProductRequest($prompt, $shopSearchQuery)
|
||||||
) {
|
) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1256,6 +1256,18 @@ final class AgentRunnerConfig
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getDirectShopResultProductIdentityTerms(): array
|
||||||
|
{
|
||||||
|
return array_values(array_unique(array_merge(
|
||||||
|
$this->getShopQueryProductAttributeCleanupProductTypeTerms(),
|
||||||
|
$this->genreStringList('product_roles.accessory_product_terms.terms'),
|
||||||
|
$this->genreStringList('product_roles.requested_accessory_code_terms.terms')
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user