Pārlūkot izejas kodu

Classifier: Query-Heuristik als Fallback bei fehlenden Slots

Problem: ONNX-Classifier erkennt Intent aber KeywordMatcher findet
keine Slots bei hoeflichen Formulierungen ("koenntest du bitte
musik von rammstein spielen" → slots={}).

Fix: Strategie 3 — Stoppwort-Heuristik als letzter Fallback.
Entfernt Hoeflichkeits-, Funktions- und Intent-spezifische Woerter,
Rest wird als Query-Slot verwendet.

"koenntest du bitte musik von rammstein spielen" → query="rammstein"
"ich moechte musik von mozart hoeren" → query="mozart"

Gilt fuer: play_music, search_notes, search_appointment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
patrick 2 mēneši atpakaļ
vecāks
revīzija
a1a4a71738
1 mainītis faili ar 46 papildinājumiem un 0 dzēšanām
  1. 46 0
      plugins/nlp_classifier/main.py

+ 46 - 0
plugins/nlp_classifier/main.py

@@ -304,8 +304,54 @@ class NLPClassifierPlugin(TrixyPlugin):
             pdebug(f"[Classifier] Slots via generischem Match ({kw_result.intent}): {kw_result.slots}")
             return kw_result.slots
 
+        # Strategie 3: Heuristik — Stoppwoerter entfernen, Rest als Query
+        # Fuer Intents mit freiem {query} Slot (play_music, search_notes, etc.)
+        query_intents = {
+            "play_music", "search_notes", "search_appointment",
+        }
+        if intent_name in query_intents:
+            query = self._extract_query_heuristic(text)
+            if query:
+                pdebug(f"[Classifier] Query via Heuristik: '{query}'")
+                return {"query": query}
+
         return {}
 
+    @staticmethod
+    def _extract_query_heuristic(text: str) -> str:
+        """
+        Extrahiert einen Query aus dem Text durch Entfernen von Stoppwoertern.
+
+        "koenntest du bitte musik von rammstein spielen"
+        → entferne: koenntest, du, bitte, musik, von, spielen
+        → uebrig: "rammstein"
+        """
+        stop_words = {
+            # Hoeflichkeit
+            "koenntest", "kannst", "wuerdest", "waerst", "bitte", "mal",
+            "du", "mir", "doch", "gerne", "gern",
+            # Musik-spezifisch
+            "musik", "spiel", "spiele", "spielen", "abspielen", "abspiel",
+            "mach", "mache", "hoeren", "hoer", "an", "von", "etwas",
+            "lied", "song", "track",
+            # Allgemein
+            "ich", "moechte", "will", "haette", "lass", "wir",
+            "den", "die", "das", "der", "dem", "ein", "eine", "einen",
+            "und", "oder", "fuer", "mit", "auf", "in", "im",
+            "sei", "so", "lieb", "nett", "es",
+            # Suche
+            "suche", "such", "suchen", "finde", "finden", "nach",
+        }
+
+        words = text.lower().split()
+        # Stoppwoerter entfernen
+        query_words = [w for w in words if w not in stop_words]
+
+        # Satzzeichen entfernen
+        query = " ".join(query_words).strip("?!.,")
+
+        return query if query else ""
+
     def _get_session_info(self, satellite_id: str) -> dict[str, Any]:
         """Holt Session-Info fuer den Satellite."""
         try: