Spaces:
Sleeping
Discovery Conversation Script
β οΈ Design intent, not the present-state map. The turn-by-turn script and adaptive rules below capture the discovery intent; the implementation is now a single Gemini 2.5-flash call per turn with function-calling tools (
backend/single_brain.py/brain_tools.py) β there is no scripted question renderer, noorchestrator, nosales_brain/qa_brainsplit, and no separate faithfulness judge. Present-state authority:README.mdΒ§4.
The 10-turn fact-find that turns a stranger into a profiled buyer.
Design principles (inspired by Even.in's tone + insurance-sector buyer-research norms):
- Plain language. No "PED", no "UIN", no "sub-limit". We're talking to an adult who hasn't read a policy wording end-to-end.
- Every question explains WHY we're asking. A form feels invasive; a conversation feels helpful. The one-line why-this-matters subtitle is non-optional.
- Chips, not text boxes. Multi-choice + sliders + toggles. Free-text only when no chip set is honest.
- Honesty pre-commitment. Right after the first turn, the bot tells the user: "Tell me the truth, even on hard things. Your honest answer protects your claim later β not just my recommendation."
- Optional, not gated. The user can stop at any time. We surface what we can with partial profiles (insurer-level CSR / complaints) but ONLY personalize the scorecard once
profile_completeness >= 0.6.
Turn-by-turn script
Turn 0 β Welcome (the bot starts)
"Hi β I'm here to help you find a health policy that genuinely fits you, not the one that pays the highest commission to a broker. I'll ask about 8β10 short questions. Some will feel personal (your health, what you earn). Be honest β every answer is private to this chat, and being upfront about your medical history is the single biggest thing that protects you when you actually need to claim. Ready?"
[Chip: "Let's start" Β· "Tell me how this works first" Β· "Just let me browse"]
Turn 1 β Age
"What's your age?"
Why we ask: premium, eligibility, and renewability all hinge on this.
[Slider 18β80, step 1]
Turn 2 β Who's covered
"Who else do you want to cover?"
Why we ask: covering parents or kids changes which policies make sense β some plans price family floaters very differently.
[Multi-select chips: "Just me", "Spouse", "Children", "Parents", "Parents-in-law"]
Turn 3 β Parents' health (CONDITIONAL β only if Turn 2 included parents)
"If you're covering parents, what's the older one's age, and do they have any pre-existing conditions like diabetes, BP, or heart issues?"
Why we ask: parents-with-PED need policies with shorter PED waiting periods and lifelong renewability β that narrows the field a lot.
[Slider for age + chips: "None", "Diabetes", "Hypertension/BP", "Heart", "Cancer", "Thyroid", "Multiple"]
Turn 4 β Your own conditions
"Any pre-existing conditions for yourself? Diabetes, BP, thyroid, asthma, anything chronic?"
Why we ask: this is where honesty matters most. Hiding it gets your premium βΉ500 cheaper today and a denied claim of βΉ8 lakh later. Insurers can and do find out at claim time.
[Multi-select: "None", "Diabetes", "BP/Hypertension", "Thyroid", "Asthma", "Heart", "Cancer history", "Other"]
Turn 5 β Existing cover
"Do you already have any health insurance β through your employer or that you bought yourself?"
Why we ask: if you already have βΉ5L from work, you might need a top-up rather than a full base plan β different product, different price.
[Chips: "None", "Employer only", "Personal policy", "Both" β if any, ask sum insured slider]
Turn 6 β City
"Which city or town?"
Why we ask: cashless hospital network density varies massively. A "16,000-hospital network" means nothing if none are near you.
[Free text + autocomplete] OR [Chips: "Metro", "Tier-1", "Tier-2", "Tier-3 / smaller town"]
Turn 7 β Budget
"Roughly what annual premium budget feels comfortable?"
Why we ask: helps us rank β but if a slightly higher budget materially improves your protection, we'll flag it.
[Slider with 4 markers: <βΉ15k, βΉ15β30k, βΉ30β60k, βΉ60k+]
Turn 8 β Maternity & near-term events (CONDITIONAL)
"Anything planned in the next 12β24 months β pregnancy, a known surgery, anything you've discussed with a doctor recently?"
Why we ask: most policies have 30-day initial waits and 24β36-month maternity waits. If you need cover soon, that filters the list.
[Multi-select: "Pregnancy planned", "Surgery planned", "Recent hospitalisation", "None of these"]
Turn 9 β Risk preference
"When it comes to surprises in your bill, what do you prefer?"
Why we ask: this single answer decides whether co-pay/deductible plans (cheaper premium, share-of-bill) or full-cover plans (higher premium, predictable bill) fit you.
[Chips: "Lowest premium, I'll accept a 10β20% co-pay", "Balanced", "No surprises β full cover at higher premium"]
Turn 10 β Income (optional, asked last)
"One last optional question β your annual income band. We use it only to gauge how much sum insured fits your risk."
Why we ask: if you earn βΉ8L/yr, a βΉ50L cover is overkill; if you earn βΉ40L/yr, a βΉ5L cover leaves you exposed.
[Chips: "Prefer not to say", "<βΉ5L", "βΉ5β10L", "βΉ10β25L", "βΉ25L+"]
Wrap
"That's all I needed. Here's what I heard: . I'll now show you 3 policies that fit best, with the exact reasons they ranked well for you specifically."
β Render scorecard cards (now personalised because profile_completeness >= 0.6).
Honest disclosure β the trust contract
Right after Turn 0 and again before Turn 4 (own conditions), the bot surfaces a one-line contract:
"Your answers stay in this conversation. They are NOT shared with any insurer until you choose to buy a policy through their channel. Being honest with me about your medical history is also what makes your claim defensible later β because insurers can match disclosed history against hospital records at claim time."
This is the customer-protection framing. It tells the user honesty is self-protection, not insurer-favoring.
Adaptive rules
- If the user is in free-form mode (asks questions back to the bot), don't push the script β let them lead. Resume when they ask "what do you recommend?"
- If
profile_completeness >= 0.6after some subset of questions, offer to skip the rest: "I have enough to recommend now. Want to keep going, or see what I'd suggest?" - Never ask the same question twice.
Profile.askedtracks this. - A user who says "just show me policies" gets the marketplace with insurer-level metrics (CSR / complaints) visible but per-user scorecards GREYED with a "complete your profile to see how this ranks for you" CTA.
Implementation notes
The 9-slot fact-find SCHEMA still lives in backend/needs_finder.py::GRAPH β used now as the schema source embedded in the single-LLM system prompt rather than as a scripted question list. Each entry's id, field, is_core, and condition are consumed by the LLM as a structured contract; the prompt_en / prompt_hi strings are no longer rendered to the user (the LLM owns voice + cadence end-to-end via its system prompt + the conversation so far, and records facts through the save_profile_field tool).
To add a new question:
- Add a
Question(...)entry withid,field(which Profile attribute it sets),is_core(boolean β counts toward completeness), optionalconditioncallable, optionalparser. - Surface the new slot in the single-brain system prompt's 9-slot schema (alongside accepted value shapes + examples) so the LLM knows to capture it. See the system prompt in
backend/single_brain.py. - Wire any post-capture validation into the
save_profile_fieldhandler inbackend/brain_tools.py(enum coercion, INR parsing, bounds). - Add a row in
70-docs/scorecard-knowledge-graph.mdPart B showing how the new input shifts weights. - Wire the shift into
_profile_tuned_weights()inbackend/scorecard.py.
Drift between these places breaks the transparency promise. Keep them in sync.