Building DhanDost: an AI financial decision coach for Indian salaried professionals, designed around the things a language model must not be allowed to do
Indian salaried professionals get two kinds of financial help and neither one works.
The first is generic content — blogs, reels, calculators. It explains concepts to people whose actual question is not conceptual. Someone with a credit card balance, an EMI, a rent commitment and ₹18,000 of slack at the end of the month doesn’t need to be told what a debt avalanche is. They need to know what to do with their ₹18,000, this month.
The second is advice from someone selling a product. It’s specific, but its incentives are not aligned with the person receiving it.
The gap is personalised, numerate, non-conflicted decision support. That’s what DhanDost is: you connect your real transactions, and it helps you decide where the next rupee goes.
Which puts an LLM in an obviously useful and obviously dangerous position.
An LLM is excellent at framing a financial situation in plain language, weighing considerations, and explaining a trade-off in a way that lands. It is untrustworthy at arithmetic, and it is actively hazardous at naming financial products.
So the architecture enforces a hard split:
The LLM proposes strategy in words. Deterministic TypeScript computes every rupee.
The model never produces a number that reaches the user. It reasons about approach — pay the high-interest debt first, hold more buffer, split between the two — and the actual allocation, the interest saved, the months to payoff, the projected balance are all computed in code from the user’s real data.
This wasn’t a performance optimisation. It was a user-harm decision. If a coaching product tells someone to move ₹40,000 and the figure is a hallucination, the damage is direct and financial. A wrong number in this product is not a bad answer; it’s a bad outcome in someone’s actual life. The one class of failure I was not willing to ship was a plausible-sounding wrong rupee figure. Removing the model from the arithmetic path removes that failure mode structurally rather than probabilistically — and structural beats probabilistic when the downside is someone’s money.
The second constraint is regulatory. India’s advisory regime draws a bright line around recommending specific financial products, and an unlicensed AI coach naming a mutual fund is on the wrong side of it. So a scrubbing layer strips named financial products from model output before it reaches the user. DhanDost tells you what kind of move makes sense for your situation. It does not tell you which fund to buy. That boundary is enforced in code, not in a system prompt, because a system prompt is a request and a code path is a guarantee.
Both decisions cost capability. A less constrained product would feel more impressive in a demo. I took the trade deliberately: in personal finance, a product that is confidently wrong is worse than one that is usefully narrow.
The other product question was what a “recommendation” should even look like.
A single recommendation invites two failure modes — the user either follows it without understanding it, or rejects it and gets nothing. Neither builds the judgment the product is supposed to be developing.
So DhanDost presents Three Paths: Safer, Balanced, Bolder. Same situation, same real numbers, three legitimate strategies with the trade-off made explicit. The user chooses.
This is a deliberate stance about what the product is for. Financial decisions are risk-preference decisions, and risk preference is not something a model can infer well from transaction data — it depends on job security, family obligations, temperament, things not in the ledger. Presenting three defensible options and naming what each costs treats the user as the decision-maker and the product as the analyst. It also makes the reasoning inspectable: seeing the Bolder path next to the Safer one teaches the trade-off in a way a single answer never does.
None of the above matters if the underlying data is wrong. Indian bank transaction descriptions are close to hostile — UPI strings, cryptic merchant codes, inconsistent formats.
I built categorisation as a layered engine rather than an LLM call, in deliberate order of cost and reliability: exact known-merchant mappings first, then UPI-suffix extraction, then keyword rules, then an LLM sweep for what survives, then a user-feedback loop where corrections improve future categorisation.
The design principle: use the cheapest deterministic method that can settle a case, and reserve the model for genuine ambiguity. That’s faster, cheaper, more predictable — and the feedback loop means the system’s dependence on the model decreases with use.
A related case that only showed up in real data: self-transfers. Money moving between a user’s own accounts is not income and not spending, but naively it registers as both, which inflates every number downstream. Detecting and excluding those was a small feature and a large correctness gain — the kind of thing you only find by running your own real transactions through it.
A working, multi-user product: authentication with per-user data isolation, transaction ingestion and categorisation, the Three Paths engine, a two-stage lifecycle for debt paydown and savings allocation, self-transfer detection, and a conversational AI coach for follow-up questions.
It was built with AI-assisted development — Lovable for the React/Tailwind front end, Supabase (Postgres and Deno edge functions) for the backend, OpenAI for the reasoning layer. I state that plainly because it’s the point, not a caveat. I’m a product person who can take an idea to a shipped, working product without an engineering team. Every product decision here — the deterministic-computation boundary, the regulatory scrubbing layer, the Three Paths framing, the layered categorisation order, what not to build — is mine. The implementation was AI-assisted. That combination is precisely the operating model I want to be hired for.
I’d rather state the limits than let them be discovered.