678 lines
31 KiB
YAML
678 lines
31 KiB
YAML
# Agent orchestration limits, user-visible status/source labels and Shopware query prompt wording.
|
|
# Values mirror the current stable defaults; PHP fallbacks remain in AgentRunnerConfig.
|
|
parameters:
|
|
retriex.agent.config:
|
|
commerce_history_budget_chars: 1000
|
|
product_search_knowledge_chunk_limit: 6
|
|
advisory_product_search_knowledge_chunk_limit: 9
|
|
optimized_shop_query_prefix_pattern: '/^(?:keywords?|suchquery|search\s*query|query)\s*:\s*/iu'
|
|
optimized_shop_query_trim_characters: " \t\n\r\0\x0B\"'`"
|
|
|
|
input_normalization:
|
|
enabled: true
|
|
max_input_chars: 500
|
|
max_output_chars: 700
|
|
max_added_tokens: 2
|
|
max_length_ratio_percent: 150
|
|
heartbeat_message: 'Ich optimiere die Anfrage…'
|
|
output_prefix_pattern: '/^(?:normalisiert|korrigiert|corrected|normalized)\s*:\s*/iu'
|
|
placeholder_outputs:
|
|
- 'normalized user input'
|
|
- 'corrected user input'
|
|
- 'user input'
|
|
- 'normalisierte nutzereingabe'
|
|
- 'korrigierte nutzereingabe'
|
|
skip_patterns:
|
|
- '/https?:\/\//iu'
|
|
- '/\bwww\./iu'
|
|
- '/```/u'
|
|
prompt:
|
|
intro: 'Normalize the following user input for RetrieX routing before intent detection.'
|
|
output_format_block: |-
|
|
Output format:
|
|
Return exactly one line: the corrected user input.
|
|
current_user_input_label: 'USER INPUT'
|
|
rules:
|
|
- '- Output only the corrected user input text itself, never the words "normalized user input".'
|
|
- '- Correct only obvious typing mistakes, transposed letters, missing umlauts, spacing, and punctuation that clearly preserve the same meaning.'
|
|
- '- Do not add product names, model numbers, article numbers, measurement values, parameters, brands, or application areas that are not already present in the input.'
|
|
- '- Preserve product names, model numbers, article numbers, chemical symbols, units, pH, Redox, ORP, and measurement values exactly unless only letter casing is corrected.'
|
|
- '- Preserve the input language; do not translate German into English or English into German.'
|
|
- '- Preserve vague references such as "der indikator", "das gerät", "suche im shop", or "dazu" without resolving them from context.'
|
|
- '- If the input is already clear or you are uncertain, return the original input unchanged.'
|
|
- '- No introduction, no explanation, no quotation marks.'
|
|
|
|
fuzzy_routing:
|
|
enabled: true
|
|
min_token_length: 4
|
|
medium_token_length: 7
|
|
long_token_length: 11
|
|
max_distance_short: 1
|
|
max_distance_medium: 2
|
|
max_distance_long: 3
|
|
min_similarity_percent: 72
|
|
# Canonical routing terms only, not typo variants.
|
|
# Resolved from config/retriex/vocabulary.yaml view
|
|
# agent.input_normalization_fuzzy_routing_terms.
|
|
# A local terms list may still be added here as an explicit project override.
|
|
vocabulary_views:
|
|
terms: agent.input_normalization_fuzzy_routing_terms
|
|
|
|
follow_up_context:
|
|
strong_reference_patterns:
|
|
- '/\bder\s+wert\b/u'
|
|
- '/\bdieser\s+wert\b/u'
|
|
- '/\bdiesen\s+wert\b/u'
|
|
- '/\bdem\s+wert\b/u'
|
|
- '/\bmit\s+welche(?:m|n|r)?\b/u'
|
|
- '/\bwomit\b/u'
|
|
- '/\bdamit\b/u'
|
|
- '/\bdafuer\b/u'
|
|
- '/\bdafür\b/u'
|
|
- '/\bdazu\b/u'
|
|
- '/\bdaraus\b/u'
|
|
- '/\bwelche(?:r|s|m|n)?\s+indikator\b/u'
|
|
- '/\bwelche(?:r|s|m|n)?\s+indikatortyp\b/u'
|
|
- '/\bindikator\s+(?:dafuer|dafür|dazu|hierfuer|hierfür)\b/u'
|
|
- '/\bwelche(?:r|s|m|n)?\s+bereich\b/u'
|
|
- '/\bwelche(?:r|s|m|n)?\s+messbereich\b/u'
|
|
- '/\bwelche(?:r|s|m|n)?\s+grenzwert\b/u'
|
|
explicit_commercial_signal_terms:
|
|
- shop
|
|
- preis
|
|
- preise
|
|
- preisen
|
|
- kostet
|
|
- kosten
|
|
- kaufen
|
|
- bestellen
|
|
- warenkorb
|
|
- lieferzeit
|
|
- verfuegbar
|
|
- verfügbar
|
|
- lager
|
|
- url
|
|
- link
|
|
- artikelnummer
|
|
- sku
|
|
- produktnummer
|
|
|
|
commercial_table_follow_up:
|
|
enabled: true
|
|
prompt_patterns:
|
|
- '/\b(?:tabelle|tabellarisch|übersicht|uebersicht|liste|auflistung)\b.{0,80}\b(?:preis|preise|preisen|kosten|kostet|shop)\b/u'
|
|
- '/\b(?:preis|preise|preisen|kosten|kostet|shop)\b.{0,80}\b(?:tabelle|tabellarisch|übersicht|uebersicht|liste|auflistung)\b/u'
|
|
- '/\b(?:mit|inkl|inklusive|plus)\s+(?:preis|preise|preisen|kosten|shopdaten)\b/u'
|
|
history_anchor_patterns:
|
|
- '/\bTestomat(?:®)?\s+\d{3,4}\b/iu'
|
|
- '/\b(?:Indikatortyp|Indikator|Indikatoren|Reagenz|Reagenzien|Zubehör|Zubehoer)\b/iu'
|
|
vocabulary_views:
|
|
table_terms: agent.follow_up_context.commercial_table_follow_up.table_terms
|
|
commercial_terms:
|
|
- preis
|
|
- preise
|
|
- preisen
|
|
- kosten
|
|
- kostet
|
|
- shop
|
|
- shoppreis
|
|
- shoppreise
|
|
- shopdaten
|
|
indicator_marker_patterns:
|
|
- '/\b(?:Indikatortyp|Indikator(?:en)?|indicator(?:\s+type)?|Reagenz(?:ien)?)\b/iu'
|
|
query_template_with_model: '{model} indikator'
|
|
query_template_without_model: 'indikator'
|
|
history_question_pattern: '/^Question:\s*(.+)$/mi'
|
|
history_turn_split_pattern: '/(?=^Question:\s)/m'
|
|
history_question_strip_pattern: '/^Question:\s*.*(?:\R|$)/u'
|
|
context_labels:
|
|
previous_user_question_template: 'Vorherige Nutzerfrage: {question}'
|
|
previous_reference_anchors_template: 'Vorherige technische Referenzanker (nur zur Referenzauflösung, keine Faktenquelle): {anchors}'
|
|
current_follow_up_question_template: 'Aktuelle Folgefrage: {question}'
|
|
reference_anchor:
|
|
product_model_pattern: '/\bTestomat(?:®)?\s+(?:\d{3,4}(?:\s+[A-Z]{2,8})?|EVO(?:\s+[A-Z]{2,6})?|ECO(?:[-\s]?(?:PLUS|C))?|DUO(?:\s+\d{3,4})?|LAB(?:\s+[A-Z]{2,6})?)\b/iu'
|
|
measurement_value_pattern: '/\b\d+(?:[,.]\d+)?\s*°\s*dH\b/iu'
|
|
|
|
messages:
|
|
empty_prompt: '❌ Empty prompt.'
|
|
analyze_request: 'Ich analysiere deine Anfrage...'
|
|
check_internet_sources: 'Ich prüfe auf Internetquellen...'
|
|
retrieve_knowledge: 'Ich hole relevante Daten aus meinem RAG-Wissen...'
|
|
optimize_search: 'Ich optimiere die Recherche...'
|
|
no_concrete_shop_query: 'Ich kann die Shop-Suche noch nicht belastbar auflösen. Bitte nenne das Produkt, den Messparameter oder das Zubehör etwas konkreter.'
|
|
fetch_search_data_template: 'Ich rufe Recherchedaten ab (type: %s)'
|
|
analyze_all_information: 'Ich analysiere alle Informationen...'
|
|
thinking_while_streaming: 'Denke nach...'
|
|
no_llm_data_received: '❌ Es wurden keine Daten vom LLM empfangen.'
|
|
shop_repair_check: 'Erweiterte Shopsuche wird geprüft…'
|
|
shop_query_optimization_heartbeat: 'Shop-Suchanfrage wird optimiert…'
|
|
generic_internal_error: '❌ Bei der Verarbeitung der Anfrage ist ein interner Fehler aufgetreten.'
|
|
debug_internal_error_prefix: '❌ Interner Fehler: '
|
|
|
|
final_answer_guard:
|
|
enabled: true
|
|
# Prevents runaway final answers caused by repeated LLM output. This is a
|
|
# runtime safety guard and does not change retrieval, ranking or product matching.
|
|
max_output_chars: 12000
|
|
truncation_message: |2-
|
|
|
|
Hinweis: Die Antwort wurde gekürzt, weil eine wiederholte oder zu lange Ausgabe erkannt wurde. Bitte starten Sie bei Bedarf eine präzisere Nachfrage.
|
|
repeated_line:
|
|
enabled: true
|
|
min_output_chars: 1200
|
|
min_line_chars: 16
|
|
max_line_repetitions: 3
|
|
trailing_window_lines: 220
|
|
ignore_patterns:
|
|
- '/^\s*(?:produkt(?:-|\s)?nummer|artikel(?:-|\s)?nummer|preis|verfügbar|verfuegbar|url|quellen?)\b/iu'
|
|
- '/^\s*(?:status|query|intent|datenbasis|shop(?:-|\s)?suche)\b/iu'
|
|
|
|
rag_evidence_guard:
|
|
cleanup_profile: rag_evidence
|
|
# Legacy/domain override list. Generic German stopwords are provided by
|
|
# language cleanup profile `rag_evidence`. Keep RAG/product-role terms here.
|
|
stop_terms:
|
|
- ohne
|
|
- messen
|
|
- messung
|
|
- tester
|
|
- testgerät
|
|
- testgeraet
|
|
- gerät
|
|
- geraet
|
|
- messgerät
|
|
- messgeraet
|
|
- produkt
|
|
- produkte
|
|
- artikel
|
|
- shop
|
|
aggregate_query_patterns:
|
|
- '/\bwie\s+viele\b/u'
|
|
- '/\bwieviele\b/u'
|
|
- '/\banzahl\b/u'
|
|
- '/\bcount\b/u'
|
|
- '/\bgesamtzahl\b/u'
|
|
aggregate_evidence_terms:
|
|
- anzahl
|
|
- gesamtzahl
|
|
- stückzahl
|
|
- stueckzahl
|
|
- count
|
|
- portfolio
|
|
- sortiment
|
|
- bestand
|
|
- bestände
|
|
- bestaende
|
|
- 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'
|
|
vocabulary_maps:
|
|
synonyms: agent.rag_evidence_guard.synonyms
|
|
|
|
direct_shop_result_answer:
|
|
enabled: true
|
|
max_results: 10
|
|
intro: 'Aus den Shopdaten ergeben sich folgende passende Treffer:'
|
|
no_results: 'Ich finde in den Shopdaten keine passenden Treffer für die angefragte Produktsuche. Ich liste deshalb keine fachfremden Ersatzprodukte auf.'
|
|
sorted_by_length_note: 'Sortierung: aufsteigend nach erkannter Kabellänge.'
|
|
min_length_filter_note: 'Filter: nur Treffer ab {value} m.'
|
|
max_length_filter_note: 'Filter: nur Treffer bis {value} m.'
|
|
|
|
no_llm_fallback:
|
|
max_shop_results: 5
|
|
messages:
|
|
shop_only: 'Ich finde dazu im RAG-Wissen keine belastbare Fachinformation. Aus den Shopdaten ergeben sich folgende Treffer; technische Eignung bitte prüfen:'
|
|
shop_with_knowledge: 'Es liegen RAG-/Kontexttreffer und Shopdaten vor. Ohne LLM leite ich daraus keine technische Eignung ab. Die Shopdaten zeigen folgende Treffer; technische Eignung bitte prüfen:'
|
|
accessory_only_for_main_device: 'Die Shop-Treffer wirken wie Zubehör/Verbrauchsmaterial und nicht wie eine angefragte Messanlage oder ein Hauptgerät. Ich werte sie deshalb nicht als passende Hauptlösung.'
|
|
escalation: 'Für eine verbindliche Produktauswahl sollte der konkrete Anwendungsfall durch Vertrieb oder Support geprüft werden.'
|
|
knowledge_only: 'Ich habe Treffer im RAG-Wissen gefunden, aber ohne LLM kann ich daraus keine belastbare fachliche Antwort synthetisieren. Ich gebe deshalb keine sichere Produktaussage aus. Bitte aktiviere das LLM oder konkretisiere die Frage für eine gezielte Prüfung.'
|
|
no_data: 'Ich finde dazu keine belastbaren Daten in den vorliegenden Quellen. Bitte nenne Produkt, Messparameter, Zubehör oder Anwendungsfall genauer.'
|
|
no_shop_results_with_knowledge: 'Ich finde RAG-/Kontexttreffer, aber keine passenden Shop-Treffer zur aktuellen Suchanfrage. Das ist keine Aussage, dass es das Produkt nicht gibt. Ohne LLM gebe ich keine technische Negativaussage aus; bitte prüfe den Suchbegriff oder den Anwendungsfall gezielter.'
|
|
no_shop_results_no_knowledge: 'Ich finde weder belastbares RAG-Wissen noch passende Shop-Treffer zur aktuellen Suchanfrage. Das ist keine sichere Negativaussage. Bitte nenne Produkt, Messparameter oder Zubehör konkreter.'
|
|
shop_unavailable_with_knowledge: 'Live-Shopdaten konnten nicht geladen werden. Ich kann keine Aussage zu aktueller Verfügbarkeit, Preis oder Shop-Portfolio treffen. Wenn das RAG-Wissen einen direkten Fachbeleg enthält, wird die fachliche Antwort davon getrennt betrachtet.'
|
|
shop_unavailable_no_knowledge: 'Live-Shopdaten konnten nicht geladen werden und die RAG-Treffer enthalten keinen direkten Fachbeleg zur Anfrage. Ich kann daraus keine verlässliche Produkt-, Verfügbarkeits- oder Portfolioaussage ableiten.'
|
|
product_fields:
|
|
unreadable_results_message: '- Es wurden Shop-Treffer übergeben, aber keine lesbaren Produktdaten gefunden.'
|
|
unnamed_product: 'Unbenanntes Shop-Produkt'
|
|
product_number_template: 'Art.-Nr. {value}'
|
|
manufacturer_template: 'Hersteller: {value}'
|
|
price_template: 'Preis: {value}'
|
|
availability_template: 'Verfügbar: {value}'
|
|
availability_yes: 'ja'
|
|
availability_no: 'nein'
|
|
url_template: 'URL: {value}'
|
|
incompatible_role_note: 'Hinweis: Zubehör/Verbrauchsartikel; nicht als Messanlage/Gerät bestätigt'
|
|
line_template: '{index}. {parts}'
|
|
separator: ' | '
|
|
unavailable_reason_template: '{message} Ursache: {reason}'
|
|
|
|
product_roles:
|
|
vocabulary_views:
|
|
main_device_request_keywords: agent.no_llm_fallback.product_roles.main_device_request_keywords
|
|
accessory_product_keywords: agent.no_llm_fallback.product_roles.accessory_product_keywords
|
|
|
|
|
|
production_ui:
|
|
stage_labels:
|
|
preparing_answer: 'Antwort wird vorbereitet'
|
|
shop_routing_detected: 'Shop-Routing erkannt'
|
|
rag_searched: 'RAG-Wissen wurde durchsucht'
|
|
shop_search_preparing: 'Shop-Suche wird vorbereitet'
|
|
more_context_needed: 'Mehr Kontext nötig'
|
|
shop_search_running: 'Shop wird durchsucht'
|
|
shop_unavailable: 'Shopdaten nicht verfügbar'
|
|
shop_completed: 'Shop-Suche abgeschlossen'
|
|
answer_generating: 'Antwort wird generiert'
|
|
completed: 'Abgeschlossen'
|
|
interrupted: 'Antwort wurde unterbrochen'
|
|
confidence_labels:
|
|
checking_evidence: 'Beleglage wird geprüft'
|
|
checking_shop_data: 'Shopdaten werden geprüft'
|
|
more_context_needed: 'mehr Kontext nötig'
|
|
interrupted: 'nicht abgeschlossen'
|
|
direct: 'fachlich belegt'
|
|
aggregate_missing: 'geprüfte Quellen, keine passende Zählinformation'
|
|
weak: 'RAG-Näherungstreffer, kein direkter Fachbeleg'
|
|
default: 'noch keine belastbaren Treffer'
|
|
direct_shop_check: 'fachlich belegt; Shopdaten werden geprüft'
|
|
aggregate_missing_shop_check: 'geprüfte Quellen ohne Zählinformation; Shopdaten werden geprüft'
|
|
weak_shop_check: 'RAG-Näherungstreffer; Shopdaten werden geprüft'
|
|
default_shop_check: 'Shopdaten werden geprüft'
|
|
aggregate_missing_shop_unavailable: 'geprüfte Quellen ohne Zählinformation; Shopdaten nicht verfügbar'
|
|
aggregate_missing_no_count: 'geprüfte Quellen, keine passende Zählinformation'
|
|
shop_unavailable_with_knowledge: 'fachlich belegt; Shopdaten nicht verfügbar'
|
|
shop_unavailable: 'Shopdaten nicht verfügbar'
|
|
rag_and_shop: 'RAG + Shopdaten'
|
|
shop_only: 'nur Shopdaten'
|
|
rag_no_shop_hits: 'RAG-Wissen, keine Shop-Treffer'
|
|
no_reliable_data: 'keine belastbaren Daten'
|
|
no_reliable_hits: 'noch keine belastbaren Treffer'
|
|
text:
|
|
live_shop_source_plain_label: 'Live-Shopdaten'
|
|
run_status_eyebrow: 'RetrieX-Status'
|
|
evidence_prefix: 'Beleglage: '
|
|
data_basis_label: 'Datenbasis'
|
|
data_basis_empty_completed: 'keine belastbare Datenbasis'
|
|
data_basis_empty_running: 'wird geprüft'
|
|
rag_hits_checking: 'RAG-Treffer: wird geprüft'
|
|
shop_hits_loading: 'Shop-Treffer: wird geladen'
|
|
shop_hits_unavailable: 'Shop-Treffer: nicht verfügbar'
|
|
shop_hits_no_query: 'Shop-Treffer: keine Suchquery'
|
|
shop_hits_not_requested: 'Shop-Treffer: nicht angefragt'
|
|
status_completed: 'Status: abgeschlossen'
|
|
status_running: 'Status: läuft'
|
|
shop_results_eyebrow: 'Shop-Ergebnisse'
|
|
shop_results_title: 'Shop-Ergebnisse'
|
|
evaluated_query_label: 'Ausgewertete Suchquery'
|
|
unnamed_product: 'Unbenanntes Produkt'
|
|
field_not_provided: 'nicht übermittelt'
|
|
product_number_label: 'Artikelnummer'
|
|
price_label: 'Preis'
|
|
availability_label: 'Verfügbarkeit'
|
|
manufacturer_label: 'Hersteller'
|
|
relevance_label: 'Relevanz'
|
|
availability_yes: 'verfügbar'
|
|
availability_no: 'nicht verfügbar'
|
|
availability_unknown: 'Shopstatus nicht übermittelt'
|
|
followup_eyebrow: 'Folgeaktionen'
|
|
followup_title: 'Was möchtest du als Nächstes tun?'
|
|
shop_meta_fallback_query: 'keine Suchquery ermittelt'
|
|
shop_meta_query_mode_optimized: 'optimiert'
|
|
shop_meta_query_mode_direct: 'direkt'
|
|
shop_meta_default_intent: 'commerce'
|
|
shop_meta_title_unavailable: 'Shopdaten nicht verfügbar'
|
|
shop_meta_title_completed: 'Shop-Suche abgeschlossen'
|
|
shop_meta_title_running: 'Shop-Suche wird ausgeführt'
|
|
shop_meta_status_completed: 'Status: abgeschlossen'
|
|
shop_meta_status_running: 'Status: läuft'
|
|
shop_meta_result_unavailable: 'Shoptreffer: nicht verfügbar'
|
|
shop_meta_result_loading: 'Shoptreffer: wird geladen'
|
|
shop_meta_repair_used: 'Erweiterte Suche: genutzt'
|
|
shop_meta_repair_checked: 'Erweiterte Suche: geprüft'
|
|
shop_meta_eyebrow: 'Shop-Suche'
|
|
shop_meta_query_label: 'Gesendete Suchquery'
|
|
shop_meta_query_prefix: 'Query: '
|
|
shop_meta_intent_prefix: 'Intent: '
|
|
shop_unavailable_default_reason: 'Keine Detailmeldung vom Shopware-Server.'
|
|
shop_unavailable_title: 'Shopdaten konnten nicht geladen werden'
|
|
shop_unavailable_text_prefix: 'RetrieX antwortet ohne Live-Shopdaten weiter. Ursache: '
|
|
no_llm_history_default: 'Es wurden keine Daten vom LLM empfangen.'
|
|
history_notice_default_title: 'Systemhinweis'
|
|
history_notice_shop_unavailable_title: 'Shopdaten konnten nicht geladen werden'
|
|
history_notice_answer_incomplete_title: 'Antwort konnte nicht abgeschlossen werden'
|
|
templates:
|
|
rag_hits_count: 'RAG-Treffer: {count}'
|
|
shop_hits_count: 'Shop-Treffer: {count}'
|
|
shop_results_summary: '{count} Shop-Treffer ausgewertet'
|
|
shop_results_top_displayed_suffix: ' · Top {max} angezeigt'
|
|
shop_results_repair_suffix: ' · erweiterte Shopsuche genutzt'
|
|
relevance_matched_queries: 'Gefunden über: {queries}'
|
|
relevance_highlight: 'Passender Shop-Hinweis: {highlight}'
|
|
relevance_match_source: 'Trefferquelle: {source}'
|
|
relevance_query: 'Passend zur Suchquery: {query}'
|
|
relevance_default: 'Aus den Live-Shopdaten übernommen'
|
|
shop_meta_result_count: 'Shoptreffer: {count}'
|
|
history_notice_without_detail: 'Systemhinweis: {title}.'
|
|
history_notice_with_detail: 'Systemhinweis: {title}. Ursache: {detail}'
|
|
shop_results:
|
|
max_cards: 5
|
|
follow_up_actions:
|
|
commerce:
|
|
- label: 'Im Shop suchen'
|
|
prompt: 'Suche die aktuelle Produktauswahl im Shop.'
|
|
- label: 'Nur Zubehör anzeigen'
|
|
prompt: 'Zeige aus der aktuellen Produktauswahl nur Zubehör.'
|
|
- label: 'Nur Geräte anzeigen'
|
|
prompt: 'Zeige aus der aktuellen Produktauswahl nur Geräte.'
|
|
- label: 'Preis anzeigen'
|
|
prompt: 'Zeige mir die Preise der aktuell relevanten Produkte.'
|
|
knowledge:
|
|
- label: 'Technische Details anzeigen'
|
|
prompt: 'Zeige technische Details zur aktuellen Antwort.'
|
|
|
|
source_labels:
|
|
external_url: 'Externe URL'
|
|
rag_knowledge: 'RAG Wissen'
|
|
conversation_history: 'Chatverlauf'
|
|
shop_system: 'Shopsystem'
|
|
extended_shop_search: 'Erweiterte Shopsuche'
|
|
used_sources_prefix: 'Genutzte Quellen: '
|
|
sources_prefix: 'Quellen: '
|
|
|
|
html:
|
|
source_badge_template: '<span class="badge bg-info text-black">%s</span>'
|
|
error_template: |
|
|
<div class="retriex-alert retriex-alert--error"><div class="retriex-alert__icon">❌</div><div class="retriex-alert__content"><div class="retriex-alert__title">Hinweis</div><div class="retriex-alert__text">%s</div></div></div>
|
|
think_template: |
|
|
<span class="text-info think">%s</span>
|
|
info_template: "\n\n<span class=\"text-info fw-bolder\">%s</span>\n"
|
|
debug_template: "\n\nDEBUG: <code>%s</code>\n"
|
|
|
|
shop_prompt:
|
|
intro: 'Generate a short search query for Shopware 6 from the following user input text.'
|
|
output_format_block: |-
|
|
Output format:
|
|
Keyword1 Keyword2 Keyword3
|
|
recent_conversation_context_label: 'RECENT CONVERSATION CONTEXT'
|
|
current_user_input_label: 'CURRENT USER INPUT'
|
|
rules:
|
|
- '- Output only the final search query.'
|
|
- '- Always convert relevant search terms to their singular form.'
|
|
- '- No introduction, no explanation, no quotation marks.'
|
|
- '- Use only shop-relevant search terms from the user input for a shop search.'
|
|
- '- Maximum 6 search terms, preferably fewer.'
|
|
- '- Remove filler words, polite phrases, and irrelevant words.'
|
|
- '- Preserve product names, brands, model numbers, and compound terms exactly if they are relevant.'
|
|
- '- Preserve the language of the CURRENT USER INPUT for generic product/search terms; do not translate German search terms into English.'
|
|
- '- For German user input, output German shop terms, for example "freies Chlor Messung" instead of "free chlorine measurement".'
|
|
- '- Preserve domain terms from the current user input or resolved context in their original language.'
|
|
- '- Numbers that belong to a product name or model must be preserved when they are present in the CURRENT USER INPUT or a clearly resolved reference.'
|
|
- '- Separate terms using spaces only.'
|
|
- '- If a relevant product name is present, it must be placed at the beginning of the final search query.'
|
|
- '- Try to always identify all products mentioned in the user input text, even in long prompts.'
|
|
- '- Look for terms such as Testomat, Horiba, Tritromat, Pockettester, Redox, ORP, or words like indicator/Indikator.'
|
|
- '- If the current user input is vague or referential, use the recent conversation context only as support.'
|
|
- '- Do not output words that only describe conversation flow, such as "same", "again", "also", or "like above".'
|
|
conversation_context_rules:
|
|
- '- The current user input has highest priority.'
|
|
- '- Use the recent conversation context only to resolve omitted references.'
|
|
- '- Use it only for product carry-over, brand carry-over, model carry-over, or variant follow-ups.'
|
|
- '- Do not revive older products unless the current user input clearly refers to them.'
|
|
- '- If the current input starts a new topic, ignore older product context.'
|
|
- '- Prefer the most recent product reference over older ones.'
|
|
current_input_preservation:
|
|
enabled: true
|
|
# Terms that must be preserved from the current user input in the final
|
|
# Shopware search query. This prevents short domain terms from being
|
|
# dropped by query optimization or generic cleanup. Adapt vocabulary view
|
|
# defaults or add a local `terms` override instead of changing PHP code.
|
|
vocabulary_views:
|
|
terms: agent.shop_prompt.current_input_preservation_terms
|
|
|
|
product_attribute_query_cleanup:
|
|
enabled: true
|
|
# For direct product/accessory lookups with comparative attribute
|
|
# constraints, keep the concrete product type and application terms but
|
|
# do not send range words/numeric thresholds to the plain text shop
|
|
# search. Example: "Anschlusskabel pH/Redox länger 20m" becomes
|
|
# "anschlusskabel redox" so the shop can return 25m/50m/100m cables.
|
|
min_query_tokens_after_cleanup: 2
|
|
# Direct product/accessory cleanup terms are resolved from
|
|
# config/retriex/vocabulary.yaml. Local lists may still be added here
|
|
# as project-specific overrides, but the default source is vocabulary.
|
|
vocabulary_views:
|
|
product_type_terms: search_repair.direct_product_type_terms
|
|
stop_terms: search_repair.direct_product_attribute_stop_terms
|
|
comparative_constraint_patterns:
|
|
- '/\b(?:länger|laenger|kürzer|kuerzer|größer|groesser|kleiner|über|ueber|unter|mindestens|maximal|maximum|minimum|ab|bis|mehr\s+als|weniger\s+als)\s+(?P<value>\d+(?:[,.]\d+)?\s*[\p{L}µ°%]*)\b/iu'
|
|
|
|
query_stopword_cleanup:
|
|
enabled: true
|
|
min_query_tokens_after_cleanup: 2
|
|
# Plain Shopware text search should contain product-relevant terms only.
|
|
# These terms are UI, instruction, presentation or sorting words and are
|
|
# removed after LLM query optimization. Keep this list simple and local.
|
|
terms:
|
|
- zeige
|
|
- zeig
|
|
- suche
|
|
- such
|
|
- finde
|
|
- find
|
|
- gib
|
|
- gebe
|
|
- nenne
|
|
- mir
|
|
- bitte
|
|
- ich
|
|
- wir
|
|
- im
|
|
- in
|
|
- shop
|
|
- für
|
|
- fuer
|
|
- nach
|
|
- mit
|
|
- ohne
|
|
- von
|
|
- zum
|
|
- zur
|
|
- der
|
|
- die
|
|
- das
|
|
- ein
|
|
- eine
|
|
- einen
|
|
- ordne
|
|
- sortiere
|
|
- sortiert
|
|
- sortierung
|
|
- liste
|
|
- tabelle
|
|
- übersicht
|
|
- uebersicht
|
|
- auflistung
|
|
- meter
|
|
- metern
|
|
|
|
direct_result_guard:
|
|
enabled: true
|
|
# Direct product-list answers should only list products whose primary
|
|
# identity (name/URL) matches the requested product type. This prevents
|
|
# devices from being listed as a requested consumable merely because the
|
|
# description mentions such consumables as accessories.
|
|
prefer_primary_identity_matches: true
|
|
compound_prefix_match:
|
|
enabled: true
|
|
# Some Shopware product names combine the requested product type with
|
|
# a noun suffix, for example "pH-Pufferlösung". Keep this list small
|
|
# and explicit so broad direct-result filtering remains safe.
|
|
terms:
|
|
- puffer
|
|
- kalibrierpuffer
|
|
|
|
length_sort:
|
|
enabled: true
|
|
trigger_patterns:
|
|
- '/\b(?:ordne|sortiere|sortiert|sortierung)\b.{0,80}\b(?:meter|metern|m)\b/iu'
|
|
- '/\bnach\s+(?:meter|metern|m)\b/iu'
|
|
value_patterns:
|
|
- '/(?P<value>\d+(?:[,.]\d+)?)\s*(?:m|meter|metern)\b/iu'
|
|
|
|
length_filter:
|
|
enabled: true
|
|
min_patterns:
|
|
- '/\b(?:ab|mindestens|minimum|min\.?|>=|größer\s+gleich|groesser\s+gleich)\s*(?P<value>\d+(?:[,.]\d+)?)\s*(?:m|meter|metern)\b/iu'
|
|
- '/\b(?:länger|laenger|größer|groesser|mehr)\s+(?:als\s+)?(?P<value>\d+(?:[,.]\d+)?)\s*(?:m|meter|metern)\b/iu'
|
|
- '/(?P<value>\d+(?:[,.]\d+)?)\s*(?:m|meter|metern)\s*(?:oder\s+)?(?:länger|laenger|mehr)\b/iu'
|
|
max_patterns:
|
|
- '/\b(?:bis|maximal|maximum|max\.?|höchstens|hoechstens|<=|kleiner\s+gleich)\s*(?P<value>\d+(?:[,.]\d+)?)\s*(?:m|meter|metern)\b/iu'
|
|
- '/\b(?:kürzer|kuerzer|kleiner|weniger)\s+(?:als\s+)?(?P<value>\d+(?:[,.]\d+)?)\s*(?:m|meter|metern)\b/iu'
|
|
- '/(?P<value>\d+(?:[,.]\d+)?)\s*(?:m|meter|metern)\s*(?:oder\s+)?(?:kürzer|kuerzer|weniger)\b/iu'
|
|
|
|
context_usage:
|
|
referential_terms:
|
|
- der
|
|
- die
|
|
- das
|
|
- den
|
|
- dem
|
|
- dazu
|
|
- davon
|
|
- dafür
|
|
- dafuer
|
|
- dieser
|
|
- diese
|
|
- dieses
|
|
- obige
|
|
- obigen
|
|
- oben
|
|
- vorher
|
|
- zuvor
|
|
- gleiche
|
|
- gleichen
|
|
- selbe
|
|
- selben
|
|
context_anchor_enrichment:
|
|
enabled: true
|
|
max_query_terms: 2
|
|
template: '{anchor} {query}'
|
|
vocabulary_views:
|
|
trigger_terms: agent.shop_prompt.context_anchor_enrichment.trigger_terms
|
|
anchor_patterns:
|
|
- '/\b(?:indikator(?:typ)?|indicator(?:\s+type)?|reagenz(?:satz|typ)?|reagent(?:\s+set|\s+type)?|typ|type)\s+[A-Za-zÄÖÜäöüß]{0,8}\s*\d{1,5}(?:\s*[A-ZÄÖÜ]{1,4})?(?:\s*%)?\b/iu'
|
|
meta_query_guard:
|
|
enabled: true
|
|
cleanup_profile: shop_context_fallback
|
|
context_fallback_enabled: true
|
|
context_fallback_question_limit: 12
|
|
context_fallback_history_budget_chars: 20000
|
|
context_fallback_use_full_history: true
|
|
context_fallback_max_terms: 6
|
|
# Legacy/domain override list. Generic stopwords, user-instruction
|
|
# phrases and presentation terms are provided by profile
|
|
# `shop_context_fallback`. Keep shop/price/domain terms here.
|
|
context_fallback_filter_terms:
|
|
- preis
|
|
- preise
|
|
- preisen
|
|
- kosten
|
|
- kostet
|
|
- grenzwert
|
|
- grenzwerte
|
|
- grenzwerten
|
|
- welche
|
|
- gut
|
|
- geeignet
|
|
- messen
|
|
- gemessen
|
|
meta_only_terms:
|
|
- shop
|
|
- preis
|
|
- preise
|
|
- preisen
|
|
- kosten
|
|
- kostet
|
|
- shopsuche
|
|
- shop-suche
|
|
rag_anchor_enrichment:
|
|
enabled: true
|
|
# Enriches overly narrow numeric shop queries with a product anchor from
|
|
# retrieved RAG records when the same record explicitly contains the
|
|
# requested numeric value/unit. This prevents queries such as "0,02"
|
|
# when RAG already identified a concrete product such as a device model.
|
|
min_score: 120
|
|
max_query_terms: 6
|
|
early_chunk_bonus_max: 10
|
|
template: '{anchor} {query} {subject}'
|
|
scores:
|
|
exact_value_with_unit: 120
|
|
exact_value_only: 40
|
|
anchor_bonus: 50
|
|
numeric_focus_patterns:
|
|
- '/(?P<value>\d+(?:[,.]\d+)?)\s*(?P<unit>°?\s*d\s*h|dh|dH)/iu'
|
|
product_title_patterns:
|
|
- '/#\s*Produkt\s+Titel:\s*`(?P<title>[^`]+)`/iu'
|
|
- '/\*\*Produktname:\*\*\s*(?P<title>[^\r\n]+)/iu'
|
|
anchor_bonus_patterns:
|
|
- '/\b[\p{L}][\p{L}\p{N}®+._-]*(?:\s+|[-_])\d{2,5}\b/u'
|
|
subject_terms:
|
|
- resthärte
|
|
- resthaerte
|
|
- wasserhärte
|
|
- wasserhaerte
|
|
- gesamthärte
|
|
- gesamthaerte
|
|
- härte
|
|
- haerte
|
|
- grenzwert
|
|
- messung
|
|
|
|
language_preservation:
|
|
enabled: true
|
|
language_markers:
|
|
de:
|
|
- ' ä '
|
|
- ' ö '
|
|
- ' ü '
|
|
- ' ß '
|
|
- ' der '
|
|
- ' die '
|
|
- ' das '
|
|
- ' ein '
|
|
- ' eine '
|
|
- ' einer '
|
|
- ' einen '
|
|
- ' welchem '
|
|
- ' welchen '
|
|
- ' welche '
|
|
- ' welcher '
|
|
- ' kann '
|
|
- ' nutzen '
|
|
- ' zur '
|
|
- ' für '
|
|
- ' fuer '
|
|
- ' messung '
|
|
- ' indikator '
|
|
- ' reagenz '
|
|
- ' chlor '
|
|
translation_replacements:
|
|
de:
|
|
free chlorine: 'freies chlor'
|
|
free chlor: 'freies chlor'
|
|
total chlorine: 'gesamtchlor'
|
|
chlorine measurement: 'chlor messung'
|
|
water hardness: 'wasserhärte'
|
|
measurement: 'messung'
|
|
measuring: 'messung'
|
|
chlorine: 'chlor'
|
|
indicator: 'indikator'
|
|
indicators: 'indikatoren'
|
|
reagent: 'reagenz'
|
|
reagents: 'reagenzien'
|
|
accessory: 'zubehör'
|
|
accessories: 'zubehör'
|