Spaces:
Sleeping
fix(routing): KI-154 — empty-profile QA must route to fact_find
Browse filesLive bug: user said 'to buy a health insurance policy' (clear intent to
buy) and got a generic policy-fact dump citing Health Protector Plus +
ACKO + IRDAI 2024 regulations on an EMPTY profile session. Bot quoted
'Any One Illness' definitions to someone who hasn't even given their name.
Two failures combined:
1. FACT_FIND_TRIGGERS only had 'buy health insurance' (no article).
'to buy a health insurance policy' has 'buy A health insurance' — the
substring match failed, classify_intent fell through to 'qa'.
2. should_route_to_fact_find force-routed only recommendation/comparison
intents to fact_find on empty profile. QA was let through, which is
correct for specific-policy questions ('Does Star Comprehensive cover
IVF?') but wrong for generic intent statements ('to buy a policy').
Fix:
1. Extend FACT_FIND_TRIGGERS with more buying phrasings: 'to buy',
'want to buy', 'looking to buy', 'buy a ', 'buy an ', 'purchase',
'shopping for a', 'get a policy', 'need a plan', 'buy a policy', etc.
2. New rule in should_route_to_fact_find: when profile_is_empty AND
intent=='qa' AND query does NOT name a specific insurer/SKU (via
_names_two_specific_policies OR single-insurer-token check), force
route to fact_find. Empty-profile users never see raw policy facts
before we know who they are.
Verified localhost: 'to buy a health insurance policy' now routes to
fact_find_brain with conversational welcome asking age + dependents.
Specific-policy qa queries that DO name an insurer still get qa.
- backend/orchestrator.py +26 -0
|
@@ -59,6 +59,14 @@ FACT_FIND_TRIGGERS = (
|
|
| 59 |
"have kids", "have parents", "for my parents", "for my family",
|
| 60 |
"my income", "earn ", "salary",
|
| 61 |
"first policy", "first time buyer",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
)
|
| 63 |
|
| 64 |
COMPARISON_KEYWORDS = (
|
|
@@ -265,6 +273,24 @@ def should_route_to_fact_find(
|
|
| 265 |
if intent == "comparison" and _names_two_specific_policies(query):
|
| 266 |
return False
|
| 267 |
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 268 |
return False
|
| 269 |
|
| 270 |
|
|
|
|
| 59 |
"have kids", "have parents", "for my parents", "for my family",
|
| 60 |
"my income", "earn ", "salary",
|
| 61 |
"first policy", "first time buyer",
|
| 62 |
+
# KI-154 (2026-05-15) — additional buying-intent phrasings that don't
|
| 63 |
+
# contain "buy health insurance" as a tight substring. Live bug: user
|
| 64 |
+
# said "to buy a health insurance policy" — fell through to qa because
|
| 65 |
+
# the literal "buy health insurance" (no article) didn't match.
|
| 66 |
+
"to buy", "want to buy", "looking to buy", "buy a ", "buy an ",
|
| 67 |
+
"purchase", "purchasing", "shopping for a", "get a policy",
|
| 68 |
+
"get a plan", "need a policy", "need a plan", "buy a policy",
|
| 69 |
+
"buy a plan", "buy insurance", "buy a policy for",
|
| 70 |
)
|
| 71 |
|
| 72 |
COMPARISON_KEYWORDS = (
|
|
|
|
| 273 |
if intent == "comparison" and _names_two_specific_policies(query):
|
| 274 |
return False
|
| 275 |
return True
|
| 276 |
+
# KI-154 (2026-05-15) — empty-profile + qa intent: route to fact_find
|
| 277 |
+
# UNLESS the query names a specific policy / insurer (real policy-fact
|
| 278 |
+
# lookup) or asks about specific policy mechanics. Without this rule,
|
| 279 |
+
# broad questions like "to buy a health insurance policy" or "tell me
|
| 280 |
+
# about health insurance" dumped raw policy facts on users who haven't
|
| 281 |
+
# even given their name yet.
|
| 282 |
+
if profile_is_empty and intent == "qa":
|
| 283 |
+
# If query names a specific insurer/SKU, it's a legitimate policy-fact
|
| 284 |
+
# lookup (e.g., "Does Star Comprehensive cover IVF?"). Let qa handle.
|
| 285 |
+
if _names_two_specific_policies(query):
|
| 286 |
+
return False
|
| 287 |
+
# Single named policy/insurer is also fine for qa
|
| 288 |
+
ql = query.lower()
|
| 289 |
+
if any(tok in ql for tok in _NAMED_INSURER_TOKENS):
|
| 290 |
+
return False
|
| 291 |
+
# Otherwise — empty-profile generic intent — route to fact_find so the
|
| 292 |
+
# bot collects basic context before quoting policy specifics.
|
| 293 |
+
return True
|
| 294 |
return False
|
| 295 |
|
| 296 |
|