HealthBricks — a planning room for India's health-access gaps
Track 2 · Databricks Apps & Agents for Good Hackathon
Inspiration
We started from a question a state health official actually has to answer every budget cycle: "I have a fixed amount of money this year. Where do I put a new hospital, which existing ones do I upgrade, and where do I send mobile units — so that the most underserved people are actually reached?"
Today that decision is made with district-level spreadsheets and intuition. India's health data exists — NFHS-5 surveys, facility registries, census-grade population grids — but it lives in separate silos at the wrong granularity for a where exactly decision. Meanwhile, the National Health Mission runs Mobile Medical Units (MMUs) as its frontline way to take primary care to the doorstep of remote, difficult, under-served and unreached populations — and it just refreshed the playbook with the Revised Operational Guidelines for MMUs, 2026 (NHM). The program's norms are strikingly concrete: deploy roughly 1 MMU per 10 lakh population, capped at 5 per district, at a recurring cost of ₹24 lakh per unit per year (₹28 lakh for the North-East, J&K and Himachal Pradesh), each unit delivering a PHC-grade package across 12 thematic areas — maternal, child, reproductive, communicable, non-communicable, mental, dental, eye/ENT, geriatric and emergency care. That money only does as much good as the plan behind it, and where exactly do we send them is precisely the question this platform answers.
So we built the planning room: one platform that turns the scattered data into a map you can interrogate and three concrete, quantified levers a government can pull — build, upgrade, route — all scored on the same honest objective: people whose need isn't being met.
What it does
Everything in the platform is scored on one number, computed per hexagon of India:
$$\text{unmet}(h) = \sum_{c \in C_{\text{NFHS}}} \text{pop}(h) \cdot \max(0,\; d_c(h) - s_c(h))$$
where $d_c$ is normalized demand (need) for clinical category $c$, $s_c$ is normalized supply (provision), and $C_{\text{NFHS}}$ are the 7 categories for which the NFHS-5 survey gives us a real demand signal. In plain terms: population, weighted by how far supply falls short of need. One engine, so the whole tool reads as a single coherent system instead of four disconnected charts.
On top of that engine sit four workspaces:
- Insight Layers (the map). India as an H3 hexagon choropleth (res-5, ~250 km² cells). Pick a clinical category and explore it through stacked layers — Coverage, Population Underserved, Demand, Gap, Population — each with a live distribution histogram and a dual-range slider. Drag the handles and the country re-filters in front of you; the filters combine across layers so you can ask "show me hexes that are high-need and low-coverage and densely populated."
- Build new facilities. Say "5 new facilities for maternal care." A greedy max-coverage optimizer returns the exact hexes that mop up the most population-weighted unmet need, spaced apart so they don't cannibalize each other.
- Upgrade existing facilities. Given a capability to add (say cardiology), it ranks the existing facilities that don't offer it yet but sit on the largest surrounding unmet demand — the cheapest path to more coverage.
- Mobile Medical Units. Pick K units and a drive-time budget, and it plans real road-network loops from hub facilities through the highest-unmet stops. This is the lever the 2026 guidelines are pushing, so we made it first-class: routes over actual roads, de-duplicated coverage so two units never claim the same village, and a "people served" number for each route. It mirrors the real program — an MMU is a broadly capable unit (medical officer + nurse + lab + pharmacist, riding a doctor-and-diagnostics van across the NHM's 12 thematic areas), which is exactly why we score it on aggregate unmet need across categories rather than any single specialty.
And tying it together: PoshanNiti, a copilot you can type to or talk to (live voice), which answers questions over the same governed tables — and the map is wired to take its cues (highlight a region, switch a lever) as we grow what the agent can do.

How we built it
It's a fully Databricks-native stack, which is what let us ship this in a hackathon's worth of time [VERIFY: insert team size / hackathon duration]:
- Data layer — Unity Catalog. We fused three sources onto one spatial spine: Kontur population (GHSL-based, aggregated H3 res-8 → res-5), NFHS-5 district health indicators (~107 columns of need signals), and the India facilities registry (geocoded, specialties exploded and classified into 16 clinical categories). The hard-won lesson here became our one rule: join only by
region_idorh3_5, never by district name — because NFHS-5 uses pre-2020 names (Allahabad, Gulbarga) while every other source uses modern ones (Prayagraj, Kalaburagi). Surrogate keys made the joins vintage-proof: 12,709 hexes, 740 regions, 96.8% of population matched to a survey row. - Logic layer — pure Python + SQL. The scoring, the facility optimizers, and the MMU route solver are a small dependency-light module so they run identically on a laptop and inside the app. The MMU planner is a Team Orienteering Problem with a submodular (coverage) reward — greedy insertion by marginal coverage-per-second, then 2-opt / or-opt local search — over a precomputed road-time matrix of ~639,000 origin-destination pairs we built locally with OSRM.
- Serving — Databricks Apps + Lakebase + Genie + Mosaic AI. The whole product is one FastAPI app on Databricks Apps. The map and optimizers read from the SQL warehouse; chat history lives in Lakebase (Postgres). The text copilot is a Mosaic AI Agent Framework endpoint with a Genie tool over the same gold tables; the voice channel is OpenAI Realtime with Genie exposed as a function tool. deck.gl + MapLibre render the hexes and routes.
Challenges we ran into
- Making the agent loop ground itself in our data — and act on the UI. Standing up a Mosaic AI Agent Framework loop was the easy part; the real work was integrating its agentic (ReAct) loop with the right tools. We grounded it on a Genie tool over the same governed gold tables so answers come from our numbers instead of the model's imagination, then designed a
ui_actionscontract so a tool call can reach back into the front end — highlight a region, switch a lever — rather than just returning prose. Getting an agent loop to be both source-grounded and UI-aware, with tools scoped tightly enough to be reliable, took more iteration than any single optimizer.
Accomplishments we're proud of
A government user can go from "the whole country lights up with gaps" to a ranked, map-drawn deployment plan — new sites, upgrades, and mobile routes — in a few clicks, every recommendation traceable to the same transparent objective. The MMU routes run on real roads with de-duplicated impact, not straight lines and hand-waving. And it's all live on one Databricks App with a voice copilot sitting on the same governed data.
What we learned
Geospatial plumbing is the project. The optimization is satisfying and the agent is flashy, but the credibility comes from the unglamorous work — vintage-proof keys, exact H3 ids, population-weighting everything, and refusing to fake the road network. We also learned how far the Databricks-native path carries you: Unity Catalog → Lakebase → Apps → Genie → Agent Framework meant we spent our time on the problem, not on glue.
The agent side taught us a sharper lesson: with Mosaic's Agent Framework the loop is the cheap part — the tools are everything. An agentic loop is only as trustworthy as the grounded, tightly-scoped tools you hand it: a Genie tool bound to our governed tables so it answers from real numbers, and UI-action tools so it can manipulate the app instead of just describing it. Most of our agent work was tool design and data-grounding, not prompt-wrangling.
What's next
- A Travel-time-to-care layer (modeled drive-minutes to the nearest facility) as a first-class insight layer and optimizer input.
- Make the Insight Layers ranges a global filter that constrains the Build / Upgrade / MMU candidate sets — "only plan for hexes more than 60 minutes from care."
- Let the copilot drive the levers: ask PoshanNiti "where should we build 3 maternal clinics in Bihar?" and have it run the optimizer and highlight the answer on the map.
- A norm-aware, budget-aware mode that bakes in the actual NHM rules — 1 MMU per 10 lakh population, a cap of 5 per district, ₹24 lakh (₹28 lakh in NE/J&K/HP) per unit — and, given a rupee envelope, returns the build/upgrade/MMU mix that maximizes people served. That turns the 2026 guidelines straight into a costed deployment plan.
Built With
- agentbricks
- genie
- lakebase
- lakehouse
- openai-realtime
Log in or sign up for Devpost to join the conversation.