Skip to content

[Enhancement] Question-understanding pipeline: intent classification, clarifying questions, answer-length calibration, and suggested follow-ups #42

Description

@zeemscript

Summary

Every prompt gets the identical treatment: "Assalamu alaikum" and a three-part inheritance question both run through the same fixed generation config with the same 2048-token allowance and the same prompt guidance — so greetings get essays, complex questions get whatever fits, and ambiguous questions get a confident guess at one of their possible meanings. This issue adds a question-understanding stage to /chat: classify the intent of each message, calibrate answer shape and length per intent, ask a clarifying question instead of guessing when the question is genuinely ambiguous, and return 2–3 suggested follow-up questions so the frontend can keep students exploring. This is answer-shape quality, complementing the campaign issues that cover grounding (#24), citations (#15), and formatting of Arabic content (#14).

Current state

  • The /chat handler (main.py, lines 118–184) sends every prompt through one path with hardcoded generation config — temperature: 0.7, top_p: 0.8, top_k: 40, max_output_tokens: 2048 (lines 145–150) — regardless of what kind of message it is.
  • ISLAMIC_CONTEXT (lines 57–71) contains no guidance on answer length, structure, or when to ask for clarification; rule 5 ("Acknowledge when a question is beyond your scope") is the only shape-related instruction.
  • ChatResponse (lines 85–88) is response / chat_id / history — no field exists for follow-up suggestions or any signal about what kind of answer this is, so the frontend renders every reply identically.
  • Nothing detects ambiguity: "Is music haram?" (a classic it-depends question with multiple scholarly framings) and "what breaks the fast?" (underspecified: eating? fasting person's doubts? which acts?) both get single-shot guesses today.

What to build

  1. Intent taxonomy + classifier — a small enum of intents, e.g.: greeting_smalltalk, factual_knowledge (aqeedah/seerah/definitions), fiqh_ruling, personal_guidance (emotional/spiritual support, du'a requests), platform_question (DeenBridge/courses/zakat features), out_of_scope. Implement classification in a new module (e.g. intent.py) as a single cheap structured-output Gemini call with a deterministic short-circuit for trivial cases (very short greetings, salam variants) so the common case adds no latency. Measure and report the added latency in the PR.
  2. Per-intent answer shaping — map each intent to generation parameters and a per-intent instruction snippet appended to the prompt context: greetings → warm, 1–2 sentences, return the salam properly, invite a question; factual → structured, thorough, sourced; personal guidance → compassionate tone, du'a where fitting, gentle scholar referral for serious matters; platform questions → concise and practical; out-of-scope → polite deflection per the existing rule 5. Replace the hardcoded generation-config dict with the per-intent table (env-overridable defaults).
  3. Clarify-before-answering — extend the classifier to also emit an ambiguity judgment with a proposed clarifying question. When a question is genuinely underspecified, the assistant asks one targeted clarifying question instead of answering, and the response carries a flag (e.g. needs_clarification: true) so the frontend can style it. Guard against over-triggering: default threshold conservative, env-tunable, and never clarify twice in a row for the same session.
  4. Suggested follow-ups — the answer generation emits 2–3 natural next questions (e.g. after an answer about wudu: "What invalidates wudu?", "How is tayammum performed?") in a delimited machine-readable block after the prose, parsed and stripped server-side into suggested_followups: List[str] on ChatResponse. Use the same defensive parse-or-degrade pattern as the structured-citations issue ([Enhancement] Return structured Quran/Hadith citations alongside answers #15): a malformed block yields an empty list, never an error, and never leaks into response.
  5. Response metadata — echo the classified intent in the response so the frontend can adapt rendering, and so logs let the maintainer see the intent distribution of real traffic.
  6. Eval + tests — contribute per-intent cases to the evaluation-harness ([Enhancement] Evaluation harness for Islamic answer quality #16) dataset format: greetings must be short (length assertion), ambiguous fixtures must trigger clarification, follow-ups must parse. Unit tests with a mocked Gemini client cover the classifier short-circuit, per-intent config selection, follow-up parsing (well-formed, malformed, missing), and the no-double-clarification guard.

Acceptance criteria

  • "Assalamu alaikum" gets a warm ≤2-sentence reply returning the greeting; a substantive aqeedah question gets a structured, full-length answer — both verifiable via committed eval cases.
  • Classification adds at most one lightweight model call, with the deterministic short-circuit covering trivial messages (asserted in tests) and measured latency reported in the PR.
  • An underspecified fixture question yields exactly one clarifying question with needs_clarification: true; the follow-up user reply then gets a real answer (no clarification loops).
  • suggested_followups contains 2–3 relevant questions for knowledge answers, is empty on parse failure, and the raw block never appears in response.
  • intent is present in the response and logged; hardcoded generation config is replaced by the per-intent table with env-overridable defaults.
  • Existing clients that read only response/chat_id/history are unaffected.
  • New modules are linted, tested offline with mocks, and CI stays green.

Pointers

Difficulty

Medium — no new infrastructure, but it touches the heart of the chat path: a classifier that must be fast and rarely wrong, calibration tables, defensive parsing, and an ambiguity heuristic that is genuinely useful without becoming an annoying "what do you mean?" bot.


🏆 GrantFox OSS — Official Campaign | FWC26. Apply for this issue through the GrantFox campaign page. The maintainer assigns one contributor before work starts; unassigned PRs may not be reviewed. PRs target the dev branch. Quality bar: CI must stay green.

💬 Questions or need help? Reach the maintainers and other contributors on the DeenBridge Telegram: https://t.me/+nst9lXNj1wc4ZDE0

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions