"""Cheap syntactic features for intent classification, concatenated to the BGE embedding. The embedding captures topic/paraphrase; these capture the interrogative-vs-declarative *syntax* that the embedding blurs (so 'my policy is X' [fact] and 'what is my policy?' [question] separate cleanly). Shared by evals/intent_train.py (training) and tiered_rag_mlx.py (inference) so they never drift.""" import re _QWORD = ("what", "what's", "whats", "who", "who's", "whose", "when", "where", "which", "how", "why", "is my", "are my", "do you", "did i", "can you") _RECALL = re.compile(r"\b(remind me|recall|do you remember|tell me (my|where|what)|what was|again\b)", re.I) _STORE = re.compile(r"\b(remember|note that|save this|keep in mind|for later|don't forget)\b", re.I) _ASSERT = re.compile(r"\bmy\b.{0,40}?\b(is|are|=|named|called|costs?)\b|^\s*(i'?m|i am|i'?ll|i will|i live|i work|i drive|i prefer|i'?d like)\b", re.I) _IMPER = re.compile(r"^\s*(make it|change|set |add |order|paint|use |scratch that|update|move )", re.I) _CODE = re.compile(r"\b[A-Z]{2,}[- ]?\d|\b\d{3,}\b") # a code / number value present # spelled-out arithmetic ('nine times five', 'fifteen percent of two hundred') — so math doesn't depend # on a literal digit (the classifier was leaning on \d and missing word-numbers) _NUMWORD = re.compile(r"\b(zero|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|" r"fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty|thirty|forty|fifty|" r"sixty|seventy|eighty|ninety|hundred|thousand|million|dozen|half|quarter|double)\b", re.I) _OPWORD = re.compile(r"\b(plus|minus|times|divided|multiply|multiplied|subtract(ed)?|add(ed|s)?|percent|" r"sum of|total of|product of|difference|average of|squared|cubed)\b", re.I) # a declarative assertion ("the theme is space", "it costs $5 each", "deadline is Monday") _DECL = re.compile(r"\b(the|this|that|it|we'?re|there|deadline|theme|venue|color|colour|price|name)\b.{0,30}?" r"\b(is|are|'?re|'?s|costs?|moved|changed|named|called|set to|will be)\b", re.I) def _declarative(t): return not (t.endswith("?") or t.startswith(_QWORD)) and bool(_DECL.search(t)) def intent_feats(text): t = text.strip().lower() return [ float(t.endswith("?")), float(t.startswith(_QWORD)), float(bool(_RECALL.search(text))), float(bool(_STORE.search(text))), float(bool(_ASSERT.search(text))), float(bool(_IMPER.search(text))), float(bool(re.search(r"\d", text))), float(bool(_CODE.search(text))), float(_declarative(t)), # 'the theme is space', 'it costs $5' float(bool(_NUMWORD.search(text))), # spelled-out number ('twelve', 'hundred') float(bool(_OPWORD.search(text))), # arithmetic op word ('minus', 'percent') min(len(t.split()) / 12.0, 1.5), # length (chit-chat tends short) ]