optimize technical truth

This commit is contained in:
team 1
2026-04-28 12:31:13 +02:00
parent fd8516c7f8
commit 0ee8799b9d
8 changed files with 523 additions and 21 deletions

View File

@@ -1427,6 +1427,7 @@ final readonly class AgentRunner
if ($hasShopResults) {
return $this->buildNoLlmShopFallbackAnswer(
prompt: $prompt,
hasKnowledge: $hasKnowledge,
shopResults: $shopResults
);
@@ -1453,15 +1454,22 @@ final readonly class AgentRunner
/**
* @param ShopProductResult[] $shopResults
*/
private function buildNoLlmShopFallbackAnswer(bool $hasKnowledge, array $shopResults): string
private function buildNoLlmShopFallbackAnswer(string $prompt, bool $hasKnowledge, array $shopResults): string
{
$intro = $hasKnowledge
? $this->agentRunnerConfig->getNoLlmFallbackShopWithKnowledgeMessage()
: $this->agentRunnerConfig->getNoLlmFallbackShopOnlyMessage();
$requestedProductRole = $this->resolveNoLlmRequestedProductRole($prompt);
$lines = [$intro, ''];
$lines = [$intro];
foreach ($this->buildNoLlmShopProductLines($shopResults) as $line) {
if ($this->hasOnlyNoLlmAccessoryResultsForMainDeviceRequest($requestedProductRole, $shopResults)) {
$lines[] = $this->agentRunnerConfig->getNoLlmFallbackAccessoryOnlyForMainDeviceMessage();
}
$lines[] = '';
foreach ($this->buildNoLlmShopProductLines($shopResults, $requestedProductRole) as $line) {
$lines[] = $line;
}
@@ -1499,7 +1507,7 @@ final readonly class AgentRunner
* @param ShopProductResult[] $shopResults
* @return string[]
*/
private function buildNoLlmShopProductLines(array $shopResults): array
private function buildNoLlmShopProductLines(array $shopResults, string $requestedProductRole): array
{
$maxResults = max(1, $this->agentRunnerConfig->getNoLlmFallbackMaxShopResults());
$lines = [];
@@ -1510,7 +1518,7 @@ final readonly class AgentRunner
continue;
}
$lines[] = $this->formatNoLlmShopProductLine($product, $index);
$lines[] = $this->formatNoLlmShopProductLine($product, $index, $requestedProductRole);
$index++;
if (count($lines) >= $maxResults) {
@@ -1525,9 +1533,10 @@ final readonly class AgentRunner
return $lines;
}
private function formatNoLlmShopProductLine(ShopProductResult $product, int $index): string
private function formatNoLlmShopProductLine(ShopProductResult $product, int $index, string $requestedProductRole): string
{
$parts = [];
$productRole = $this->resolveNoLlmShopProductRole($product);
$name = $this->normalizeOneLine($product->name);
$parts[] = $name !== '' ? $name : 'Unbenanntes Shop-Produkt';
@@ -1552,9 +1561,86 @@ final readonly class AgentRunner
$parts[] = 'URL: ' . $this->normalizeOneLine($product->url);
}
if ($requestedProductRole === 'main_device_or_system' && $productRole === 'accessory_or_consumable') {
$parts[] = 'Hinweis: Zubehör/Verbrauchsartikel; nicht als Messanlage/Gerät bestätigt';
}
return sprintf('%d. %s', $index, implode(' | ', $parts));
}
/**
* @param ShopProductResult[] $shopResults
*/
private function hasOnlyNoLlmAccessoryResultsForMainDeviceRequest(string $requestedProductRole, array $shopResults): bool
{
if ($requestedProductRole !== 'main_device_or_system') {
return false;
}
$seenProducts = 0;
foreach ($shopResults as $product) {
if (!$product instanceof ShopProductResult) {
continue;
}
$seenProducts++;
if ($this->resolveNoLlmShopProductRole($product) !== 'accessory_or_consumable') {
return false;
}
}
return $seenProducts > 0;
}
private function resolveNoLlmRequestedProductRole(string $prompt): string
{
$normalized = mb_strtolower($prompt, 'UTF-8');
if ($this->containsAnyConfiguredTerm($normalized, $this->agentRunnerConfig->getNoLlmAccessoryProductRoleKeywords())) {
return 'accessory_or_consumable';
}
if ($this->containsAnyConfiguredTerm($normalized, $this->agentRunnerConfig->getNoLlmMainDeviceRequestRoleKeywords())) {
return 'main_device_or_system';
}
return 'unknown';
}
private function resolveNoLlmShopProductRole(ShopProductResult $product): string
{
$normalized = mb_strtolower($this->normalizeOneLine(implode(' ', [
$product->name,
(string) $product->description,
(string) $product->customFields,
implode(' ', $product->highlights),
])), 'UTF-8');
if ($this->containsAnyConfiguredTerm($normalized, $this->agentRunnerConfig->getNoLlmAccessoryProductRoleKeywords())) {
return 'accessory_or_consumable';
}
return 'unknown';
}
/**
* @param string[] $terms
*/
private function containsAnyConfiguredTerm(string $haystack, array $terms): bool
{
foreach ($terms as $term) {
$term = mb_strtolower(trim($term), 'UTF-8');
if ($term !== '' && str_contains($haystack, $term)) {
return true;
}
}
return false;
}
/**
* @param string[] $sources