fix:performance optimization
This commit is contained in:
parent
583525a151
commit
378128c3ce
2 changed files with 174 additions and 339 deletions
|
|
@ -14,15 +14,28 @@ from modules.datamodels.datamodelAi import AiCallRequest, AiCallOptions, Operati
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Cache for system prompts to avoid regenerating on every request
|
||||
_cached_analysis_prompt = None
|
||||
_cached_analysis_prompt_date = None
|
||||
_cached_final_answer_prompt = None
|
||||
_cached_final_answer_prompt_date = None
|
||||
|
||||
|
||||
def get_analysis_system_prompt() -> str:
|
||||
"""
|
||||
Get the system prompt for analyzing user input and creating queries.
|
||||
Focuses on understanding the question and determining what queries are needed.
|
||||
Uses caching to avoid regenerating the prompt on every request.
|
||||
"""
|
||||
global _cached_analysis_prompt, _cached_analysis_prompt_date
|
||||
current_date = datetime.datetime.now().strftime("%d.%m.%Y")
|
||||
|
||||
return f"""Heute ist der {current_date}.
|
||||
# Return cached prompt if date hasn't changed
|
||||
if _cached_analysis_prompt is not None and _cached_analysis_prompt_date == current_date:
|
||||
return _cached_analysis_prompt
|
||||
|
||||
# Regenerate prompt (only when date changes)
|
||||
_cached_analysis_prompt = f"""Heute ist der {current_date}.
|
||||
|
||||
Du bist ein Chatbot der Althaus AG.
|
||||
Deine Aufgabe ist es, Benutzeranfragen zu analysieren und zu bestimmen, welche Datenbankabfragen oder Web-Recherchen benötigt werden, um die Frage zu beantworten.
|
||||
|
|
@ -288,16 +301,27 @@ WICHTIG FÜR PROGRESSIVE QUERIES:
|
|||
|
||||
Du antwortest ausschliesslich auf Deutsch. Nutze kein sz(ß) sondern immer ss.
|
||||
"""
|
||||
|
||||
# Update cache with new date
|
||||
_cached_analysis_prompt_date = current_date
|
||||
return _cached_analysis_prompt
|
||||
|
||||
|
||||
def get_final_answer_system_prompt() -> str:
|
||||
"""
|
||||
Get the system prompt for generating the final answer.
|
||||
Focuses on formatting, presenting results, and user engagement.
|
||||
Uses caching to avoid regenerating the prompt on every request.
|
||||
"""
|
||||
global _cached_final_answer_prompt, _cached_final_answer_prompt_date
|
||||
current_date = datetime.datetime.now().strftime("%d.%m.%Y")
|
||||
|
||||
return f"""Heute ist der {current_date}.
|
||||
# Return cached prompt if date hasn't changed
|
||||
if _cached_final_answer_prompt is not None and _cached_final_answer_prompt_date == current_date:
|
||||
return _cached_final_answer_prompt
|
||||
|
||||
# Regenerate prompt (only when date changes)
|
||||
_cached_final_answer_prompt = f"""Heute ist der {current_date}.
|
||||
|
||||
Du bist ein Chatbot der Althaus AG.
|
||||
Deine Aufgabe ist es, auf Basis von Datenbank-Ergebnissen und Web-Recherchen hilfreiche, präzise Antworten zu geben.
|
||||
|
|
@ -454,6 +478,10 @@ Am Ende jeder Antwort biete hilfreiche Optionen für nächste Schritte an (Detai
|
|||
|
||||
Du antwortest ausschliesslich auf Deutsch. Nutze kein sz(ß) sondern immer ss.
|
||||
"""
|
||||
|
||||
# Update cache with new date
|
||||
_cached_final_answer_prompt_date = current_date
|
||||
return _cached_final_answer_prompt
|
||||
|
||||
|
||||
def get_system_prompt() -> str:
|
||||
|
|
@ -480,152 +508,21 @@ 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.)
|
||||
⚠️ WICHTIG - QUERY-ANZAHL FÜR PERFORMANCE ⚠️
|
||||
✓ Erstelle MAXIMAL 5 SQL-Queries (für bessere Performance)
|
||||
✓ Jede Query muss eine andere Strategie verfolgen
|
||||
✓ Alle Queries werden parallel ausgeführt
|
||||
|
||||
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 MINDESTENS 5-8 separate, vollständige, ausführbare SQL-Abfragen
|
||||
3. Falls eine Datenbankabfrage benötigt wird: Erstelle MAXIMAL 5 separate, vollständige, ausführbare SQL-Abfragen mit unterschiedlichen Strategien
|
||||
|
||||
⚠️⚠️⚠️ 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, 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)
|
||||
|
||||
⚠️⚠️⚠️ 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!
|
||||
⚠️ WICHTIGE REGELN:
|
||||
- Bei "mindestens X": Höhere Werte einschließen (z.B. "mindestens 10A" → 10A OR 12A OR 15A OR 20A)
|
||||
- Bei Zertifizierungen (UL, CE, TÜV, etc.): IMMER needsWebResearch = true setzen
|
||||
- SQL: Doppelte Anführungszeichen für Spaltennamen, JOIN mit Lagerplatz bei Beständen
|
||||
- Bei Lagerbeständen: Breite Suche über Artikelkürzel, Artikelnummer UND Artikelbezeichnung
|
||||
|
||||
Return ONLY valid JSON:
|
||||
{{
|
||||
|
|
@ -637,18 +534,9 @@ Return ONLY valid JSON:
|
|||
"purpose": string (description of what this query retrieves),
|
||||
"table": string (primary table name, e.g., "Artikel", "Lagerplatz_Artikel")
|
||||
}}
|
||||
] (array of query objects - MINDESTENS 5-8 bei komplexen Anfragen, MINDESTENS 8 bei Zertifizierungen!),
|
||||
] (MAXIMAL 5 queries für Performance!),
|
||||
"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!
|
||||
"""
|
||||
|
||||
|
||||
|
|
@ -721,15 +609,13 @@ def get_empty_results_retry_instructions(empty_count: int) -> str:
|
|||
return ""
|
||||
|
||||
return f"""
|
||||
⚠️⚠️⚠️ KRITISCH - LEERE ERGEBNISSE ERKANNT ⚠️⚠️⚠️
|
||||
⚠️ LEERE ERGEBNISSE ERKANNT ⚠️
|
||||
|
||||
Es wurden {empty_count} Query(s) ausgeführt, die 0 Zeilen zurückgegeben haben. Die bisherige Query-Strategie war nicht erfolgreich.
|
||||
Es wurden {empty_count} Query(s) ausgeführt, die 0 Zeilen zurückgegeben haben. Versuche alternative Strategien.
|
||||
|
||||
DU MUSST JETZT MEHRERE ALTERNATIVE QUERY-STRATEGIEN VERSUCHEN!
|
||||
⚠️ WICHTIG - MAXIMAL 5 QUERIES FÜR PERFORMANCE ⚠️
|
||||
|
||||
⚠️⚠️⚠️ OBLIGATORISCH - ERSTELLE MINDESTENS 5-8 ALTERNATIVE QUERIES ⚠️⚠️⚠️
|
||||
|
||||
Erstelle mehrere alternative SQL-Queries mit komplett anderen Strategien:
|
||||
Erstelle MAXIMAL 5 alternative SQL-Queries mit komplett anderen Strategien:
|
||||
|
||||
1. **Breitere Suche ohne Zertifizierung**: Entferne Zertifizierungsfilter komplett
|
||||
- Beispiel: Suche nur nach Netzgerät + einphasig + 10A (ohne UL)
|
||||
|
|
@ -760,7 +646,7 @@ Erstelle mehrere alternative SQL-Queries mit komplett anderen Strategien:
|
|||
- Beispiel: Netzgerät AND (10A OR 15A OR 20A) - keine weiteren Filter
|
||||
|
||||
WICHTIG:
|
||||
- Erstelle IMMER mehrere Queries (mindestens 5-8) mit unterschiedlichen Strategien
|
||||
- Erstelle MAXIMAL 5 Queries mit unterschiedlichen Strategien (für Performance)
|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ async def chatProcess(
|
|||
|
||||
async def _execute_queries_parallel(queries: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||||
"""
|
||||
Execute multiple SQL queries in parallel.
|
||||
Execute multiple SQL queries in parallel with shared connector.
|
||||
|
||||
Args:
|
||||
queries: List of query dictionaries, each containing:
|
||||
|
|
@ -243,21 +243,24 @@ async def _execute_queries_parallel(queries: List[Dict[str, Any]]) -> Dict[str,
|
|||
- "query_1_data", "query_2_data", etc.: Raw data arrays
|
||||
- "query_1_error", "query_2_error", etc.: Error messages if query failed
|
||||
"""
|
||||
async def execute_single_query(idx: int, query_info: Dict[str, Any]):
|
||||
"""Execute a single query and return result."""
|
||||
connector = PreprocessorConnector()
|
||||
try:
|
||||
query_text = query_info.get("query", "")
|
||||
result = await connector.executeQuery(query_text, return_json=True)
|
||||
await connector.close()
|
||||
return idx, result, None
|
||||
except Exception as e:
|
||||
await connector.close()
|
||||
return idx, None, str(e)
|
||||
|
||||
# Execute all queries in parallel
|
||||
tasks = [execute_single_query(i, q) for i, q in enumerate(queries)]
|
||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||
# Create single connector instance to reuse across all queries
|
||||
connector = PreprocessorConnector()
|
||||
try:
|
||||
async def execute_single_query(idx: int, query_info: Dict[str, Any]):
|
||||
"""Execute a single query using shared connector."""
|
||||
try:
|
||||
query_text = query_info.get("query", "")
|
||||
result = await connector.executeQuery(query_text, return_json=True)
|
||||
return idx, result, None
|
||||
except Exception as e:
|
||||
return idx, None, str(e)
|
||||
|
||||
# Execute all queries in parallel with shared connector
|
||||
tasks = [execute_single_query(i, q) for i, q in enumerate(queries)]
|
||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||
finally:
|
||||
# Close connector once after all queries complete
|
||||
await connector.close()
|
||||
|
||||
# Process results into dictionary
|
||||
query_results = {}
|
||||
|
|
@ -915,108 +918,11 @@ async def _processChatbotMessage(
|
|||
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"
|
||||
)
|
||||
# Limit query count to maximum 5 for performance
|
||||
max_queries_allowed = 5
|
||||
if needsDatabaseQuery and len(sql_queries) > max_queries_allowed:
|
||||
logger.info(f"Limiting queries from {len(sql_queries)} to {max_queries_allowed} for performance")
|
||||
sql_queries = sql_queries[:max_queries_allowed]
|
||||
|
||||
logger.info(f"Analysis: DB={needsDatabaseQuery}, Web={needsWebResearch}, SQL queries={len(sql_queries)}")
|
||||
|
||||
|
|
@ -1078,6 +984,32 @@ async def _processChatbotMessage(
|
|||
queryResults = {}
|
||||
webResearchResults = ""
|
||||
|
||||
# Start web research early in parallel with DB queries if needed
|
||||
web_research_task = None
|
||||
if needsWebResearch:
|
||||
# Start with basic query (will enrich later with DB results if available)
|
||||
basic_web_query = _buildWebResearchQuery(userInput.prompt, workflow.messages, None)
|
||||
logger.info(f"Starting web research in parallel with DB queries using basic query: '{basic_web_query}'")
|
||||
await _emit_log_and_event(interfaceDbChat, workflowId, event_manager, "Suche im Internet nach Informationen...")
|
||||
|
||||
async def perform_web_research():
|
||||
"""Perform web research and return results."""
|
||||
try:
|
||||
researchResult = await services.web.performWebResearch(
|
||||
prompt=basic_web_query,
|
||||
urls=[],
|
||||
country=None,
|
||||
language=userInput.userLanguage or "de",
|
||||
researchDepth="general",
|
||||
operationId=None
|
||||
)
|
||||
return json.dumps(researchResult, ensure_ascii=False, indent=2) if isinstance(researchResult, dict) else str(researchResult)
|
||||
except Exception as e:
|
||||
logger.error(f"Web research failed: {e}", exc_info=True)
|
||||
return f"Web research error: {str(e)}"
|
||||
|
||||
web_research_task = asyncio.create_task(perform_web_research())
|
||||
|
||||
# Execute database queries in parallel
|
||||
if needsDatabaseQuery and sql_queries:
|
||||
logger.info(f"Executing {len(sql_queries)} database queries in parallel...")
|
||||
|
|
@ -1151,10 +1083,11 @@ async def _processChatbotMessage(
|
|||
(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
|
||||
# Iterative retry loop: try up to 2 times with different strategies
|
||||
max_empty_retry_attempts = 2
|
||||
empty_retry_attempt = 0
|
||||
original_sql_queries_count = len(sql_queries)
|
||||
previous_retry_rows = 0
|
||||
|
||||
while should_retry and empty_retry_attempt < max_empty_retry_attempts:
|
||||
empty_retry_attempt += 1
|
||||
|
|
@ -1188,7 +1121,7 @@ async def _processChatbotMessage(
|
|||
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"
|
||||
retry_context += "Erstelle JETZT MAXIMAL 5 alternative SQL-Queries mit komplett anderen Strategien (für Performance):\n"
|
||||
|
||||
if empty_retry_attempt == 1:
|
||||
retry_context += "- Breitere Suche ohne zu spezifische Filter\n"
|
||||
|
|
@ -1230,6 +1163,10 @@ async def _processChatbotMessage(
|
|||
retry_analysis = _extractJsonFromResponse(retry_analysis_content)
|
||||
if retry_analysis and retry_analysis.get("needsDatabaseQuery", False):
|
||||
retry_sql_queries = retry_analysis.get("sqlQueries", [])
|
||||
# Limit to maximum 5 queries for performance
|
||||
if len(retry_sql_queries) > 5:
|
||||
logger.info(f"Limiting retry queries from {len(retry_sql_queries)} to 5 for performance")
|
||||
retry_sql_queries = retry_sql_queries[:5]
|
||||
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(
|
||||
|
|
@ -1287,20 +1224,32 @@ async def _processChatbotMessage(
|
|||
)
|
||||
should_retry = False # Stop retry loop, we found results
|
||||
break
|
||||
else:
|
||||
# Still no results, continue to next attempt
|
||||
elif retry_rows > previous_retry_rows:
|
||||
# Made some progress (found more rows than before) - continue
|
||||
previous_retry_rows = retry_rows
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"Versuch {empty_retry_attempt}: Immer noch keine Ergebnisse. Versuche nächste Strategie...",
|
||||
f"Versuch {empty_retry_attempt}: Fortschritt erzielt ({retry_rows} Zeilen gefunden). Versuche weitere Strategie...",
|
||||
log_type="info"
|
||||
)
|
||||
else:
|
||||
# No progress made - stop retrying
|
||||
await _emit_log_and_event(
|
||||
interfaceDbChat,
|
||||
workflowId,
|
||||
event_manager,
|
||||
f"Versuch {empty_retry_attempt}: Keine Ergebnisse gefunden. Beende Retry-Versuche.",
|
||||
log_type="warning"
|
||||
)
|
||||
should_retry = False # Stop retry loop, no progress
|
||||
break
|
||||
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
|
||||
# Check if we should continue retrying (already handled in break conditions above)
|
||||
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(
|
||||
|
|
@ -1322,33 +1271,18 @@ async def _processChatbotMessage(
|
|||
log_type="error"
|
||||
)
|
||||
|
||||
# Execute web research
|
||||
if needsWebResearch:
|
||||
logger.info("Performing web research...")
|
||||
await _emit_log_and_event(interfaceDbChat, workflowId, event_manager, "Suche im Internet nach Informationen...")
|
||||
|
||||
# Wait for web research to complete (if it was started in parallel)
|
||||
if web_research_task:
|
||||
try:
|
||||
# Rebuild enriched query with database results if available (better product context)
|
||||
web_research_query = _buildWebResearchQuery(
|
||||
userInput.prompt,
|
||||
workflow.messages,
|
||||
queryResults if queryResults else None
|
||||
)
|
||||
|
||||
logger.info(f"Using enriched web research query: '{web_research_query}'")
|
||||
|
||||
researchResult = await services.web.performWebResearch(
|
||||
prompt=web_research_query,
|
||||
urls=[],
|
||||
country=None,
|
||||
language=userInput.userLanguage or "de",
|
||||
researchDepth="general",
|
||||
operationId=None
|
||||
)
|
||||
webResearchResults = json.dumps(researchResult, ensure_ascii=False, indent=2) if isinstance(researchResult, dict) else str(researchResult)
|
||||
await _emit_log_and_event(interfaceDbChat, workflowId, event_manager, "Internet-Recherche abgeschlossen")
|
||||
webResearchResults = await web_research_task
|
||||
if webResearchResults and not webResearchResults.startswith("Web research error"):
|
||||
logger.info("Web research completed successfully")
|
||||
await _emit_log_and_event(interfaceDbChat, workflowId, event_manager, "Internet-Recherche abgeschlossen")
|
||||
else:
|
||||
logger.warning("Web research completed with errors")
|
||||
await _emit_log_and_event(interfaceDbChat, workflowId, event_manager, "Internet-Recherche fehlgeschlagen", log_type="warning")
|
||||
except Exception as e:
|
||||
logger.error(f"Web research failed: {e}", exc_info=True)
|
||||
logger.error(f"Error waiting for web research: {e}", exc_info=True)
|
||||
webResearchResults = f"Web research error: {str(e)}"
|
||||
await _emit_log_and_event(interfaceDbChat, workflowId, event_manager, "Internet-Recherche fehlgeschlagen", log_type="warning")
|
||||
|
||||
|
|
@ -1364,11 +1298,11 @@ async def _processChatbotMessage(
|
|||
# Build prompt for final answer
|
||||
system_prompt = get_final_answer_system_prompt()
|
||||
|
||||
# Build answer context with query results
|
||||
answerContext = f"User question: {userInput.prompt}{context}\n\n"
|
||||
# Build answer context with query results using efficient list-based building
|
||||
answer_context_parts = [f"User question: {userInput.prompt}{context}\n"]
|
||||
|
||||
# Add database results - organize by query with metadata
|
||||
db_results_part = ""
|
||||
db_results_parts = []
|
||||
if queryResults:
|
||||
successful_results = []
|
||||
error_results = []
|
||||
|
|
@ -1415,19 +1349,31 @@ async def _processChatbotMessage(
|
|||
if "error" in queryResults:
|
||||
error_results.append(f"Allgemeiner Fehler: {queryResults['error']}")
|
||||
|
||||
# Build db_results_part efficiently
|
||||
if successful_results:
|
||||
db_results_part = "\n\nDATENBANK-ERGEBNISSE:\n" + "\n\n".join(successful_results)
|
||||
answerContext += "DATENBANK-ERGEBNISSE:\n" + "\n\n".join(successful_results) + "\n\n"
|
||||
db_results_parts.append("\n\nDATENBANK-ERGEBNISSE:\n")
|
||||
db_results_parts.append("\n\n".join(successful_results))
|
||||
answer_context_parts.append("DATENBANK-ERGEBNISSE:\n")
|
||||
answer_context_parts.append("\n\n".join(successful_results))
|
||||
answer_context_parts.append("\n")
|
||||
|
||||
if error_results:
|
||||
db_results_part += "\n\nDATENBANK-FEHLER:\n" + "\n".join(error_results)
|
||||
answerContext += "DATENBANK-FEHLER:\n" + "\n".join(error_results) + "\n\n"
|
||||
db_results_parts.append("\n\nDATENBANK-FEHLER:\n")
|
||||
db_results_parts.append("\n".join(error_results))
|
||||
answer_context_parts.append("DATENBANK-FEHLER:\n")
|
||||
answer_context_parts.append("\n".join(error_results))
|
||||
answer_context_parts.append("\n")
|
||||
|
||||
db_results_part = "".join(db_results_parts)
|
||||
|
||||
# Add web research results
|
||||
web_results_part = ""
|
||||
if webResearchResults:
|
||||
web_results_part = f"\n\nINTERNET-RECHERCHE:\n{webResearchResults}"
|
||||
answerContext += f"INTERNET-RECHERCHE:\n{webResearchResults}\n\n"
|
||||
answer_context_parts.append(f"INTERNET-RECHERCHE:\n{webResearchResults}\n")
|
||||
|
||||
# Join answer context efficiently
|
||||
answerContext = "".join(answer_context_parts)
|
||||
|
||||
# Check if we have any actual data
|
||||
successful_query_keys = [k for k in queryResults.keys() if k.startswith("query_") and not k.endswith("_error") and not k.endswith("_data")]
|
||||
|
|
@ -1447,39 +1393,42 @@ async def _processChatbotMessage(
|
|||
|
||||
logger.info(f"Total articles found across all queries: {total_articles_found}")
|
||||
|
||||
# Add explicit article count information to prompt
|
||||
# Add explicit article count information to prompt (using efficient list building)
|
||||
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"
|
||||
article_count_parts = [
|
||||
"\n\n⚠️⚠️⚠️ WICHTIG - ARTIKELANZAHL ⚠️⚠️⚠️\n",
|
||||
f"In den DATENBANK-ERGEBNISSEN oben wurden INSGESAMT {total_articles_found} Artikel gefunden.\n",
|
||||
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"
|
||||
article_count_parts.append(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"
|
||||
article_count_parts.append(f"Zeige die ersten 20 Artikel in einer Tabelle + Hinweis auf weitere {total_articles_found - 20} Artikel.\n")
|
||||
article_count_parts.extend([
|
||||
f"❌ VERBOTEN: Nur einen Artikel zu zeigen, wenn {total_articles_found} gefunden wurden!\n",
|
||||
f"✓ OBLIGATORISCH: Zeige ALLE {total_articles_found} Artikel!\n"
|
||||
])
|
||||
article_count_info = "".join(article_count_parts)
|
||||
|
||||
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
|
||||
# Add warning messages if needed (using efficient list building)
|
||||
warning_parts = []
|
||||
if not has_query_results and needsDatabaseQuery:
|
||||
if db_results_part:
|
||||
db_results_part += "\n\nWICHTIG: Es wurden KEINE Datenbank-Ergebnisse gefunden. Die Datenbankabfrage wurde nicht ausgeführt oder hat keine Ergebnisse zurückgegeben."
|
||||
else:
|
||||
db_results_part = "\n\nWICHTIG: Es wurden KEINE Datenbank-Ergebnisse gefunden. Die Datenbankabfrage wurde nicht ausgeführt oder hat keine Ergebnisse zurückgegeben."
|
||||
warning_parts.append("\n\nWICHTIG: Es wurden KEINE Datenbank-Ergebnisse gefunden. Die Datenbankabfrage wurde nicht ausgeführt oder hat keine Ergebnisse zurückgegeben.")
|
||||
|
||||
if has_only_errors:
|
||||
if db_results_part:
|
||||
db_results_part += "\n\n⚠️⚠️⚠️ KRITISCH - ALLE QUERIES FEHLGESCHLAGEN ⚠️⚠️⚠️\n" + \
|
||||
"ALLE Datenbankabfragen sind fehlgeschlagen. Es gibt KEINE gültigen Daten aus der Datenbank.\n" + \
|
||||
"DU DARFST KEINE DATEN ERFINDEN! Schreibe stattdessen: 'Es wurden keine Artikel gefunden' oder 'Die Datenbankabfrage ist fehlgeschlagen'."
|
||||
else:
|
||||
db_results_part = "\n\n⚠️⚠️⚠️ KRITISCH - ALLE QUERIES FEHLGESCHLAGEN ⚠️⚠️⚠️\n" + \
|
||||
"ALLE Datenbankabfragen sind fehlgeschlagen. Es gibt KEINE gültigen Daten aus der Datenbank.\n" + \
|
||||
"DU DARFST KEINE DATEN ERFINDEN! Schreibe stattdessen: 'Es wurden keine Artikel gefunden' oder 'Die Datenbankabfrage ist fehlgeschlagen'."
|
||||
warning_parts.extend([
|
||||
"\n\n⚠️⚠️⚠️ KRITISCH - ALLE QUERIES FEHLGESCHLAGEN ⚠️⚠️⚠️\n",
|
||||
"ALLE Datenbankabfragen sind fehlgeschlagen. Es gibt KEINE gültigen Daten aus der Datenbank.\n",
|
||||
"DU DARFST KEINE DATEN ERFINDEN! Schreibe stattdessen: 'Es wurden keine Artikel gefunden' oder 'Die Datenbankabfrage ist fehlgeschlagen'."
|
||||
])
|
||||
|
||||
if warning_parts:
|
||||
db_results_part = db_results_part + "".join(warning_parts) if db_results_part else "".join(warning_parts)
|
||||
|
||||
# Use the function from constants file to build the prompt
|
||||
answer_prompt = get_final_answer_prompt_with_results(
|
||||
|
|
|
|||
Loading…
Reference in a new issue