optimize commerce keyword filterlist

This commit is contained in:
team 1
2026-05-03 19:25:21 +02:00
parent 98447703ac
commit 2520ca06af
4 changed files with 190 additions and 1 deletions

View File

@@ -610,6 +610,7 @@ final readonly class PromptBuilder
$negativeContextTerms = $this->extractMeasurementGuardStringList($guard, 'negative_context_terms');
$nonEquivalentTerms = $this->extractMeasurementGuardStringList($guard, 'non_equivalent_terms');
$label = $this->normalizeBlockText((string) ($guard['label'] ?? 'requested measurement parameter'));
$strictNoEvidence = (bool) ($guard['strict_no_evidence'] ?? true);
$resolvedRequestedRole = $requestedRole ?? $this->resolveRequestedProductRole($prompt);
$safeNoEvidenceAnswer = $this->normalizeBlockText((string) (
$resolvedRequestedRole === 'accessory_or_consumable'
@@ -650,6 +651,7 @@ final readonly class PromptBuilder
}
$rules = $this->config->getMeasurementEvidenceIntroRules();
$rules = array_merge($rules, $this->config->getMeasurementEvidenceProductSpecificRules());
$rules[] = '- User requested measurement parameter: ' . $label . '.';
$rules[] = '- Positive parameter terms for this request: ' . implode(', ', $positiveTerms) . '.';
if ($positiveContextTerms !== []) {
@@ -666,7 +668,11 @@ final readonly class PromptBuilder
$rules[] = '- RAG/URL evidence scan for this exact parameter: ' . ($knowledgeHasEvidence ? 'explicit positive evidence found.' : 'no explicit positive evidence found.');
$rules = array_merge($rules, $shopEvidenceLines);
if (!$knowledgeHasEvidence && !$shopHasEvidence) {
if (!$strictNoEvidence && !$knowledgeHasEvidence && !$shopHasEvidence) {
$rules[] = '- The deterministic exact-term scan did not find product-specific evidence. The answer may still use a clearly equivalent named measurement parameter from the same source record, but must not infer suitability from generic categories, document titles, tags, search terms, neighbouring products, or broad umbrella-topic wording.';
}
if ($strictNoEvidence && !$knowledgeHasEvidence && !$shopHasEvidence) {
$rules[] = '- Mandatory answer behavior: do not recommend a product as suitable for this measurement parameter.';
if ($safeNoEvidenceAnswer !== '') {
$rules[] = '- Start the answer with this meaning in the user language: ' . $safeNoEvidenceAnswer;
@@ -724,14 +730,114 @@ final readonly class PromptBuilder
foreach ($requestTerms as $term) {
if ($this->containsMeasurementTerm($normalizedPrompt, $term)) {
$parameter['strict_no_evidence'] = true;
return $parameter;
}
}
}
return $this->resolveGenericRequestedMeasurementGuard($prompt);
}
private function resolveGenericRequestedMeasurementGuard(string $prompt): ?array
{
foreach ($this->config->getMeasurementEvidenceGenericRequestPatterns() as $pattern) {
if (@preg_match($pattern, $prompt, $matches) !== 1) {
continue;
}
$rawParameter = $matches['parameter'] ?? ($matches[1] ?? '');
if (!is_scalar($rawParameter)) {
continue;
}
$parameterTerms = $this->buildGenericMeasurementParameterTerms((string) $rawParameter);
if ($parameterTerms === []) {
continue;
}
$label = implode(' / ', $parameterTerms);
return [
'id' => 'generic_' . substr(sha1($label), 0, 12),
'label' => $label,
'request_terms' => $parameterTerms,
'positive_terms' => $parameterTerms,
'positive_context_terms' => $this->config->getMeasurementEvidenceGenericPositiveContextTerms(),
'negative_context_terms' => $this->config->getMeasurementEvidenceGenericNegativeContextTerms(),
'non_equivalent_terms' => [],
'safe_no_evidence_answer_de' => $this->renderMeasurementEvidenceTemplate(
$this->config->getMeasurementEvidenceGenericSafeNoEvidenceAnswerTemplate(),
$label
),
'safe_no_accessory_evidence_answer_de' => $this->renderMeasurementEvidenceTemplate(
$this->config->getMeasurementEvidenceGenericSafeNoAccessoryEvidenceAnswerTemplate(),
$label
),
'strict_no_evidence' => false,
];
}
return null;
}
/**
* @return string[]
*/
private function buildGenericMeasurementParameterTerms(string $rawParameter): array
{
$rawParameter = $this->normalizeBlockText($rawParameter);
if ($rawParameter === '') {
return [];
}
$terms = [];
$withoutParentheses = preg_replace('/\([^)]*\)/u', ' ', $rawParameter) ?? $rawParameter;
$this->appendGenericMeasurementParameterParts($terms, $withoutParentheses);
if (preg_match_all('/\(([^)]{1,40})\)/u', $rawParameter, $matches) === 1) {
foreach ($matches[1] as $parenthetical) {
$this->appendGenericMeasurementParameterParts($terms, (string) $parenthetical);
}
}
return array_values(array_unique($terms));
}
/**
* @param string[] $terms
*/
private function appendGenericMeasurementParameterParts(array &$terms, string $value): void
{
$value = $this->normalizeBlockText($value);
if ($value === '') {
return;
}
$parts = preg_split('/\s*(?:,|;|\/|\boder\b|\bund\b|\bor\b|\band\b)\s*/iu', $value) ?: [$value];
foreach ($parts as $part) {
$part = $this->normalizeBlockText((string) $part);
$part = trim($part, " \t\n\r\0\x0B-–—:()[]{}\"'`“”„");
if ($part === '' || preg_match('/[\p{L}\p{N}]/u', $part) !== 1) {
continue;
}
if (mb_strlen($part, 'UTF-8') < 2 || in_array($part, $terms, true)) {
continue;
}
$terms[] = $part;
}
}
private function renderMeasurementEvidenceTemplate(string $template, string $label): string
{
return strtr($template, ['{label}' => $label]);
}
/**
* @return string[]
*/

View File

@@ -581,6 +581,48 @@ final class PromptBuilderConfig
return $this->getRequiredStringList('measurement_evidence_guard.intro_rules');
}
/**
* @return string[]
*/
public function getMeasurementEvidenceProductSpecificRules(): array
{
return $this->getRequiredStringList('measurement_evidence_guard.product_specific_rules');
}
/**
* @return string[]
*/
public function getMeasurementEvidenceGenericRequestPatterns(): array
{
return $this->getRequiredStringList('measurement_evidence_guard.generic_request_patterns');
}
/**
* @return string[]
*/
public function getMeasurementEvidenceGenericPositiveContextTerms(): array
{
return $this->getRequiredStringList('measurement_evidence_guard.generic_positive_context_terms');
}
/**
* @return string[]
*/
public function getMeasurementEvidenceGenericNegativeContextTerms(): array
{
return $this->getRequiredStringList('measurement_evidence_guard.generic_negative_context_terms');
}
public function getMeasurementEvidenceGenericSafeNoEvidenceAnswerTemplate(): string
{
return $this->getRequiredString('measurement_evidence_guard.generic_safe_no_evidence_answer_template_de');
}
public function getMeasurementEvidenceGenericSafeNoAccessoryEvidenceAnswerTemplate(): string
{
return $this->getRequiredString('measurement_evidence_guard.generic_safe_no_accessory_evidence_answer_template_de');
}
/**
* @return array<int, array<string, mixed>>
*/