patch 18
This commit is contained in:
@@ -123,6 +123,11 @@ parameters:
|
|||||||
- bestände
|
- bestände
|
||||||
- bestaende
|
- bestaende
|
||||||
- lieferprogramm
|
- lieferprogramm
|
||||||
|
aggregate_answer_evidence_patterns:
|
||||||
|
- '/\b(?:anzahl|gesamtzahl|stückzahl|stueckzahl|count)\b.{0,80}\b\d+\b/u'
|
||||||
|
- '/\b\d+\s+(?:[a-z0-9+\-]+\s+){0,3}(?:produkte|artikel|geräte|geraete|messgeräte|messgeraete)\b/u'
|
||||||
|
- '/\b(?:insgesamt|gesamt|total)\b.{0,80}\b\d+\b/u'
|
||||||
|
- '/\b(?:sortiment|portfolio|lieferprogramm)\b.{0,120}\b(?:umfasst|enthält|enthaelt|besteht\s+aus|beinhaltet)\b.{0,80}\b\d+\b/u'
|
||||||
synonyms:
|
synonyms:
|
||||||
salinität:
|
salinität:
|
||||||
- salinität
|
- salinität
|
||||||
|
|||||||
@@ -404,6 +404,11 @@ parameters:
|
|||||||
- '- State that no reliable information was found in the provided RAG knowledge, URL content, or shop results.'
|
- '- State that no reliable information was found in the provided RAG knowledge, URL content, or shop results.'
|
||||||
- '- Do not answer with "gibt es nicht". Use narrow wording such as "Ich finde dazu keine belastbaren Daten in den vorliegenden Quellen."'
|
- '- Do not answer with "gibt es nicht". Use narrow wording such as "Ich finde dazu keine belastbaren Daten in den vorliegenden Quellen."'
|
||||||
- '- Ask one focused clarification question if a parameter, product family, accessory type, or application context would make the search answerable.'
|
- '- Ask one focused clarification question if a parameter, product family, accessory type, or application context would make the search answerable.'
|
||||||
|
aggregatfrage_keine_belastbare_zaehlinformation:
|
||||||
|
- '- The user asks for a count or aggregate number, but the retrieved sources do not contain an explicit count/aggregate answer.'
|
||||||
|
- '- Do not present nearby product-family or portfolio mentions as proof of a concrete count.'
|
||||||
|
- '- Say narrowly: "Ich habe passende Quellen geprüft, finde darin aber keine belastbare Zählinformation für die angefragte Anzahl."'
|
||||||
|
- '- If helpful, explain that individual product mentions are not the same as a maintained aggregate count.'
|
||||||
semantische_rag_treffer_kein_direkter_fachbeleg:
|
semantische_rag_treffer_kein_direkter_fachbeleg:
|
||||||
- '- Retrieved RAG records are semantic nearest-neighbor hits only; they are not a direct factual match for the essential user term or configured synonym.'
|
- '- Retrieved RAG records are semantic nearest-neighbor hits only; they are not a direct factual match for the essential user term or configured synonym.'
|
||||||
- '- Do not present these RAG hits as fachlich belegt. Say narrowly that the RAG knowledge does not contain a direct Fachbeleg for the requested term.'
|
- '- Do not present these RAG hits as fachlich belegt. Say narrowly that the RAG knowledge does not contain a direct Fachbeleg for the requested term.'
|
||||||
|
|||||||
@@ -354,7 +354,8 @@ final readonly class AgentRunner
|
|||||||
isCommerceIntent: true,
|
isCommerceIntent: true,
|
||||||
shopSearchAttempted: $shopSearchAttempted,
|
shopSearchAttempted: $shopSearchAttempted,
|
||||||
hasShopResults: $shopResults !== [],
|
hasShopResults: $shopResults !== [],
|
||||||
shopSearchHadSystemFailure: $primaryShopSearchHadSystemFailure
|
shopSearchHadSystemFailure: $primaryShopSearchHadSystemFailure,
|
||||||
|
knowledgeEvidenceState: $knowledgeEvidenceState
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'meta'
|
'meta'
|
||||||
@@ -419,7 +420,8 @@ final readonly class AgentRunner
|
|||||||
isCommerceIntent: $this->isCommerceIntent($commerceIntent),
|
isCommerceIntent: $this->isCommerceIntent($commerceIntent),
|
||||||
shopSearchAttempted: $shopSearchAttempted,
|
shopSearchAttempted: $shopSearchAttempted,
|
||||||
hasShopResults: $shopResults !== [],
|
hasShopResults: $shopResults !== [],
|
||||||
shopSearchHadSystemFailure: $primaryShopSearchHadSystemFailure
|
shopSearchHadSystemFailure: $primaryShopSearchHadSystemFailure,
|
||||||
|
knowledgeEvidenceState: $knowledgeEvidenceState
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'meta'
|
'meta'
|
||||||
@@ -458,7 +460,8 @@ final readonly class AgentRunner
|
|||||||
isCommerceIntent: $this->isCommerceIntent($commerceIntent),
|
isCommerceIntent: $this->isCommerceIntent($commerceIntent),
|
||||||
shopSearchAttempted: $shopSearchAttempted,
|
shopSearchAttempted: $shopSearchAttempted,
|
||||||
hasShopResults: $shopResults !== [],
|
hasShopResults: $shopResults !== [],
|
||||||
shopSearchHadSystemFailure: $primaryShopSearchHadSystemFailure
|
shopSearchHadSystemFailure: $primaryShopSearchHadSystemFailure,
|
||||||
|
knowledgeEvidenceState: $knowledgeEvidenceState
|
||||||
),
|
),
|
||||||
completed: true
|
completed: true
|
||||||
),
|
),
|
||||||
@@ -1652,12 +1655,20 @@ final readonly class AgentRunner
|
|||||||
}
|
}
|
||||||
|
|
||||||
$haystack = $this->normalizeRagEvidenceText(implode("\n\n", array_map('strval', $knowledgeChunks)));
|
$haystack = $this->normalizeRagEvidenceText(implode("\n\n", array_map('strval', $knowledgeChunks)));
|
||||||
|
$isAggregateQuery = $this->isAggregateRagEvidenceQuery($prompt);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$this->isAggregateRagEvidenceQuery($prompt)
|
$isAggregateQuery
|
||||||
|
&& !$this->containsAnyRagEvidencePattern($haystack, $this->agentRunnerConfig->getRagEvidenceAggregateAnswerEvidencePatterns())
|
||||||
|
) {
|
||||||
|
return 'aggregate_missing';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$isAggregateQuery
|
||||||
&& !$this->containsAnyRagEvidenceTerm($haystack, $this->agentRunnerConfig->getRagEvidenceAggregateEvidenceTerms())
|
&& !$this->containsAnyRagEvidenceTerm($haystack, $this->agentRunnerConfig->getRagEvidenceAggregateEvidenceTerms())
|
||||||
) {
|
) {
|
||||||
return 'weak';
|
return 'aggregate_missing';
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($needles as $needleGroup) {
|
foreach ($needles as $needleGroup) {
|
||||||
@@ -1680,6 +1691,7 @@ final readonly class AgentRunner
|
|||||||
{
|
{
|
||||||
return match ($knowledgeEvidenceState) {
|
return match ($knowledgeEvidenceState) {
|
||||||
'direct' => 'fachlich belegt',
|
'direct' => 'fachlich belegt',
|
||||||
|
'aggregate_missing' => 'geprüfte Quellen, keine passende Zählinformation',
|
||||||
'weak' => 'RAG-Näherungstreffer, kein direkter Fachbeleg',
|
'weak' => 'RAG-Näherungstreffer, kein direkter Fachbeleg',
|
||||||
default => 'noch keine belastbaren Treffer',
|
default => 'noch keine belastbaren Treffer',
|
||||||
};
|
};
|
||||||
@@ -1689,6 +1701,7 @@ final readonly class AgentRunner
|
|||||||
{
|
{
|
||||||
return match ($knowledgeEvidenceState) {
|
return match ($knowledgeEvidenceState) {
|
||||||
'direct' => 'fachlich belegt; Shopdaten werden geprüft',
|
'direct' => 'fachlich belegt; Shopdaten werden geprüft',
|
||||||
|
'aggregate_missing' => 'geprüfte Quellen ohne Zählinformation; Shopdaten werden geprüft',
|
||||||
'weak' => 'RAG-Näherungstreffer; Shopdaten werden geprüft',
|
'weak' => 'RAG-Näherungstreffer; Shopdaten werden geprüft',
|
||||||
default => 'Shopdaten werden geprüft',
|
default => 'Shopdaten werden geprüft',
|
||||||
};
|
};
|
||||||
@@ -1725,6 +1738,20 @@ final readonly class AgentRunner
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $patterns
|
||||||
|
*/
|
||||||
|
private function containsAnyRagEvidencePattern(string $haystack, array $patterns): bool
|
||||||
|
{
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
|
if (@preg_match($pattern, $haystack) === 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<int, string[]>
|
* @return array<int, string[]>
|
||||||
*/
|
*/
|
||||||
@@ -1968,8 +1995,15 @@ final readonly class AgentRunner
|
|||||||
bool $isCommerceIntent,
|
bool $isCommerceIntent,
|
||||||
bool $shopSearchAttempted,
|
bool $shopSearchAttempted,
|
||||||
bool $hasShopResults,
|
bool $hasShopResults,
|
||||||
bool $shopSearchHadSystemFailure
|
bool $shopSearchHadSystemFailure,
|
||||||
|
string $knowledgeEvidenceState = 'unknown'
|
||||||
): string {
|
): string {
|
||||||
|
if ($knowledgeEvidenceState === 'aggregate_missing' && !$hasShopResults) {
|
||||||
|
return $shopSearchHadSystemFailure
|
||||||
|
? 'geprüfte Quellen ohne Zählinformation; Shopdaten nicht verfügbar'
|
||||||
|
: 'geprüfte Quellen, keine passende Zählinformation';
|
||||||
|
}
|
||||||
|
|
||||||
if ($shopSearchHadSystemFailure) {
|
if ($shopSearchHadSystemFailure) {
|
||||||
return $hasKnowledge ? 'fachlich belegt; Shopdaten nicht verfügbar' : 'Shopdaten nicht verfügbar';
|
return $hasKnowledge ? 'fachlich belegt; Shopdaten nicht verfügbar' : 'Shopdaten nicht verfügbar';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,12 @@ final readonly class PromptBuilder
|
|||||||
string $knowledgeEvidenceState = 'unknown'
|
string $knowledgeEvidenceState = 'unknown'
|
||||||
): string {
|
): string {
|
||||||
$hasDirectKnowledgeEvidence = $knowledgeEvidenceState === 'direct' || $knowledgeEvidenceState === 'unknown' && $hasKnowledge;
|
$hasDirectKnowledgeEvidence = $knowledgeEvidenceState === 'direct' || $knowledgeEvidenceState === 'unknown' && $hasKnowledge;
|
||||||
$hasWeakKnowledgeEvidence = $knowledgeEvidenceState === 'weak';
|
$hasAggregateMissingEvidence = $knowledgeEvidenceState === 'aggregate_missing';
|
||||||
|
$hasWeakKnowledgeEvidence = $knowledgeEvidenceState === 'weak' || $hasAggregateMissingEvidence;
|
||||||
|
|
||||||
|
if ($hasAggregateMissingEvidence && !$hasShopResults && !$shopSearchHadSystemFailure) {
|
||||||
|
return 'aggregatfrage_keine_belastbare_zaehlinformation';
|
||||||
|
}
|
||||||
|
|
||||||
if ($shopSearchHadSystemFailure && !$hasDirectKnowledgeEvidence) {
|
if ($shopSearchHadSystemFailure && !$hasDirectKnowledgeEvidence) {
|
||||||
return $hasWeakKnowledgeEvidence
|
return $hasWeakKnowledgeEvidence
|
||||||
|
|||||||
@@ -355,6 +355,14 @@ final class AgentRunnerConfig
|
|||||||
return $this->getRequiredStringList('rag_evidence_guard.aggregate_evidence_terms');
|
return $this->getRequiredStringList('rag_evidence_guard.aggregate_evidence_terms');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getRagEvidenceAggregateAnswerEvidencePatterns(): array
|
||||||
|
{
|
||||||
|
return $this->getRequiredStringList('rag_evidence_guard.aggregate_answer_evidence_patterns');
|
||||||
|
}
|
||||||
|
|
||||||
public function getNoLlmFallbackShopOnlyMessage(): string
|
public function getNoLlmFallbackShopOnlyMessage(): string
|
||||||
{
|
{
|
||||||
return $this->getRequiredString('no_llm_fallback.messages.shop_only');
|
return $this->getRequiredString('no_llm_fallback.messages.shop_only');
|
||||||
|
|||||||
@@ -460,6 +460,7 @@ final readonly class RetriexEffectiveConfigProvider
|
|||||||
'synonyms' => $this->agentRunnerConfig->getRagEvidenceSynonyms(),
|
'synonyms' => $this->agentRunnerConfig->getRagEvidenceSynonyms(),
|
||||||
'aggregate_query_patterns' => $this->agentRunnerConfig->getRagEvidenceAggregateQueryPatterns(),
|
'aggregate_query_patterns' => $this->agentRunnerConfig->getRagEvidenceAggregateQueryPatterns(),
|
||||||
'aggregate_evidence_terms' => $this->agentRunnerConfig->getRagEvidenceAggregateEvidenceTerms(),
|
'aggregate_evidence_terms' => $this->agentRunnerConfig->getRagEvidenceAggregateEvidenceTerms(),
|
||||||
|
'aggregate_answer_evidence_patterns' => $this->agentRunnerConfig->getRagEvidenceAggregateAnswerEvidencePatterns(),
|
||||||
],
|
],
|
||||||
'source_labels' => [
|
'source_labels' => [
|
||||||
'external_url' => $this->agentRunnerConfig->getExternalUrlSourceLabel(),
|
'external_url' => $this->agentRunnerConfig->getExternalUrlSourceLabel(),
|
||||||
@@ -1021,6 +1022,7 @@ final readonly class RetriexEffectiveConfigProvider
|
|||||||
$this->validateStringListMap($ragEvidence['synonyms'] ?? [], 'agent.rag_evidence_guard.synonyms', $errors, $warnings);
|
$this->validateStringListMap($ragEvidence['synonyms'] ?? [], 'agent.rag_evidence_guard.synonyms', $errors, $warnings);
|
||||||
$this->validateRegexPatternList($ragEvidence['aggregate_query_patterns'] ?? [], 'agent.rag_evidence_guard.aggregate_query_patterns', $errors);
|
$this->validateRegexPatternList($ragEvidence['aggregate_query_patterns'] ?? [], 'agent.rag_evidence_guard.aggregate_query_patterns', $errors);
|
||||||
$this->validateStringList($this->toList($ragEvidence['aggregate_evidence_terms'] ?? []), 'agent.rag_evidence_guard.aggregate_evidence_terms', $errors, $warnings);
|
$this->validateStringList($this->toList($ragEvidence['aggregate_evidence_terms'] ?? []), 'agent.rag_evidence_guard.aggregate_evidence_terms', $errors, $warnings);
|
||||||
|
$this->validateRegexPatternList($ragEvidence['aggregate_answer_evidence_patterns'] ?? [], 'agent.rag_evidence_guard.aggregate_answer_evidence_patterns', $errors);
|
||||||
|
|
||||||
$this->validateStringListMap($agent['shop_query_optimizer'] ?? [], 'agent.shop_query_optimizer', $errors, $warnings);
|
$this->validateStringListMap($agent['shop_query_optimizer'] ?? [], 'agent.shop_query_optimizer', $errors, $warnings);
|
||||||
$this->validateRegexPattern($agent['optimized_shop_query_prefix_pattern'] ?? null, 'agent.optimized_shop_query_prefix_pattern', $errors);
|
$this->validateRegexPattern($agent['optimized_shop_query_prefix_pattern'] ?? null, 'agent.optimized_shop_query_prefix_pattern', $errors);
|
||||||
|
|||||||
Reference in New Issue
Block a user