Three layers with a strict division of labour. The test for whether the line is drawn correctly: if the LLM provider went down and you swapped in a template renderer, would the answers still be factually correct? They would — you would lose fluency and translation, not truth.
The three layers
1. Deterministic layer — PostgreSQL
Decides every fact
Services, scenarios, eligibility rules, required documents, procedure steps, fees and offices are rows. Conditions are stored as JSON expression trees and evaluated by code with three-valued logic, so "we do not know yet" is a distinct outcome from "no". Nothing here is summarised by a model.
Which service
Which branch
Eligible or not
Which documents
Ready or not
2. Grounded retrieval — pgvector
Finds supporting text
Official prose is chunked, embedded and retrieved by hybrid search: Postgres full-text plus vector cosine, fused with reciprocal rank fusion. Every chunk carries its source title and last-verified date. Retrieval finds text; it does not decide truth, and "nothing documented" is a valid result that routes the citizen to the office.
Supporting evidence
Source citations
Coverage assessment
3. Language layer — LLM
Only phrases and translates
Four jobs: detect intent, translate, route context, and render already-decided content. It is never asked what documents a service needs — it is handed the list and asked to express it in Urdu. Every call has a required deterministic fallback, enforced by the type signature of the client.
Intent extraction
Question phrasing
Translation
Query expansion
What is actually in the database, right now
3
Services
10
Scenarios
21
Requirements
10
Eligibility rules
15
Procedure steps
7
Exception routes
11
Offices
10
Sources
Retrieval corpus: 11 documents, 20 chunks, 20 embedded with Xenova/multilingual-e5-small at 1024 dimensions.
Provenance
Every citizen-facing fact carries a verification tier and a source. The seeded knowledge base is deliberately unverified: it is structurally complete and attributed to real official pages, but no one has yet confirmed each value against the live page. Fees are stored as NULL rather than as a plausible guess.
0
verified · 0%
51
unverified · 82%
11
synthetic · 18%
Every requirement, step, rule and fee has a source. Zero orphaned facts.
Runtime capabilities
Language model
groq → mock
Live. Keys: dashscope 0, groq 1.
Embeddings
local / Xenova/multilingual-e5-small @ 1024d
Multilingual semantic retrieval active.
Grounding
Strict mode on. Sources go stale after 180 days. Evidence floor 0.75 cosine.