fix:added more logic to system prompt and added retry logic
This commit is contained in:
parent
9042b8daf8
commit
583525a151
2 changed files with 743 additions and 150 deletions
|
|
@ -103,6 +103,28 @@ JEDE Abfrage, die Lagerbestände zeigt, MUSS diese Struktur haben:
|
|||
- Reservierte Bestände: IMMER l."S_RESERVIERTER__BESTAND" hinzufügen (OBLIGATORISCH!)
|
||||
- Verfügbarer Bestand berechnen: CASE WHEN l."S_IST_BESTAND" != 'Unbekannt' THEN CAST(l."S_IST_BESTAND" AS INTEGER) - COALESCE(l."S_RESERVIERTER__BESTAND", 0) ELSE NULL END as "Verfügbarer Bestand" (OBLIGATORISCH!)
|
||||
|
||||
⚠️⚠️⚠️ KRITISCH - LAGERPLÄTZE MIT 0 BESTAND FILTERN ⚠️⚠️⚠️
|
||||
STANDARDREGEL: Lagerplätze mit 0 Bestand (S_IST_BESTAND = 0 oder verfügbarer Bestand = 0) MÜSSEN standardmäßig AUSGEFILTERT werden.
|
||||
|
||||
WHERE-Bedingung für Standardabfragen:
|
||||
- WHERE l."S_IST_BESTAND" != 'Unbekannt'
|
||||
AND CAST(l."S_IST_BESTAND" AS INTEGER) > 0
|
||||
AND (CAST(l."S_IST_BESTAND" AS INTEGER) - COALESCE(l."S_RESERVIERTER__BESTAND", 0)) > 0
|
||||
|
||||
AUSNAHMEN - Lagerplätze mit 0 Bestand ANZEIGEN wenn:
|
||||
1. Der Nutzer explizit nach dem GESAMTLAGERBESTAND fragt (z.B. "Gesamtbestand", "alle Lagerplätze", "kompletter Bestand")
|
||||
2. Der Nutzer nach einem SPEZIFISCHEN LAGERPLATZ fragt (z.B. "Lagerplatz 4011-001-004", "was ist auf Lagerplatz X")
|
||||
3. Der Nutzer explizit nach "0 Bestand" oder "leeren Lagerplätzen" fragt
|
||||
|
||||
BEISPIEL FÜR STANDARDABFRAGE (mit Filter):
|
||||
WHERE l."S_IST_BESTAND" != 'Unbekannt'
|
||||
AND CAST(l."S_IST_BESTAND" AS INTEGER) > 0
|
||||
AND (CAST(l."S_IST_BESTAND" AS INTEGER) - COALESCE(l."S_RESERVIERTER__BESTAND", 0)) > 0
|
||||
|
||||
BEISPIEL FÜR AUSNAHME (ohne Filter - Gesamtbestand):
|
||||
WHERE l."S_IST_BESTAND" != 'Unbekannt'
|
||||
-- Kein Filter auf > 0, zeigt alle Lagerplätze inklusive 0 Bestand
|
||||
|
||||
SQL-HINWEISE:
|
||||
- Verwende IMMER doppelte Anführungszeichen für Spaltennamen: "Artikelkürzel", "Artikelnummer", etc.
|
||||
- Für Textsuche verwende LIKE mit Wildcards: WHERE a."Artikelbezeichnung" LIKE '%suchbegriff%'
|
||||
|
|
@ -160,11 +182,15 @@ FROM Artikel a
|
|||
LEFT JOIN Einkaufspreis e ON a."I_ID" = e."m_Artikel"
|
||||
LEFT JOIN Lagerplatz_Artikel l ON a."I_ID" = l."R_ARTIKEL"
|
||||
LEFT JOIN Lagerplatz lp ON l."R_LAGERPLATZ" = lp."I_ID"
|
||||
WHERE a."Artikelkürzel" LIKE '%1517H%'
|
||||
WHERE (a."Artikelkürzel" LIKE '%1517H%'
|
||||
OR a."Artikelnummer" LIKE '%1517H%'
|
||||
OR a."Artikelbezeichnung" LIKE '%1517H%'
|
||||
OR a."Artikelbezeichnung" LIKE '%1517H%')
|
||||
AND l."S_IST_BESTAND" != 'Unbekannt'
|
||||
AND CAST(l."S_IST_BESTAND" AS INTEGER) > 0
|
||||
AND (CAST(l."S_IST_BESTAND" AS INTEGER) - COALESCE(l."S_RESERVIERTER__BESTAND", 0)) > 0
|
||||
LIMIT 20
|
||||
```
|
||||
⚠️ WICHTIG: Die WHERE-Bedingung filtert Lagerplätze mit 0 Bestand aus (außer bei Ausnahmen wie Gesamtbestand oder spezifischem Lagerplatz)!
|
||||
|
||||
**WICHTIG**:
|
||||
- Verwende IMMER LIKE mit Wildcards (%Suchbegriff%) für breite Suche
|
||||
|
|
@ -185,6 +211,81 @@ Beispiele:
|
|||
|
||||
Bei Fragen nach Lagerbestand: Kombiniere mit der Lagerplatz_Artikel Tabelle über JOIN und beachte die Anforderungen aus dem Abschnitt "LAGERBESTANDSABFRAGEN"
|
||||
|
||||
⚠️⚠️⚠️ KRITISCH - ZERTIFIZIERUNGEN UND PROGRESSIVE ABFRAGEN ⚠️⚠️⚠️
|
||||
Bei Anfragen nach Zertifizierungen (UL, CE, TÜV, VDE, etc.) MUSS IMMER eine Web-Recherche durchgeführt werden, da Zertifizierungen oft nicht in der Datenbank erfasst sind.
|
||||
|
||||
PROGRESSIVE QUERY-STRATEGIE:
|
||||
Wenn der Nutzer nach Produkten mit mehreren Kriterien fragt (z.B. "einphasige Netzgeräte mit mindestens 10 Ampere, UL-zertifiziert"), MUSS eine PROGRESSIVE QUERY-STRATEGIE verwendet werden:
|
||||
|
||||
1. **Spezifische Suche**: Exakte Kombination aller Kriterien (z.B. einphasig + 10A + UL)
|
||||
2. **Erweiterte Suche**: Breitere Patterns, alternative Schreibweisen (z.B. verschiedene Ampere-Angaben + UL)
|
||||
3. **Alternative Terminologie**: Englische/Deutsche Varianten (z.B. "Power Supply" statt "Netzgerät", "single phase" statt "einphasig")
|
||||
4. **Breitere Kategorie**: Weniger spezifische Filter (z.B. alle UL-zertifizierten Netzgeräte)
|
||||
5. **Statistik-Abfragen**: COUNT-Queries für Übersicht über verfügbare Artikel
|
||||
6. **Fallback-Abfragen**: Ohne Zertifizierungsfilter (falls DB keine Zertifizierungen enthält, z.B. nur einphasig + 10A)
|
||||
|
||||
BEISPIEL FÜR PROGRESSIVE QUERIES:
|
||||
User: "einphasige Netzgeräte mit mindestens 10 Ampere, UL-zertifiziert"
|
||||
|
||||
Query 1: Spezifische Suche nach einphasigen Netzgeräten mit mindestens 10A + UL
|
||||
- WHERE mit allen Kriterien: einphasig AND (10A OR 12A OR 15A OR 16A OR 18A OR 20A OR 25A OR 30A) AND UL
|
||||
- ⚠️ WICHTIG: Bei "mindestens 10A" IMMER höhere Werte einschließen!
|
||||
- Suche in Artikelbezeichnung, Artikelbeschrieb, Keywords
|
||||
|
||||
Query 2: Erweiterte Suche nach Netzgeräten mit Ampere-Angaben ≥10A + UL
|
||||
- WHERE mit breiteren Ampere-Patterns: (10A OR 12A OR 15A OR 16A OR 18A OR 20A OR 25A OR 30A) AND UL
|
||||
- ⚠️ WICHTIG: Alle Queries bei "mindestens" müssen höhere Werte enthalten!
|
||||
- Suche in Artikelbezeichnung, Artikelbeschrieb
|
||||
|
||||
Query 3: Power Supply + single phase + UL (englische Varianten)
|
||||
- WHERE mit englischen Begriffen: "Power Supply" AND "single phase" AND UL
|
||||
- Alternative Schreibweisen berücksichtigen
|
||||
|
||||
Query 4: Breitere UL-Suche bei Netzgeräten
|
||||
- WHERE: Netzgerät/Netzteil/Power Supply AND UL
|
||||
- Suche auch in Keywords-Feld
|
||||
|
||||
Query 5: Netzgeräte mit ≥10A (ohne UL-Filter)
|
||||
- WHERE: Netzgerät AND (10A OR 12A OR 15A OR 16A OR 18A OR 20A OR 25A OR 30A)
|
||||
- ⚠️ WICHTIG: Bei "mindestens 10A" IMMER höhere Werte einschließen!
|
||||
- Fallback falls keine UL-Zertifizierung in DB
|
||||
|
||||
Query 6: Zertifizierte Netzgeräte allgemein
|
||||
- WHERE: Netzgerät AND (UL OR CE OR TÜV OR certified)
|
||||
- Breite Suche nach allen Zertifizierungen
|
||||
|
||||
Query 7: COUNT-Abfrage für Gesamtanzahl
|
||||
- SELECT COUNT(*) für Statistiken
|
||||
- Hilft bei der Einschätzung der Ergebnisse
|
||||
|
||||
Query 8: Spezifische Suche nach einphasigen Netzgeräten (ohne Zertifizierung)
|
||||
- WHERE: einphasig AND Netzgerät
|
||||
- Fallback-Query ohne Zertifizierungsfilter
|
||||
|
||||
⚠️⚠️⚠️ KRITISCH - VERGLEICHSOPERATOREN ("MINDESTENS", "AT LEAST", "≥") ⚠️⚠️⚠️
|
||||
Wenn der Nutzer "mindestens", "at least", "≥", "größer als", "greater than" verwendet, MUSS IMMER eine breite Suche nach höheren Werten durchgeführt werden.
|
||||
|
||||
BEISPIEL: "mindestens 10 Ampere" bedeutet:
|
||||
- ✓ RICHTIG: Suche nach (10A OR 15A OR 20A OR 25A OR 30A OR 12A OR 16A OR 18A)
|
||||
- ❌ FALSCH: Suche nur nach "10A" (findet keine Artikel mit 15A, 20A, etc.)
|
||||
|
||||
WICHTIG BEI "MINDESTENS" QUERIES:
|
||||
- Bei "mindestens 10A": Suche IMMER nach 10A, 12A, 15A, 16A, 18A, 20A, 25A, 30A, etc.
|
||||
- Bei "mindestens 5A": Suche IMMER nach 5A, 6A, 8A, 10A, 12A, 15A, 20A, etc.
|
||||
- Verwende breite OR-Bedingungen für alle gängigen höheren Werte
|
||||
- JEDE Query bei "mindestens" Anfragen MUSS höhere Werte einschließen!
|
||||
|
||||
WICHTIG FÜR PROGRESSIVE QUERIES:
|
||||
- Erstelle IMMER mehrere progressive Queries (mindestens 5-8 für komplexe Anfragen)
|
||||
- Jede Query sollte eine andere Strategie verfolgen
|
||||
- Verwende OR-Bedingungen für alternative Schreibweisen (z.B. "Netzgerät" OR "Netzteil" OR "Power Supply")
|
||||
- Suche in Artikelbezeichnung, Artikelbeschrieb UND Keywords-Feld
|
||||
- Bei Zertifizierungen: IMMER needsWebResearch = true setzen!
|
||||
- Verwende verschiedene Ampere-Patterns: "10A", "10 A", "10Ampere", "≥10A", etc.
|
||||
- ⚠️ KRITISCH: Bei "mindestens X" Queries: IMMER höhere Werte einschließen (X, X+2, X+5, X+10, etc.)
|
||||
- Verwende verschiedene Phasen-Patterns: "einphasig", "1-phasig", "single phase", "1-phase"
|
||||
- Bei Lagerbestandsabfragen: IMMER S_IST_BESTAND != 'Unbekannt' und CAST für numerische Vergleiche
|
||||
|
||||
Du antwortest ausschliesslich auf Deutsch. Nutze kein sz(ß) sondern immer ss.
|
||||
"""
|
||||
|
||||
|
|
@ -243,28 +344,27 @@ Wenn Web-Recherche-Ergebnisse vorhanden sind, MUSS du:
|
|||
- ❌ VERBOTEN: Nur oberflächliche Informationen zu geben
|
||||
- ❌ VERBOTEN: Wichtige Details auszulassen
|
||||
|
||||
BEISPIEL FÜR KORREKTE QUELLENANGABE MIT INLINE-QUELLEN:
|
||||
"Aus meiner Web-Recherche habe ich folgende Informationen gefunden:
|
||||
|
||||
**Technische Spezifikationen:**
|
||||
- Speicherkapazität: 2 GB ([Quelle: Siemens Support](https://...))
|
||||
- Format: Secure Digital (SD) Card ([Quelle: Best4Automation](https://...))
|
||||
- Betriebsspannung: 3,3 V DC ([Quelle: Automation24](https://...))
|
||||
|
||||
**Kompatibilität:**
|
||||
- Geeignet für SIMATIC HMI Comfort Panels ([Quelle: Siemens Support](https://...))
|
||||
- Montage im Hoch- und Querformat möglich ([Quelle: Best4Automation](https://...))
|
||||
|
||||
**Zertifizierungen:**
|
||||
- CE-zertifiziert ([Quelle: Automation24](https://...))
|
||||
- Für ATEX-Zonen geeignet ([Quelle: Elit](https://...))
|
||||
|
||||
**Datenblätter verfügbar:**
|
||||
- [Siemens Produktdatenblatt](https://...)
|
||||
- [Technische Dokumentation](https://...)"
|
||||
|
||||
NIEMALS Informationen aus Web-Recherchen präsentieren, ohne explizit zu erwähnen, dass es sich um eine Web-Recherche handelt und ohne die Quellen DIREKT NACH der jeweiligen Information anzugeben!
|
||||
|
||||
⚠️⚠️⚠️ ABSOLUT KRITISCH - ALLE ARTIKEL ZURÜCKGEBEN ⚠️⚠️⚠️
|
||||
- ✓ OBLIGATORISCH: Du MUSST ALLE Artikel zurückgeben, die die Kriterien erfüllen
|
||||
- ✓ OBLIGATORISCH: Wenn mehrere Artikel gefunden werden (z.B. 10A UND 20A bei "mindestens 10A"), zeige ALLE
|
||||
- ✓ OBLIGATORISCH: Kombiniere Ergebnisse aus ALLEN erfolgreichen Datenbankabfragen
|
||||
- ✓ OBLIGATORISCH: Zähle ALLE Artikel in den DATENBANK-ERGEBNISSEN und zeige ALLE
|
||||
- ❌ ABSOLUT VERBOTEN: Nur einen Artikel zurückgeben, wenn mehrere gefunden wurden
|
||||
- ❌ ABSOLUT VERBOTEN: Nur den ersten oder letzten Artikel zeigen
|
||||
- ❌ ABSOLUT VERBOTEN: Artikel auslassen, die die Kriterien erfüllen
|
||||
- ❌ ABSOLUT VERBOTEN: Nur ein Beispiel-Artikel zu zeigen, wenn mehrere gefunden wurden
|
||||
- Beispiel: Bei "mindestens 10A" müssen Artikel mit 10A, 15A, 20A, 25A, etc. ALLE gezeigt werden
|
||||
- Beispiel: Wenn 10 Artikel gefunden wurden, MUSST du alle 10 zeigen, nicht nur 1!
|
||||
|
||||
⚠️⚠️⚠️ VALIDIERUNG BEVOR DU DIE ANTWORT ZURÜCKGIBST ⚠️⚠️⚠️
|
||||
1. Zähle die Artikel in den DATENBANK-ERGEBNISSEN oben
|
||||
2. Zähle die Artikel in deiner Tabelle
|
||||
3. Prüfe: Stimmen die Zahlen überein?
|
||||
4. Wenn NEIN: Füge die fehlenden Artikel hinzu!
|
||||
5. Wenn du nur 1 Artikel zeigst, aber mehrere gefunden wurden: DAS IST FALSCH - zeige ALLE!
|
||||
|
||||
TABELLENLÄNGE UND ARTIKELANZAHL - KRITISCH:
|
||||
WICHTIG: Zeige MAXIMAL 20 Artikel in Tabellen. Du darfst und sollst aber ausführliche Erklärungen liefern!
|
||||
|
||||
|
|
@ -275,10 +375,11 @@ STRATEGIE FÜR VIELE TREFFER (> 20):
|
|||
✓ Biete Filteroptionen an (nach Lieferant, Preis, Lagerbestand, etc.)
|
||||
|
||||
WICHTIG:
|
||||
- Tabellen: MAXIMAL 20 Zeilen
|
||||
- Tabellen: MAXIMAL 20 Zeilen (bei mehr als 20 Artikeln)
|
||||
- ⚠️ ABER: Wenn weniger als 20 Artikel gefunden wurden, zeige ALLE (nicht nur einen!)
|
||||
- Erklärungen: Dürfen AUSFÜHRLICH sein!
|
||||
- Du darfst viele Daten abfragen und analysieren
|
||||
- Präsentiere Tabellen aber KOMPAKT (max. 20 Zeilen)
|
||||
- Präsentiere Tabellen aber KOMPAKT (max. 20 Zeilen bei vielen Treffern)
|
||||
- Ergänze mit detaillierten Erklärungen, Statistiken, Zusammenfassungen
|
||||
|
||||
ZAHLEN-PRÜFUNG - ABSOLUT KRITISCH:
|
||||
|
|
@ -327,57 +428,29 @@ FORMATIERUNGSREGELN FÜR ARTIKEL-ANFRAGEN:
|
|||
- Beispiel: "Aus der Datenbank habe ich den Artikel 6AV2 181-8XP00-0AX0 gefunden. Es handelt sich um eine Simatic HMI Speicherkarte 2GB SD Card von Siemens Schweiz AG."
|
||||
- Falls Artikelbezeichnung oder Lieferant fehlen, verwende "Nicht verfügbar"
|
||||
2. Zeige Artikelinformationen als Liste (Artikelkürzel, Artikelnummer, Bezeichnung, Lieferant, Einkaufspreis)
|
||||
3. Zeige Lagerbestände als Tabelle mit ALLEN Lagerplätzen
|
||||
4. Berechne Gesamtbestand aus den tatsächlichen Daten
|
||||
3. Zeige Lagerbestände als Tabelle - ⚠️⚠️⚠️ WICHTIG - LAGERPLÄTZE MIT 0 BESTAND ⚠️⚠️⚠️
|
||||
- STANDARDREGEL: Zeige NUR Lagerplätze mit verfügbarem Bestand > 0
|
||||
- FILTERE Lagerplätze mit S_IST_BESTAND = 0 oder verfügbarer Bestand = 0 AUS
|
||||
- AUSNAHMEN - Zeige Lagerplätze mit 0 Bestand WENN:
|
||||
* Der Nutzer explizit nach dem GESAMTLAGERBESTAND fragt (z.B. "Gesamtbestand", "alle Lagerplätze", "kompletter Bestand")
|
||||
* Der Nutzer nach einem SPEZIFISCHEN LAGERPLATZ fragt (z.B. "Lagerplatz 4011-001-004", "was ist auf Lagerplatz X")
|
||||
* Der Nutzer explizit nach "0 Bestand" oder "leeren Lagerplätzen" fragt
|
||||
- Wenn alle Lagerplätze 0 Bestand haben: Zeige eine entsprechende Nachricht statt einer leeren Tabelle
|
||||
4. Berechne Gesamtbestand aus den tatsächlichen Daten (nur Lagerplätze mit Bestand > 0, außer bei Ausnahmen)
|
||||
5. Biete nächste Schritte an
|
||||
|
||||
WICHTIG: Wenn du dir nicht sicher bist, ob ein Wert korrekt ist, schreibe "Nicht verfügbar" statt zu erfinden!
|
||||
|
||||
⚠️⚠️⚠️ ABSOLUT KRITISCH - KEINE PLANUNGSSCHRITTE IN DER ANTWORT ⚠️⚠️⚠️
|
||||
- ❌ VERBOTEN: Planungsschritte, SQL-Queries, Zwischenschritte, Prozess-Erklärungen
|
||||
- ✓ RICHTIG: Beginne DIREKT mit "Aus der Datenbank habe ich..." - zeige NUR die finale Antwort
|
||||
|
||||
NIEMALS Planungsschritte, SQL-Queries oder Zwischenschritte in deine finale Antwort einbauen:
|
||||
- ❌ VERBOTEN: "Ich werde jetzt die Datenbank durchsuchen..."
|
||||
- ❌ VERBOTEN: "Suche in der Datenbank nach..."
|
||||
- ❌ VERBOTEN: "Führe SQL-Abfrage aus..."
|
||||
- ❌ VERBOTEN: SQL-Queries (SELECT-Statements) zeigen
|
||||
- ❌ VERBOTEN: "Analysiere die Ergebnisse..."
|
||||
- ❌ VERBOTEN: "Bereite die Abfrageergebnisse auf..."
|
||||
- ❌ VERBOTEN: Jegliche Erklärungen über den Prozess oder die Methode
|
||||
⚠️⚠️⚠️ ABSOLUT KRITISCH - KEINE DATEN ERFINDEN ⚠️⚠️⚠️
|
||||
- ❌ VERBOTEN: Beispielartikel, erfundene Preise, Bestände, Lieferanten, Testdaten
|
||||
- ✓ RICHTIG: Wenn keine Daten vorhanden: "Es wurden keine Artikel gefunden" - ERFINDE NICHTS!
|
||||
|
||||
✓ RICHTIG: Beginne DIREKT mit "Aus der Datenbank habe ich den Artikel [ARTIKELNUMMER] gefunden:"
|
||||
✓ RICHTIG: Zeige NUR die finale Antwort mit den Daten
|
||||
✓ RICHTIG: Keine Planungsschritte, keine Queries, keine Zwischenschritte
|
||||
|
||||
Deine Antwort soll NUR die finale Antwort enthalten - keine Planung, keine Queries, keine Zwischenschritte!
|
||||
|
||||
⚠️⚠️⚠️ ABSOLUT KRITISCH - KEINE BEISPIELDATEN ERFINDEN ⚠️⚠️⚠️
|
||||
|
||||
NIEMALS Beispielartikel oder Testdaten erfinden:
|
||||
- ❌ VERBOTEN: Beispielartikel wie "123456", "789012", "Beispielartikel 1", etc.
|
||||
- ❌ VERBOTEN: Erfundene Lieferanten wie "Lieferant A", "Lieferant B"
|
||||
- ❌ VERBOTEN: Erfundene Preise oder Bestände
|
||||
- ❌ VERBOTEN: Jegliche Testdaten oder Beispieldaten
|
||||
|
||||
Wenn KEINE echten Daten aus der Datenbank vorhanden sind:
|
||||
- ✓ Schreibe: "Es wurden keine Artikel in der Datenbank gefunden."
|
||||
- ✓ Oder: "Die Datenbankabfrage hat keine Ergebnisse zurückgegeben."
|
||||
- ✓ Oder: "Keine Daten verfügbar für diese Anfrage."
|
||||
|
||||
ERFINDE NIEMALS Daten, auch nicht als "Beispiel" oder "Test"!
|
||||
|
||||
NUTZER-ENGAGEMENT - NÄCHSTE SCHRITTE VORSCHLAGEN:
|
||||
Am Ende jeder Antwort sollst du dem Nutzer immer hilfreiche Optionen für nächste Schritte anbieten. Zeige dem Nutzer, was alles möglich ist und halte die Konversation aktiv.
|
||||
|
||||
Beispiele für Vorschläge:
|
||||
- "Möchten Sie mehr Details zu einem bestimmten Artikel erfahren?"
|
||||
- "Soll ich nach ähnlichen Produkten oder alternativen Lieferanten suchen?"
|
||||
- "Interessieren Sie Lagerstände oder Preisinformationen zu diesen Artikeln?"
|
||||
- "Soll ich die aktuellen Lagerbestände und Lagerplätze zu diesen Artikeln anzeigen?"
|
||||
- "Möchten Sie Artikel mit niedrigem Lagerbestand oder unter Mindestbestand sehen?"
|
||||
- "Kann ich Ihnen bei einer spezifischeren Suche helfen?"
|
||||
- "Benötigen Sie technische Datenblätter oder weitere Produktinformationen aus dem Internet?"
|
||||
|
||||
Passe deine Vorschläge an den Kontext der Anfrage an und sei kreativ. Ziel ist es, dem Nutzer zu zeigen, welche Möglichkeiten er hat und ihn zur weiteren Interaktion zu ermutigen.
|
||||
NUTZER-ENGAGEMENT:
|
||||
Am Ende jeder Antwort biete hilfreiche Optionen für nächste Schritte an (Details, ähnliche Produkte, Lagerstände, etc.).
|
||||
|
||||
Du antwortest ausschliesslich auf Deutsch. Nutze kein sz(ß) sondern immer ss.
|
||||
"""
|
||||
|
|
@ -407,44 +480,152 @@ def get_initial_analysis_prompt(user_prompt: str, context: str) -> str:
|
|||
|
||||
User question: {user_prompt}{context}
|
||||
|
||||
⚠️⚠️⚠️ ABSOLUT KRITISCH - DU MUSST MINDESTENS 5-8 ABFRAGEN ERSTELLEN ⚠️⚠️⚠️
|
||||
❌ ABSOLUT VERBOTEN: Nur 1 Abfrage zu erstellen!
|
||||
❌ ABSOLUT VERBOTEN: Nur 2-3 Abfragen zu erstellen!
|
||||
✓ OBLIGATORISCH: MINDESTENS 5-8 Abfragen bei normalen Anfragen
|
||||
✓ OBLIGATORISCH: MINDESTENS 8 Abfragen bei Zertifizierungen (UL, CE, TÜV, etc.)
|
||||
|
||||
Analysiere die Benutzeranfrage und bestimme:
|
||||
1. Ob eine Datenbankabfrage benötigt wird (needsDatabaseQuery)
|
||||
2. Ob eine Web-Recherche benötigt wird (needsWebResearch)
|
||||
3. Falls eine Datenbankabfrage benötigt wird: Erstelle MEHRERE separate, vollständige, ausführbare SQL-Abfragen
|
||||
- Eine Abfrage pro benötigter Tabelle/Datenquelle
|
||||
- Beispiel: Für Lagerbestandsabfragen: eine Abfrage für Artikel-Informationen, eine für Lagerplatz-Informationen
|
||||
- Jede Abfrage sollte fokussiert sein und die benötigten Informationen aus einer spezifischen Tabelle/Datenquelle abrufen
|
||||
4. Begründung für deine Entscheidung
|
||||
3. Falls eine Datenbankabfrage benötigt wird: Erstelle MINDESTENS 5-8 separate, vollständige, ausführbare SQL-Abfragen
|
||||
|
||||
⚠️⚠️⚠️ WICHTIG - WEB-RECHERCHE BEI ZUSÄTZLICHEN INFORMATIONEN ⚠️⚠️⚠️
|
||||
Wenn der Nutzer nach zusätzlichen Informationen fragt oder explizit eine Recherche anfordert, MUSS IMMER eine Web-Recherche durchgeführt werden (needsWebResearch = true).
|
||||
Beispiele für solche Anfragen:
|
||||
- "recherchier nach weiteren informationen zu diesem produkt"
|
||||
- "suche nach zusätzlichen informationen"
|
||||
- "finde mehr details"
|
||||
- "recherchiere im internet"
|
||||
- "suche online nach"
|
||||
- Ähnliche Formulierungen, die eine Recherche oder zusätzliche Informationen anfordern
|
||||
In diesen Fällen IMMER needsWebResearch auf true setzen!
|
||||
⚠️⚠️⚠️ KRITISCH - MINDESTENS 5-8 ABFRAGEN PARALLEL ⚠️⚠️⚠️
|
||||
- ✓ OBLIGATORISCH: Erstelle IMMER MINDESTENS 5-8 SQL-Queries
|
||||
- ✓ OBLIGATORISCH: Bei Zertifizierungen (UL, CE, TÜV, etc.) MINDESTENS 8 Queries!
|
||||
- ✓ OBLIGATORISCH: Alle Queries werden parallel ausgeführt und Ergebnisse kombiniert
|
||||
- ✓ OBLIGATORISCH: Jede Query MUSS eine andere Strategie verfolgen
|
||||
- ❌ VERBOTEN: Nur 1 Query zu erstellen - DAS IST ABSOLUT FALSCH UND WIRD ABGELEHNT!
|
||||
- ❌ VERBOTEN: Nur 2-3 Queries zu erstellen - DAS IST ZU WENIG!
|
||||
- ❌ VERBOTEN: Alle Queries mit derselben Strategie - verwende unterschiedliche Ansätze!
|
||||
|
||||
⚠️⚠️⚠️ WICHTIG - SO ERSTELLST DU DIE ABFRAGEN ⚠️⚠️⚠️
|
||||
1. SCHRITT 1: Analysiere die Anfrage und identifiziere ALLE Suchkriterien
|
||||
2. SCHRITT 2: Erstelle für JEDES Kriterium mindestens eine Query mit unterschiedlichen Strategien
|
||||
3. SCHRITT 3: Erstelle zusätzliche Queries mit kombinierten Strategien
|
||||
4. SCHRITT 4: Erstelle Fallback-Queries ohne spezifische Filter
|
||||
5. SCHRITT 5: ZÄHLE die Queries im sqlQueries-Array
|
||||
6. SCHRITT 6: Wenn weniger als 5 (oder 8 bei Zertifizierungen): ERSTELLE WEITERE QUERIES!
|
||||
|
||||
WENN DU NUR 1 QUERY ERSTELLST, IST DIE ANTWORT FALSCH UND WIRD ABGELEHNT!
|
||||
WENN DU NUR 2-3 QUERIES ERSTELLST, IST DAS ZU WENIG UND WIRD ABGELEHNT!
|
||||
|
||||
⚠️⚠️⚠️ KRITISCH - VERGLEICHSOPERATOREN ("MINDESTENS", "AT LEAST", "≥") ⚠️⚠️⚠️
|
||||
- Bei "mindestens X" MUSS JEDE Query höhere Werte einschließen
|
||||
- Beispiel: "mindestens 10A" → IMMER: (10A OR 12A OR 15A OR 16A OR 18A OR 20A OR 25A OR 30A)
|
||||
- ❌ VERBOTEN: Nur nach dem exakten Wert suchen
|
||||
- ⚠️⚠️⚠️ ABSOLUT KRITISCH - MEHRERE ABFRAGEN BEI "MINDESTENS" ⚠️⚠️⚠️
|
||||
* Wenn der Nutzer "mindestens X" sagt, MÜSSEN IMMER mehrere Datenbankabfragen erstellt werden
|
||||
* ✓ OBLIGATORISCH: Erstelle mehrere Queries mit unterschiedlichen Strategien, um ALLE passenden Artikel zu finden
|
||||
* ✓ OBLIGATORISCH: Du MUSST ALLE Artikel zurückgeben, die die Kriterien erfüllen (z.B. 10A UND 20A bei "mindestens 10A")
|
||||
* ❌ VERBOTEN: Nur eine Query zu erstellen - das würde Artikel mit höheren Werten übersehen
|
||||
* Beispiel: Bei "mindestens 10A" müssen Artikel mit 10A, 15A, 20A, 25A, etc. ALLE gefunden werden
|
||||
|
||||
⚠️⚠️⚠️ KRITISCH - ZERTIFIZIERUNGEN ERFORDERN WEB-RECHERCHE ⚠️⚠️⚠️
|
||||
- Bei Zertifizierungen (UL, CE, TÜV, VDE, etc.) IMMER needsWebResearch = true setzen
|
||||
- ❌ VERBOTEN: needsWebResearch = false bei Zertifizierungen - DAS IST FALSCH!
|
||||
- ✓ OBLIGATORISCH: Bei "UL", "UL-zertifiziert", "UL certified" IMMER needsWebResearch = true!
|
||||
- Erstelle MINDESTENS 8 progressive SQL-Queries mit unterschiedlichen Strategien
|
||||
|
||||
⚠️⚠️⚠️ OBLIGATORISCH - ERSTELLE DIESE 8 QUERIES BEI ZERTIFIZIERUNGEN ⚠️⚠️⚠️
|
||||
Bei "einphasige Netzgeräte mit mindestens 10A, UL-zertifiziert" MUSS du MINDESTENS diese 8 Queries erstellen:
|
||||
|
||||
⚠️ WICHTIG: Jede Query MUSS eine ANDERE Strategie haben! ⚠️
|
||||
|
||||
Query 1: Spezifische Suche - alle Kriterien kombiniert
|
||||
Zweck: Exakte Suche nach allen Kriterien gleichzeitig
|
||||
WHERE: (Netzgerät OR Netzteil OR Power Supply) AND (einphasig OR 1-phasig OR single phase) AND (10A OR 12A OR 15A OR 16A OR 18A OR 20A OR 25A OR 30A) AND (UL OR UL-zertifiziert)
|
||||
Suche in: Artikelbezeichnung, Artikelbeschrieb, Keywords
|
||||
Strategie: Alle Filter kombiniert
|
||||
|
||||
Query 2: Erweiterte Suche - breitere Ampere-Patterns + UL
|
||||
Zweck: Breitere Suche nach Ampere-Angaben mit UL
|
||||
WHERE: (Netzteil OR Netzgerät) AND (Ampere OR 10A OR 15A OR 20A OR 12A OR 16A OR 18A OR 25A OR 30A) AND (UL OR UL-zertifiziert)
|
||||
Suche auch nach "Ampere" als Begriff (nicht nur Zahlen)
|
||||
Strategie: Breitere Ampere-Patterns, weniger spezifisch
|
||||
|
||||
Query 3: Power Supply + single phase + UL (englische Varianten)
|
||||
Zweck: Suche mit englischen Begriffen
|
||||
WHERE: (Power Supply OR Stromversorgung) AND (single phase OR einphasig OR 1-phase) AND (10A OR 12A OR 15A OR 16A OR 18A OR 20A OR 25A OR 30A) AND (UL OR UL certified)
|
||||
Strategie: Alternative Terminologie (englisch/deutsch)
|
||||
|
||||
Query 4: Breitere UL-Suche bei Netzgeräten
|
||||
Zweck: UL-Suche ohne spezifische Ampere/Phasen-Filter
|
||||
WHERE: (UL OR UL-zertifiziert OR UL certified) AND (Netzgerät OR Netzteil OR Power Supply OR Stromversorgung)
|
||||
Suche auch in Keywords-Feld
|
||||
Strategie: Nur UL + Netzgerät, keine weiteren Filter
|
||||
|
||||
Query 5: Netzgeräte mit ≥10A ohne UL-Filter
|
||||
Zweck: Fallback falls UL nicht in DB erfasst
|
||||
WHERE: (Netzgerät OR Netzteil) AND (einphasig OR 1-phasig OR single phase) AND (10A OR 12A OR 15A OR 16A OR 18A OR 20A OR 25A OR 30A)
|
||||
Strategie: Entferne Zertifizierungsfilter komplett
|
||||
|
||||
Query 6: Zertifizierte Netzgeräte allgemein
|
||||
Zweck: Breite Suche nach allen Zertifizierungen
|
||||
WHERE: (UL OR CE OR TÜV OR certified OR zertifiziert) AND (Netzgerät OR Netzteil OR Power Supply)
|
||||
Strategie: Alle Zertifizierungen, keine spezifischen Filter
|
||||
|
||||
Query 7: COUNT-Abfrage für Statistik
|
||||
Zweck: Prüfe ob überhaupt Artikel existieren
|
||||
SELECT COUNT(*) WHERE (Netzgerät OR Netzteil) AND (10A OR 12A OR 15A OR 16A OR 18A OR 20A OR 25A OR 30A)
|
||||
Strategie: Statistik-Abfrage ohne spezifische Filter
|
||||
|
||||
Query 8: Spezifische Suche nach einphasigen Netzgeräten ohne Zertifizierung
|
||||
Zweck: Fallback ohne Zertifizierungsfilter
|
||||
WHERE: (1-Phasig OR einphasig OR single phase) AND (Netzgerät OR Netzteil OR Power Supply)
|
||||
Strategie: Nur Phasen-Filter, keine Zertifizierung, keine Ampere
|
||||
|
||||
⚠️⚠️⚠️ WICHTIG - DIESE 8 QUERIES SIND BEISPIEL ⚠️⚠️⚠️
|
||||
- Passe die Queries an die tatsächliche Anfrage an
|
||||
- Verwende die gleichen Strategien, aber mit den richtigen Begriffen
|
||||
- Jede Query muss eine ANDERE Strategie haben
|
||||
- Erstelle MINDESTENS 8 Queries, auch wenn du mehr brauchst
|
||||
|
||||
❌ VERBOTEN: Nur 1 Query zu erstellen - DAS IST ABSOLUT FALSCH!
|
||||
❌ VERBOTEN: Nur 2-3 Queries zu erstellen - DAS IST ZU WENIG!
|
||||
✓ OBLIGATORISCH: MINDESTENS 8 Queries bei Zertifizierungen!
|
||||
|
||||
⚠️⚠️⚠️ KRITISCH - ALLE ERGEBNISSE ZURÜCKGEBEN ⚠️⚠️⚠️
|
||||
- ✓ OBLIGATORISCH: Du MUSST ALLE Artikel zurückgeben, die die Kriterien erfüllen
|
||||
- ❌ VERBOTEN: Nur einen Artikel zurückgeben, wenn mehrere gefunden wurden
|
||||
|
||||
WICHTIG für SQL-Abfragen:
|
||||
- Verwende IMMER doppelte Anführungszeichen für Spaltennamen
|
||||
- Bei Lagerbestandsabfragen: IMMER S_RESERVIERTER__BESTAND und verfügbaren Bestand einbeziehen
|
||||
- Bei Lagerplatzabfragen: IMMER JOIN mit Lagerplatz-Tabelle für den Namen
|
||||
- Bei Lagerbestandsabfragen: IMMER S_RESERVIERTER__BESTAND, verfügbarer Bestand, JOIN mit Lagerplatz-Tabelle
|
||||
- Bei Lagerbestandsabfragen: IMMER breite Suche mit OR über Artikelkürzel, Artikelnummer UND Artikelbezeichnung
|
||||
- Filtere Lagerplätze mit 0 Bestand aus (außer bei Gesamtbestand oder spezifischem Lagerplatz)
|
||||
- Abfragen müssen direkt ausführbar sein (keine Platzhalter)
|
||||
- Erstelle SEPARATE Abfragen für verschiedene Tabellen/Datenquellen, nicht eine große JOIN-Abfrage
|
||||
- ⚠️ KRITISCH: Bei Lagerbestandsabfragen IMMER breite Suche mit OR über Artikelkürzel, Artikelnummer UND Artikelbezeichnung verwenden
|
||||
|
||||
STRATEGIE FÜR MEHRERE ABFRAGEN:
|
||||
- Analysiere welche Informationen benötigt werden
|
||||
- Identifiziere welche Tabellen diese Informationen enthalten
|
||||
- Erstelle für jede Tabelle/Datenquelle eine separate, fokussierte Abfrage
|
||||
- ⚠️ WICHTIG: Du kannst komplexe JOINs vermeiden, indem du mehrere einfache Abfragen parallel ausführst
|
||||
- Beispiel für "wie viel vom 1517H bundle haben wir auf lager":
|
||||
* Abfrage 1: Artikel-Informationen mit breiter Suche (Artikelkürzel, Artikelnummer, Artikelbezeichnung) aus Artikel-Tabelle
|
||||
* Abfrage 2: Lagerbestände und Lagerplätze aus Lagerplatz_Artikel + Lagerplatz-Tabellen (mit JOIN für Lagerplatznamen)
|
||||
* Diese Abfragen können parallel ausgeführt werden und die Ergebnisse werden dann kombiniert
|
||||
- ⚠️ BEI LAGERBESTANDSABFRAGEN: Eine Abfrage mit JOINs ist OK, aber stelle sicher, dass die WHERE-Bedingung eine breite Suche über alle Identifikationsfelder enthält
|
||||
⚠️⚠️⚠️ ABSOLUT KRITISCH - JSON-VALIDIERUNG - MUSS BEVOR DU DAS JSON ZURÜCKGIBST ⚠️⚠️⚠️
|
||||
DU MUSST DIESE SCHRITTE BEVOR DU DAS JSON ZURÜCKGIBST AUSFÜHREN:
|
||||
|
||||
SCHRITT 1: Zähle die Anzahl der Queries im sqlQueries-Array
|
||||
SCHRITT 2: Prüfe die Anzahl:
|
||||
- Wenn needsDatabaseQuery = true UND weniger als 5 Queries: ERSTELLE SOFORT WEITERE QUERIES!
|
||||
- Bei Zertifizierungen UND weniger als 8 Queries: ERSTELLE SOFORT WEITERE QUERIES!
|
||||
- Wenn nur 1 Query im Array: DAS IST ABSOLUT FALSCH - ERSTELLE MINDESTENS 5-8 QUERIES!
|
||||
- Wenn nur 2-3 Queries im Array: DAS IST ZU WENIG - ERSTELLE MINDESTENS 5-8 QUERIES!
|
||||
SCHRITT 3: Prüfe, ob jede Query eine andere Strategie hat
|
||||
SCHRITT 4: Wenn nicht genug Queries: ERSTELLE WEITERE QUERIES MIT ANDEREN STRATEGIEN!
|
||||
SCHRITT 5: Wiederhole SCHRITT 1-4 bis du mindestens 5-8 (oder 8 bei Zertifizierungen) Queries hast
|
||||
SCHRITT 6: ERST DANN gib das JSON zurück!
|
||||
|
||||
⚠️⚠️⚠️ BEISPIEL FÜR KORREKTE ANZAHL VON QUERIES ⚠️⚠️⚠️
|
||||
Bei einer normalen Anfrage (z.B. "Netzgeräte mit 10A"):
|
||||
- Query 1: Spezifische Suche mit allen Kriterien
|
||||
- Query 2: Breitere Suche mit alternativen Begriffen
|
||||
- Query 3: Suche nur nach Hauptkriterien
|
||||
- Query 4: COUNT-Query für Statistik
|
||||
- Query 5: Fallback-Query mit minimalen Filtern
|
||||
→ MINDESTENS 5 Queries!
|
||||
|
||||
Bei Zertifizierungen (z.B. "UL-zertifizierte Netzgeräte"):
|
||||
- Query 1-5: Wie oben
|
||||
- Query 6: UL-Suche in Keywords
|
||||
- Query 7: Zertifizierte Netzgeräte allgemein
|
||||
- Query 8: Fallback ohne Zertifizierungsfilter
|
||||
→ MINDESTENS 8 Queries!
|
||||
|
||||
Return ONLY valid JSON:
|
||||
{{
|
||||
|
|
@ -453,12 +634,22 @@ Return ONLY valid JSON:
|
|||
"sqlQueries": [
|
||||
{{
|
||||
"query": string (ready-to-execute SQL with double quotes for column names),
|
||||
"purpose": string (description of what this query retrieves, e.g., "Get product information from Artikel table"),
|
||||
"purpose": string (description of what this query retrieves),
|
||||
"table": string (primary table name, e.g., "Artikel", "Lagerplatz_Artikel")
|
||||
}}
|
||||
] (array of query objects, empty array if needsDatabaseQuery is false),
|
||||
] (array of query objects - MINDESTENS 5-8 bei komplexen Anfragen, MINDESTENS 8 bei Zertifizierungen!),
|
||||
"reasoning": string
|
||||
}}"""
|
||||
}}
|
||||
|
||||
⚠️⚠️⚠️ FINALE PRÜFUNG BEVOR DU DAS JSON ZURÜCKGIBST ⚠️⚠️⚠️
|
||||
1. Zähle die Anzahl der Queries im sqlQueries-Array: [ANZAHL]
|
||||
2. Prüfe: Ist [ANZAHL] >= 5? (Bei Zertifizierungen: >= 8?)
|
||||
3. Wenn NEIN: ERSTELLE SOFORT WEITERE QUERIES!
|
||||
4. Prüfe: Hat jede Query eine andere Strategie?
|
||||
5. Wenn NEIN: ERSTELLE QUERIES MIT ANDEREN STRATEGIEN!
|
||||
6. Wiederhole bis [ANZAHL] >= 5 (oder >= 8 bei Zertifizierungen)
|
||||
7. ERST DANN gib das JSON zurück!
|
||||
"""
|
||||
|
||||
|
||||
def get_query_needs_analysis_prompt(
|
||||
|
|
@ -532,40 +723,47 @@ def get_empty_results_retry_instructions(empty_count: int) -> str:
|
|||
return f"""
|
||||
⚠️⚠️⚠️ KRITISCH - LEERE ERGEBNISSE ERKANNT ⚠️⚠️⚠️
|
||||
|
||||
Es wurden {empty_count} Query(s) ausgeführt, die 0 Zeilen zurückgegeben haben. Dies bedeutet, dass die bisherige Query-Strategie nicht erfolgreich war.
|
||||
Es wurden {empty_count} Query(s) ausgeführt, die 0 Zeilen zurückgegeben haben. Die bisherige Query-Strategie war nicht erfolgreich.
|
||||
|
||||
DU MUSST JETZT EINE ALTERNATIVE QUERY-STRATEGIE VERSUCHEN!
|
||||
DU MUSST JETZT MEHRERE ALTERNATIVE QUERY-STRATEGIEN VERSUCHEN!
|
||||
|
||||
Verfügbare Tabellen im System:
|
||||
1. Artikel - Enthält alle Produktinformationen (I_ID, Artikelbezeichnung, Artikelnummer, etc.)
|
||||
2. Einkaufspreis - Enthält Preisdaten (m_Artikel, EP_CHF)
|
||||
3. Lagerplatz_Artikel - Enthält Lagerbestands- und Lagerplatzinformationen (R_ARTIKEL, R_LAGERPLATZ, Bestände, etc.)
|
||||
4. Lagerplatz - Enthält die tatsächlichen Lagerplatznamen und -informationen (I_ID, Lagerplatz, R_LAGER, R_LAGERORT)
|
||||
⚠️⚠️⚠️ OBLIGATORISCH - ERSTELLE MINDESTENS 5-8 ALTERNATIVE QUERIES ⚠️⚠️⚠️
|
||||
|
||||
ALTERNATIVE STRATEGIEN ZUM AUSPROBIEREN:
|
||||
Erstelle mehrere alternative SQL-Queries mit komplett anderen Strategien:
|
||||
|
||||
1. **Direkte Lagerplatz-Suche**: Prüfe zuerst, ob der Lagerplatzname in der Lagerplatz-Tabelle existiert:
|
||||
SELECT * FROM Lagerplatz WHERE "Lagerplatz" LIKE '%[Suchbegriff]%'
|
||||
|
||||
2. **Verschiedene Schreibweisen**: Versuche verschiedene Schreibweisen (Groß-/Kleinschreibung, Teilstrings):
|
||||
- UPPER/LOWER Funktionen verwenden
|
||||
- Verschiedene LIKE-Patterns: '%term%', 'term%', '%term'
|
||||
|
||||
3. **JOIN-Strategie überprüfen**: Stelle sicher, dass R_LAGERPLATZ korrekt mit Lagerplatz.I_ID gejoint wird:
|
||||
- R_LAGERPLATZ in Lagerplatz_Artikel enthält die ID (nicht den Namen!)
|
||||
- Verwende: LEFT JOIN Lagerplatz lp ON l."R_LAGERPLATZ" = lp."I_ID"
|
||||
|
||||
4. **Breitere Suche**: Versuche eine breitere Suche ohne exakte Filter:
|
||||
- Entferne zu spezifische WHERE-Bedingungen
|
||||
- Verwende OR-Bedingungen für verschiedene Suchvarianten
|
||||
|
||||
5. **Andere Tabellen zuerst**: Versuche zuerst eine einfache Abfrage auf einer einzelnen Tabelle, dann JOINs:
|
||||
- Starte mit Lagerplatz-Tabelle direkt
|
||||
- Dann JOIN mit Lagerplatz_Artikel
|
||||
- Dann JOIN mit Artikel
|
||||
1. **Breitere Suche ohne Zertifizierung**: Entferne Zertifizierungsfilter komplett
|
||||
- Beispiel: Suche nur nach Netzgerät + einphasig + 10A (ohne UL)
|
||||
- Suche in Artikelbezeichnung, Artikelbeschrieb, Keywords
|
||||
|
||||
WICHTIG: Wenn alle bisherigen Queries 0 Zeilen zurückgegeben haben, MUSS eine alternative Query-Strategie versucht werden!
|
||||
Erstelle eine neue Query, die eine der oben genannten Strategien verwendet. Versuche verschiedene Ansätze, bis Ergebnisse gefunden werden.
|
||||
2. **Erweiterte Suche nach Netzgeräten mit Ampere-Angaben**: Breitere Ampere-Patterns
|
||||
- Beispiel: (Netzteil OR Netzgerät) AND (10A OR 15A OR 20A OR Ampere)
|
||||
- Suche auch nach "Ampere" als Begriff, nicht nur Zahlen
|
||||
|
||||
3. **Breitere UL-Suche bei Netzgeräten**: Suche UL in allen Feldern
|
||||
- Beispiel: (UL OR UL-zertifiziert) AND (Netzgerät OR Netzteil OR Power Supply)
|
||||
- Suche auch in Keywords-Feld
|
||||
|
||||
4. **Netzgeräte mit ≥10A ohne weitere Filter**: Minimaler Filter
|
||||
- Beispiel: (Netzgerät OR Netzteil) AND (10A OR 15A OR 20A)
|
||||
- Keine Filter auf einphasig oder Zertifizierung
|
||||
|
||||
5. **Zertifizierte Netzgeräte allgemein**: Breite Zertifizierungs-Suche
|
||||
- Beispiel: (UL OR CE OR TÜV OR certified OR zertifiziert) AND (Netzgerät OR Netzteil)
|
||||
|
||||
6. **COUNT-Abfrage für Statistik**: Prüfe ob überhaupt Artikel existieren
|
||||
- SELECT COUNT(*) WHERE (Netzgerät OR Netzteil) AND (10A OR 15A OR 20A)
|
||||
|
||||
7. **Spezifische Suche nach einphasigen Netzgeräten**: Ohne Zertifizierung
|
||||
- Beispiel: (einphasig OR 1-phasig OR single phase) AND (Netzgerät OR Netzteil)
|
||||
|
||||
8. **Fallback mit minimalen Filtern**: Nur Hauptkriterien
|
||||
- Beispiel: Netzgerät AND (10A OR 15A OR 20A) - keine weiteren Filter
|
||||
|
||||
WICHTIG:
|
||||
- Erstelle IMMER mehrere Queries (mindestens 5-8) mit unterschiedlichen Strategien
|
||||
- Verwende breitere OR-Bedingungen für alternative Begriffe
|
||||
- Entferne zu spezifische Filter, die möglicherweise keine Treffer finden
|
||||
- Suche in Artikelbezeichnung, Artikelbeschrieb UND Keywords-Feld
|
||||
"""
|
||||
|
||||
|
||||
|
|
@ -607,10 +805,18 @@ WICHTIGSTE REGELN - ABSOLUT VERBINDLICH:
|
|||
- Einkaufspreis: [Wert aus Datenbank oder "Nicht verfügbar"]
|
||||
|
||||
Lagerbestände nach Lagerplätzen
|
||||
[Tabelle mit ALLEN Lagerplätzen aus den Daten]
|
||||
[Tabelle mit Lagerplätzen - ⚠️ WICHTIG: Nur Lagerplätze mit verfügbarem Bestand > 0 zeigen!]
|
||||
Lagerplatz | Ist-Bestand | Soll-Bestand | Min-Bestand | Max-Bestand | Reservierter Bestand | Verfügbarer Bestand
|
||||
|
||||
Gesamtbestand: [Summe aller Ist-Bestände] Stück (alle am Lagerplatz "[Lagerplatzname]")
|
||||
⚠️⚠️⚠️ KRITISCH - LAGERPLÄTZE MIT 0 BESTAND FILTERN ⚠️⚠️⚠️
|
||||
- STANDARDREGEL: Zeige NUR Lagerplätze mit verfügbarem Bestand > 0
|
||||
- FILTERE Lagerplätze mit S_IST_BESTAND = 0 oder verfügbarer Bestand = 0 AUS
|
||||
- AUSNAHMEN - Zeige Lagerplätze mit 0 Bestand WENN:
|
||||
* Der Nutzer explizit nach dem GESAMTLAGERBESTAND fragt
|
||||
* Der Nutzer nach einem SPEZIFISCHEN LAGERPLATZ fragt
|
||||
* Der Nutzer explizit nach "0 Bestand" oder "leeren Lagerplätzen" fragt
|
||||
|
||||
Gesamtbestand: [Summe aller Ist-Bestände] Stück (nur Lagerplätze mit Bestand > 0, außer bei Ausnahmen)
|
||||
|
||||
Möchten Sie:
|
||||
- Mehr technische Details zu diesem Artikel erfahren?
|
||||
|
|
@ -618,8 +824,9 @@ WICHTIGSTE REGELN - ABSOLUT VERBINDLICH:
|
|||
- Informationen zu anderen Artikeln im Lager anzeigen?
|
||||
- Den aktuellen Preis oder Lieferzeiten prüfen?
|
||||
|
||||
3. STELLE SICHER, DASS ALLE LAGERPLÄTZE ANGEZEIGT WERDEN
|
||||
- Wenn mehrere Lagerplätze vorhanden sind, zeige ALLE in der Tabelle
|
||||
3. STELLE SICHER, DASS NUR RELEVANTE LAGERPLÄTZE ANGEZEIGT WERDEN
|
||||
- Zeige NUR Lagerplätze mit verfügbarem Bestand > 0 (außer bei Ausnahmen)
|
||||
- Wenn alle Lagerplätze 0 Bestand haben: Zeige entsprechende Nachricht statt leerer Tabelle
|
||||
- Gruppiere nicht - zeige jeden Lagerplatz als separate Zeile
|
||||
|
||||
4. VERWENDE NUR DIE TATSÄCHLICHEN WERTE
|
||||
|
|
@ -810,26 +1017,36 @@ Antworte auf die folgende Frage des Nutzers: {user_prompt}{context}
|
|||
|
||||
KRITISCH: Verwende NUR die oben angegebenen Daten. Erfinde KEINE Werte. Wenn Daten fehlen, schreibe "Nicht verfügbar".
|
||||
|
||||
WICHTIG - MEHRERE ABFRAGEN:
|
||||
Die oben angegebenen DATENBANK-ERGEBNISSE können aus mehreren separaten Abfragen stammen. Jede Abfrage ist mit "=== Abfrage X ===" markiert und enthält Informationen zu einem spezifischen Aspekt (z.B. Artikel-Informationen, Lagerbestände, etc.).
|
||||
- Kombiniere die Informationen aus ALLEN erfolgreichen Abfragen zu einer umfassenden Antwort
|
||||
- Beispiel: Wenn Abfrage 1 Artikel-Informationen liefert und Abfrage 2 Lagerbestände liefert, kombiniere beide in deiner Antwort
|
||||
- Verwende ALLE verfügbaren Informationen aus den verschiedenen Abfragen
|
||||
⚠️⚠️⚠️ ABSOLUT KRITISCH - ALLE ARTIKEL ZURÜCKGEBEN ⚠️⚠️⚠️
|
||||
- ✓ OBLIGATORISCH: Du MUSST ALLE Artikel zurückgeben, die die Kriterien erfüllen
|
||||
- ✓ OBLIGATORISCH: Kombiniere Ergebnisse aus ALLEN erfolgreichen Abfragen
|
||||
- ✓ OBLIGATORISCH: Zähle ALLE Artikel in den DATENBANK-ERGEBNISSEN oben
|
||||
- ✓ OBLIGATORISCH: Zeige ALLE gefundenen Artikel in deiner Antwort (bis zu 20 in der Tabelle)
|
||||
- ❌ ABSOLUT VERBOTEN: Nur einen Artikel zurückgeben, wenn mehrere gefunden wurden
|
||||
- ❌ ABSOLUT VERBOTEN: Nur den ersten Artikel zeigen
|
||||
- ❌ ABSOLUT VERBOTEN: Artikel auslassen, die in den DATENBANK-ERGEBNISSEN stehen
|
||||
- Beispiel: Wenn 10 Artikel in den DATENBANK-ERGEBNISSEN stehen, MUSST du alle 10 zeigen!
|
||||
|
||||
⚠️⚠️⚠️ SCHRITT-FÜR-SCHRITT ANWEISUNG ⚠️⚠️⚠️
|
||||
BEVOR du deine Antwort schreibst:
|
||||
1. Zähle ALLE Artikel in den DATENBANK-ERGEBNISSEN oben
|
||||
2. Notiere diese Anzahl (z.B. "10 Artikel gefunden")
|
||||
3. Stelle sicher, dass du ALLE diese Artikel in deiner Antwort zeigst
|
||||
4. Wenn weniger als 20 Artikel: Zeige ALLE in einer Tabelle
|
||||
5. Wenn mehr als 20 Artikel: Zeige die ersten 20 + Hinweis auf weitere
|
||||
|
||||
⚠️⚠️⚠️ VALIDIERUNG BEVOR DU DIE ANTWORT ZURÜCKGIBST ⚠️⚠️⚠️
|
||||
- Prüfe: Zeige ich ALLE Artikel, die in den DATENBANK-ERGEBNISSEN stehen?
|
||||
- Prüfe: Wenn 10 Artikel gefunden wurden, zeige ich auch 10 Artikel?
|
||||
- Wenn NEIN: Füge die fehlenden Artikel hinzu!
|
||||
|
||||
⚠️⚠️⚠️ ABSOLUT VERBOTEN - KEINE DATEN ERFINDEN ⚠️⚠️⚠️
|
||||
Wenn KEINE Datenbank-Ergebnisse vorhanden sind, dann:
|
||||
- ❌ ERFINDE KEINE Artikelnummern, Artikelbezeichnungen, Preise oder Lagerbestände!
|
||||
- ❌ ERFINDE KEINE Beispielartikel!
|
||||
- ✓ Schreibe stattdessen: "Es wurden keine Artikel in der Datenbank gefunden." oder "Die Datenbankabfrage ist fehlgeschlagen."
|
||||
|
||||
WICHTIG: Deine Antwort soll NUR die finale Antwort enthalten - KEINE Planungsschritte, KEINE SQL-Queries, KEINE Zwischenschritte!
|
||||
Beginne DIREKT mit "Aus der Datenbank habe ich..." (wenn Daten vorhanden) oder "Es wurden keine Artikel gefunden" (wenn keine Daten vorhanden).
|
||||
- ❌ VERBOTEN: Artikelnummern, Preise, Bestände erfinden
|
||||
- ✓ RICHTIG: Wenn keine Daten: "Es wurden keine Artikel gefunden"
|
||||
|
||||
WICHTIG:
|
||||
- Beginne DIREKT mit "Aus der Datenbank habe ich..." (keine Planungsschritte!)
|
||||
- Klare, strukturierte Antwort
|
||||
- Zahlen mit Tausender-Trennzeichen (7'411)
|
||||
- Markdown-Tabellen für Daten (max 20 Zeilen)
|
||||
- Artikelnummern als Link: [ARTIKELNUMMER](/details/ARTIKELNUMMER)
|
||||
- Wenn Excel-Datei erstellt wurde, bestätige dies explizit am Ende
|
||||
- Wenn Excel-Verarbeitung fehlgeschlagen ist, erkläre dem Nutzer den Fehler klar"""
|
||||
- Markdown-Tabellen (max 20 Zeilen)
|
||||
- Artikelnummern als Link: [ARTIKELNUMMER](/details/ARTIKELNUMMER)"""
|
||||
|
||||
|
|
|
|||
|
|
@ -406,9 +406,19 @@ def _buildWebResearchQuery(userPrompt: str, workflowMessages: List, queryResults
|
|||
"weitere informationen", "further information", "additional information"
|
||||
]
|
||||
|
||||
# Certification patterns that require web research
|
||||
certification_patterns = [
|
||||
"ul", "ce", "tüv", "vde", "iec", "en", "iso",
|
||||
"zertifiziert", "certified", "certification", "zertifizierung",
|
||||
"geprüft", "approved", "compliance"
|
||||
]
|
||||
|
||||
# Check if current prompt contains search-related keywords
|
||||
has_search_intent = any(pattern in prompt_lower for pattern in search_patterns)
|
||||
|
||||
# Check if prompt contains certification-related keywords
|
||||
has_certification_intent = any(pattern in prompt_lower for pattern in certification_patterns)
|
||||
|
||||
# Extract product information - try multiple sources
|
||||
article_number = None
|
||||
article_description = None
|
||||
|
|
@ -562,6 +572,30 @@ def _buildWebResearchQuery(userPrompt: str, workflowMessages: List, queryResults
|
|||
if supplier:
|
||||
query_parts.append(supplier)
|
||||
|
||||
# Extract certification information from prompt if present
|
||||
certification_terms = []
|
||||
if has_certification_intent:
|
||||
# Extract specific certification mentions
|
||||
cert_keywords = {
|
||||
"ul": "UL certification",
|
||||
"ce": "CE certification",
|
||||
"tüv": "TÜV certification",
|
||||
"vde": "VDE certification",
|
||||
"iec": "IEC certification",
|
||||
"iso": "ISO certification"
|
||||
}
|
||||
for cert_key, cert_term in cert_keywords.items():
|
||||
if cert_key in prompt_lower:
|
||||
certification_terms.append(cert_term)
|
||||
|
||||
# If no specific certification found but certification intent detected, add generic term
|
||||
if not certification_terms:
|
||||
certification_terms.append("certification")
|
||||
|
||||
# Add certification terms to query if found
|
||||
if certification_terms:
|
||||
query_parts.extend(certification_terms)
|
||||
|
||||
# Add "Datenblatt" or "datasheet" if user requested it or if we have product info
|
||||
if "datenblatt" in prompt_lower or "datasheet" in prompt_lower or "fiche technique" in prompt_lower:
|
||||
query_parts.append("Datenblatt")
|
||||
|
|
@ -873,6 +907,117 @@ async def _processChatbotMessage(
|
|||
}]
|
||||
reasoning = analysis.get("reasoning", "")
|
||||
|
||||
# Check if we need web research for certifications
|
||||
user_prompt_lower = userInput.prompt.lower()
|
||||
certification_keywords = ["ul", "ce", "tüv", "vde", "iec", "iso", "zertifiziert", "certified", "certification"]
|
||||
has_certification = any(keyword in user_prompt_lower for keyword in certification_keywords)
|
||||
if has_certification and not needsWebResearch:
|
||||
logger.warning("Certification detected but needsWebResearch is false - forcing to true")
|
||||
needsWebResearch = True
|
||||
|
||||
# Validate query count - retry if too few queries (iterative retry up to 3 attempts)
|
||||
min_queries_required = 8 if has_certification else 5
|
||||
max_retry_attempts = 3
|
||||
retry_attempt = 0
|
||||
|
||||
while needsDatabaseQuery and len(sql_queries) < min_queries_required and retry_attempt < max_retry_attempts:
|
||||
retry_attempt += 1
|
||||
logger.warning(f"Only {len(sql_queries)} queries created, but {min_queries_required} required. Retry attempt {retry_attempt}/{max_retry_attempts}...")
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"Zu wenige Abfragen erstellt ({len(sql_queries)} statt {min_queries_required}). Versuch {retry_attempt}/{max_retry_attempts}: Erstelle alternative Strategien...",
|
||||
log_type="warning"
|
||||
)
|
||||
|
||||
# Build progressively stronger retry prompt
|
||||
retry_context = f"{context}\n\n"
|
||||
if retry_attempt == 1:
|
||||
retry_context += "⚠️⚠️⚠️ KRITISCH - ZU WENIGE ABFRAGEN ERSTELLT ⚠️⚠️⚠️\n"
|
||||
elif retry_attempt == 2:
|
||||
retry_context += "⚠️⚠️⚠️ ABSOLUT KRITISCH - IMMER NOCH ZU WENIGE ABFRAGEN ⚠️⚠️⚠️\n"
|
||||
else:
|
||||
retry_context += "⚠️⚠️⚠️ LETZTER VERSUCH - DU MUSST JETZT MINDESTENS 5-8 ABFRAGEN ERSTELLEN ⚠️⚠️⚠️\n"
|
||||
|
||||
retry_context += f"Du hast nur {len(sql_queries)} Abfrage(n) erstellt, aber es werden MINDESTENS {min_queries_required} benötigt!\n"
|
||||
retry_context += f"Dies ist bereits Versuch {retry_attempt} von {max_retry_attempts}!\n"
|
||||
retry_context += "ERSTELLE JETZT MINDESTENS 5-8 ABFRAGEN MIT VERSCHIEDENEN STRATEGIEN!\n"
|
||||
retry_context += "JEDE Query muss eine ANDERE Strategie verfolgen:\n"
|
||||
retry_context += "- Query 1: Spezifische Suche mit allen Kriterien\n"
|
||||
retry_context += "- Query 2: Breitere Suche mit alternativen Begriffen\n"
|
||||
retry_context += "- Query 3: Suche ohne Zertifizierungsfilter\n"
|
||||
retry_context += "- Query 4: Suche nur nach Hauptkriterien\n"
|
||||
retry_context += "- Query 5: COUNT-Query für Statistik\n"
|
||||
if has_certification:
|
||||
retry_context += "- Query 6: UL-Suche in Keywords\n"
|
||||
retry_context += "- Query 7: Zertifizierte Netzgeräte allgemein\n"
|
||||
retry_context += "- Query 8: Fallback mit minimalen Filtern\n"
|
||||
retry_context += "\n⚠️ ABSOLUT VERBOTEN: Nur 1 Query zu erstellen! ⚠️\n"
|
||||
retry_context += "⚠️ ABSOLUT VERBOTEN: Alle Queries mit derselben Strategie! ⚠️\n"
|
||||
retry_context += "⚠️ BEVOR DU DAS JSON ZURÜCKGIBST: Zähle die Queries im sqlQueries-Array! ⚠️\n"
|
||||
retry_context += "⚠️ WENN WENIGER ALS 8: ERSTELLE WEITERE QUERIES! ⚠️\n"
|
||||
|
||||
retry_analysis_prompt = get_initial_analysis_prompt(userInput.prompt, retry_context)
|
||||
retry_analysis_result = await method_ai.process({
|
||||
"aiPrompt": retry_analysis_prompt,
|
||||
"documentList": None,
|
||||
"resultType": "json",
|
||||
"simpleMode": True
|
||||
})
|
||||
|
||||
retry_analysis_content = None
|
||||
if retry_analysis_result.success and retry_analysis_result.documents:
|
||||
retry_analysis_content = retry_analysis_result.documents[0].documentData
|
||||
if isinstance(retry_analysis_content, bytes):
|
||||
retry_analysis_content = retry_analysis_content.decode('utf-8')
|
||||
|
||||
if retry_analysis_content:
|
||||
retry_analysis = _extractJsonFromResponse(retry_analysis_content)
|
||||
if retry_analysis:
|
||||
retry_needsDatabaseQuery = retry_analysis.get("needsDatabaseQuery", False)
|
||||
retry_needsWebResearch = retry_analysis.get("needsWebResearch", False)
|
||||
retry_sql_queries = retry_analysis.get("sqlQueries", [])
|
||||
|
||||
logger.info(f"Retry attempt {retry_attempt}: Got {len(retry_sql_queries)} queries (required: {min_queries_required})")
|
||||
|
||||
if retry_needsDatabaseQuery and len(retry_sql_queries) >= min_queries_required:
|
||||
logger.info(f"Retry successful: {len(retry_sql_queries)} queries created")
|
||||
needsDatabaseQuery = retry_needsDatabaseQuery
|
||||
needsWebResearch = retry_needsWebResearch or needsWebResearch # Keep web research if already set
|
||||
sql_queries = retry_sql_queries
|
||||
reasoning = retry_analysis.get("reasoning", reasoning)
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"Alternative Strategie erfolgreich: {len(sql_queries)} Abfrage(n) erstellt",
|
||||
log_type="info"
|
||||
)
|
||||
break # Success, exit retry loop
|
||||
else:
|
||||
logger.warning(f"Retry attempt {retry_attempt} still insufficient: {len(retry_sql_queries)} queries (required: {min_queries_required})")
|
||||
# Update sql_queries even if insufficient, so next iteration has context
|
||||
if retry_needsDatabaseQuery and len(retry_sql_queries) > len(sql_queries):
|
||||
sql_queries = retry_sql_queries
|
||||
needsDatabaseQuery = retry_needsDatabaseQuery
|
||||
needsWebResearch = retry_needsWebResearch or needsWebResearch
|
||||
else:
|
||||
logger.warning(f"Retry attempt {retry_attempt}: Failed to parse JSON response")
|
||||
else:
|
||||
logger.warning(f"Retry attempt {retry_attempt}: No content in response")
|
||||
|
||||
# Final check: if still insufficient after all retries, log warning but continue
|
||||
if needsDatabaseQuery and len(sql_queries) < min_queries_required:
|
||||
logger.error(f"CRITICAL: After {max_retry_attempts} retry attempts, only {len(sql_queries)} queries created (required: {min_queries_required}). Continuing with insufficient queries.")
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"⚠️ WARNUNG: Nach {max_retry_attempts} Versuchen nur {len(sql_queries)} Abfrage(n) erstellt (benötigt: {min_queries_required}). Setze mit reduzierten Abfragen fort.",
|
||||
log_type="warning"
|
||||
)
|
||||
|
||||
logger.info(f"Analysis: DB={needsDatabaseQuery}, Web={needsWebResearch}, SQL queries={len(sql_queries)}")
|
||||
|
||||
# Build initial enriched web research query if needed (for logging, will be rebuilt after DB queries)
|
||||
|
|
@ -964,6 +1109,208 @@ async def _processChatbotMessage(
|
|||
f"Warnung: {len(failed_queries)} Abfrage(n) fehlgeschlagen",
|
||||
log_type="warning"
|
||||
)
|
||||
|
||||
# Check if we got empty results and need to retry with alternative strategies
|
||||
# Robust calculation: check all successful queries for empty data
|
||||
total_rows = 0
|
||||
queries_with_results = 0
|
||||
queries_with_empty_results = 0
|
||||
|
||||
if successful_queries:
|
||||
for query_key in successful_queries:
|
||||
data_key = f"{query_key}_data"
|
||||
if data_key in queryResults:
|
||||
row_count = len(queryResults[data_key])
|
||||
total_rows += row_count
|
||||
if row_count > 0:
|
||||
queries_with_results += 1
|
||||
else:
|
||||
queries_with_empty_results += 1
|
||||
else:
|
||||
# Query succeeded but no data key - treat as empty
|
||||
queries_with_empty_results += 1
|
||||
logger.debug(f"Query {query_key} succeeded but has no _data key")
|
||||
else:
|
||||
# No successful queries at all
|
||||
logger.debug("No successful queries found")
|
||||
|
||||
# Also check if we have any query results at all
|
||||
has_any_results = total_rows > 0
|
||||
|
||||
# Debug logging
|
||||
logger.info(f"Query results analysis: total_rows={total_rows}, successful_queries={len(successful_queries)}, "
|
||||
f"queries_with_results={queries_with_results}, queries_with_empty_results={queries_with_empty_results}, "
|
||||
f"failed_queries={len(failed_queries)}")
|
||||
|
||||
# Trigger retry if: no results AND we have database queries AND we executed at least one query
|
||||
# Also trigger if all successful queries returned empty results
|
||||
should_retry = (
|
||||
not has_any_results and
|
||||
needsDatabaseQuery and
|
||||
len(sql_queries) > 0 and
|
||||
(len(successful_queries) > 0 or len(failed_queries) == 0) # Either we have successful queries or no failures (queries executed but empty)
|
||||
)
|
||||
|
||||
# Iterative retry loop: try up to 3 times with different strategies
|
||||
max_empty_retry_attempts = 3
|
||||
empty_retry_attempt = 0
|
||||
original_sql_queries_count = len(sql_queries)
|
||||
|
||||
while should_retry and empty_retry_attempt < max_empty_retry_attempts:
|
||||
empty_retry_attempt += 1
|
||||
logger.info(f"No results found (attempt {empty_retry_attempt}/{max_empty_retry_attempts}), retrying with alternative query strategies...")
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"Keine Ergebnisse gefunden ({len(successful_queries)} erfolgreiche Abfrage(n), {total_rows} Zeilen). Versuch {empty_retry_attempt}/{max_empty_retry_attempts}: Versuche alternative Abfrage-Strategien...",
|
||||
log_type="info"
|
||||
)
|
||||
|
||||
# Retry analysis with empty results context - create NEW analysis with alternative strategies
|
||||
from modules.features.chatbot.chatbotConstants import get_empty_results_retry_instructions
|
||||
|
||||
# Build retry prompt with progressively different strategies
|
||||
empty_count = len(sql_queries)
|
||||
empty_results_instructions = get_empty_results_retry_instructions(empty_count)
|
||||
|
||||
retry_context = f"{context}\n\n"
|
||||
if empty_retry_attempt == 1:
|
||||
retry_context += "⚠️⚠️⚠️ WICHTIG - ALTERNATIVE STRATEGIEN ERFORDERLICH ⚠️⚠️⚠️\n"
|
||||
retry_context += "Strategie: Breitere Suche, weniger Filter\n"
|
||||
elif empty_retry_attempt == 2:
|
||||
retry_context += "⚠️⚠️⚠️ KRITISCH - IMMER NOCH KEINE ERGEBNISSE ⚠️⚠️⚠️\n"
|
||||
retry_context += "Strategie: Entferne spezifische Filter komplett, verwende nur Hauptkriterien\n"
|
||||
else:
|
||||
retry_context += "⚠️⚠️⚠️ LETZTER VERSUCH - MINIMALE FILTER ⚠️⚠️⚠️\n"
|
||||
retry_context += "Strategie: Nur Hauptbegriffe, keine spezifischen Filter\n"
|
||||
|
||||
retry_context += f"Die bisherigen {len(sql_queries)} Abfragen haben 0 Zeilen zurückgegeben.\n"
|
||||
retry_context += f"{empty_results_instructions}\n"
|
||||
retry_context += f"Dies ist bereits Versuch {empty_retry_attempt} von {max_empty_retry_attempts}!\n"
|
||||
retry_context += "Erstelle JETZT mehrere alternative SQL-Queries (mindestens 5-8) mit komplett anderen Strategien:\n"
|
||||
|
||||
if empty_retry_attempt == 1:
|
||||
retry_context += "- Breitere Suche ohne zu spezifische Filter\n"
|
||||
retry_context += "- Suche ohne Zertifizierungsfilter (falls Zertifizierung nicht in DB)\n"
|
||||
retry_context += "- Suche nur nach Hauptkriterien (z.B. nur Netzgerät + 10A, ohne einphasig)\n"
|
||||
retry_context += "- Suche nach alternativen Begriffen (Netzteil statt Netzgerät, etc.)\n"
|
||||
retry_context += "- COUNT-Queries für Statistik\n"
|
||||
retry_context += "- Fallback-Queries mit minimalen Filtern\n"
|
||||
elif empty_retry_attempt == 2:
|
||||
retry_context += "- ENTFERNE alle Zertifizierungsfilter komplett\n"
|
||||
retry_context += "- ENTFERNE Phasen-Filter (einphasig/dreiphasig)\n"
|
||||
retry_context += "- Suche NUR nach: Netzgerät/Netzteil + Ampere-Angaben\n"
|
||||
retry_context += "- Verwende breitere Ampere-Patterns (5A, 6A, 8A, 10A, 12A, 15A, 20A, etc.)\n"
|
||||
retry_context += "- Suche auch in Keywords-Feld\n"
|
||||
else:
|
||||
retry_context += "- MINIMALE Filter: Nur 'Netzgerät' ODER 'Netzteil' ODER 'Power Supply'\n"
|
||||
retry_context += "- KEINE spezifischen Filter auf Ampere, Phasen oder Zertifizierung\n"
|
||||
retry_context += "- COUNT-Query: Wie viele Netzgeräte gibt es insgesamt?\n"
|
||||
retry_context += "- Suche nach ALLEN verfügbaren Netzgeräten\n"
|
||||
|
||||
retry_analysis_prompt = get_initial_analysis_prompt(userInput.prompt, retry_context)
|
||||
|
||||
# AI call for retry analysis
|
||||
retry_analysis_result = await method_ai.process({
|
||||
"aiPrompt": retry_analysis_prompt,
|
||||
"documentList": None,
|
||||
"resultType": "json",
|
||||
"simpleMode": True
|
||||
})
|
||||
|
||||
# Extract retry analysis
|
||||
retry_analysis_content = None
|
||||
if retry_analysis_result.success and retry_analysis_result.documents:
|
||||
retry_analysis_content = retry_analysis_result.documents[0].documentData
|
||||
if isinstance(retry_analysis_content, bytes):
|
||||
retry_analysis_content = retry_analysis_content.decode('utf-8')
|
||||
|
||||
if retry_analysis_content:
|
||||
retry_analysis = _extractJsonFromResponse(retry_analysis_content)
|
||||
if retry_analysis and retry_analysis.get("needsDatabaseQuery", False):
|
||||
retry_sql_queries = retry_analysis.get("sqlQueries", [])
|
||||
if retry_sql_queries:
|
||||
logger.info(f"Executing {len(retry_sql_queries)} retry queries (attempt {empty_retry_attempt}) with alternative strategies...")
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"Führe {len(retry_sql_queries)} alternative Abfrage(n) mit anderen Strategien aus (Versuch {empty_retry_attempt})...",
|
||||
log_type="info"
|
||||
)
|
||||
|
||||
# Execute retry queries
|
||||
try:
|
||||
retry_results = await _execute_queries_parallel(retry_sql_queries)
|
||||
|
||||
# Merge retry results into main results (renumber to continue sequence)
|
||||
base_query_num = len(sql_queries)
|
||||
for key, value in retry_results.items():
|
||||
if key.startswith("query_"):
|
||||
# Extract query number from retry result
|
||||
try:
|
||||
query_num = int(key.split("_")[1])
|
||||
new_query_num = base_query_num + query_num
|
||||
new_key = f"query_{new_query_num}"
|
||||
|
||||
if not key.endswith("_data") and not key.endswith("_error"):
|
||||
queryResults[new_key] = value
|
||||
if f"{key}_data" in retry_results:
|
||||
queryResults[f"{new_key}_data"] = retry_results[f"{key}_data"]
|
||||
elif key.endswith("_error"):
|
||||
queryResults[f"{new_key}_error"] = value
|
||||
except (ValueError, IndexError):
|
||||
# Fallback if parsing fails
|
||||
new_key = f"query_{base_query_num + 1}"
|
||||
if not key.endswith("_data") and not key.endswith("_error"):
|
||||
queryResults[new_key] = value
|
||||
|
||||
# Recalculate results after retry
|
||||
retry_successful = [k for k in retry_results.keys() if k.startswith("query_") and not k.endswith("_error") and not k.endswith("_data")]
|
||||
retry_rows = sum(len(retry_results.get(f"{k}_data", [])) for k in retry_successful) if retry_successful else 0
|
||||
|
||||
# Update successful_queries list to include retry results
|
||||
successful_queries = [k for k in queryResults.keys() if k.startswith("query_") and not k.endswith("_error") and not k.endswith("_data")]
|
||||
total_rows = sum(len(queryResults.get(f"{k}_data", [])) for k in successful_queries)
|
||||
|
||||
logger.info(f"Retry attempt {empty_retry_attempt}: Found {retry_rows} rows from {len(retry_successful)} queries. Total: {total_rows} rows from {len(successful_queries)} queries")
|
||||
|
||||
if retry_rows > 0:
|
||||
# Success! Found results
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"Alternative Abfragen erfolgreich: {len(retry_successful)} Abfrage(n) mit {retry_rows} Ergebnis{'en' if retry_rows != 1 else ''} gefunden",
|
||||
log_type="info"
|
||||
)
|
||||
should_retry = False # Stop retry loop, we found results
|
||||
break
|
||||
else:
|
||||
# Still no results, continue to next attempt
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"Versuch {empty_retry_attempt}: Immer noch keine Ergebnisse. Versuche nächste Strategie...",
|
||||
log_type="warning"
|
||||
)
|
||||
except Exception as retry_error:
|
||||
logger.error(f"Error executing retry queries (attempt {empty_retry_attempt}): {retry_error}", exc_info=True)
|
||||
# Continue to next attempt even on error
|
||||
|
||||
# Check if we should continue retrying
|
||||
if empty_retry_attempt >= max_empty_retry_attempts:
|
||||
logger.warning(f"Reached maximum empty retry attempts ({max_empty_retry_attempts}), stopping retry loop")
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"⚠️ Maximale Anzahl Retry-Versuche ({max_empty_retry_attempts}) erreicht. Keine Ergebnisse gefunden.",
|
||||
log_type="warning"
|
||||
)
|
||||
should_retry = False
|
||||
except Exception as e:
|
||||
logger.error(f"Error executing parallel queries: {e}")
|
||||
queryResults["error"] = f"Error executing queries: {str(e)}"
|
||||
|
|
@ -1088,6 +1435,35 @@ async def _processChatbotMessage(
|
|||
error_query_keys = [k for k in queryResults.keys() if k.endswith("_error")]
|
||||
has_only_errors = bool(error_query_keys and not successful_query_keys)
|
||||
|
||||
# Count total number of articles found across all queries
|
||||
total_articles_found = 0
|
||||
if successful_query_keys:
|
||||
for query_key in successful_query_keys:
|
||||
data_key = f"{query_key}_data"
|
||||
if data_key in queryResults:
|
||||
article_count = len(queryResults[data_key])
|
||||
total_articles_found += article_count
|
||||
logger.info(f"Query {query_key} returned {article_count} articles")
|
||||
|
||||
logger.info(f"Total articles found across all queries: {total_articles_found}")
|
||||
|
||||
# Add explicit article count information to prompt
|
||||
if total_articles_found > 0:
|
||||
article_count_info = f"\n\n⚠️⚠️⚠️ WICHTIG - ARTIKELANZAHL ⚠️⚠️⚠️\n"
|
||||
article_count_info += f"In den DATENBANK-ERGEBNISSEN oben wurden INSGESAMT {total_articles_found} Artikel gefunden.\n"
|
||||
article_count_info += f"DU MUSST ALLE {total_articles_found} Artikel in deiner Antwort zeigen!\n"
|
||||
if total_articles_found <= 20:
|
||||
article_count_info += f"Zeige ALLE {total_articles_found} Artikel in einer Tabelle.\n"
|
||||
else:
|
||||
article_count_info += f"Zeige die ersten 20 Artikel in einer Tabelle + Hinweis auf weitere {total_articles_found - 20} Artikel.\n"
|
||||
article_count_info += f"❌ VERBOTEN: Nur einen Artikel zu zeigen, wenn {total_articles_found} gefunden wurden!\n"
|
||||
article_count_info += f"✓ OBLIGATORISCH: Zeige ALLE {total_articles_found} Artikel!\n"
|
||||
|
||||
if db_results_part:
|
||||
db_results_part = article_count_info + db_results_part
|
||||
else:
|
||||
db_results_part = article_count_info
|
||||
|
||||
# Add warning messages if needed
|
||||
if not has_query_results and needsDatabaseQuery:
|
||||
if db_results_part:
|
||||
|
|
|
|||
Loading…
Reference in a new issue