DEV Community

Malik Ali Hassan
Malik Ali Hassan

Posted on

I Built a RAG Assistant That Explains Your Electricity Bill — Without Letting the AI Invent Numbers

Pakistani electricity bills are hard to read even when you're technical. The total jumps month to month, and the bill itself doesn't really explain why — slabs, categories, rates, and surcharges all blur together. Most people just pay it and move on.

I built BijliCheck at a hackathon to attack that confusion directly: a Bill Checker web app with an "Ask about your bill" AI assistant box. You check your bill, then you ask it questions about it in plain English — "why did my bill jump so much?", "how do I avoid this next time?" — and it answers using your actual numbers, not generic advice.

How it works

There are two halves, and the order matters.

First, the Bill Checker. You open the site, fill in your usage, and click "Check my bill." That produces your computed bill numbers: units, category, rate, and total. Nothing about the assistant works without this step, because the assistant's job is to explain these numbers — not to guess at bills in general.

Second, the assistant. It uses retrieval-augmented generation (RAG), in three steps:

  1. Retrieve. Your question is matched against a small local knowledge base of slab rules and billing facts, using keyword-based matching. This runs instantly in the browser — no API call for this step at all.
  2. Augment. The matched facts are combined with your computed bill numbers (units, category, rate, total) into a single prompt.
  3. Generate. That prompt goes to a free LLM (Groq), which writes a plain-English answer grounded in what was retrieved and your numbers.

The user sees the retrieved reference facts listed first, then the generated answer. That ordering is deliberate: you can see what the answer is based on before you read the answer itself.

The design decision that matters most

The assistant is not allowed to invent tariff numbers that were not given to it. That's the whole point of the RAG setup here. A plain chatbot asked about electricity bills will happily produce confident-sounding rates that may be wrong — and a wrong number on a bill is worse than no answer at all. By forcing every answer through retrieved facts plus the user's own computed numbers, the system trades fluency for grounding. The answer might be less smooth than a free-form chat, but it can't hallucinate a slab rate.

There's a second, quieter lesson in the retrieval step: RAG doesn't have to mean a vector database. For a small, well-understood set of facts — slab rules and billing facts — keyword matching over a local knowledge base is fast, free, and runs entirely in the browser. The fancy version of a technique is not always the right version. Match the retrieval method to the size of your knowledge base.

The architecture is deliberately boring

The whole thing is HTML and JavaScript — no framework — hosted on Vercel for free, connected directly to the GitHub repository. The one piece that isn't static is a single tiny serverless function in the api/ folder. It exists for one reason: the API key has to stay secret, and a purely static host can't keep a secret. So the browser does the retrieval, and the serverless function makes the one call that needs the key.

Total setup cost: $0, on Groq's free tier, in about 15 minutes. If the Ask box ever says "offline mode," it means that serverless endpoint isn't reachable — usually the API key wasn't set or the deployment wasn't redeployed after adding it. That's a deployment detail, but it's the kind of thing that eats an hour at a hackathon if you don't know where to look.

Three lessons I'd pass on

  1. Ground the model before you prompt it. Retrieval first, generation second. The order is the safety mechanism.
  2. Show your sources. Listing the retrieved facts before the answer lets the user judge the answer instead of just trusting it.
  3. Keep the demo shippable. A static frontend, one serverless function, and a free-tier model got a working hackathon demo live at zero cost. Complexity can come later, after the idea is proven.

BijliCheck started as a hackathon demo, but the pattern generalises: any domain where the model must not invent numbers — bills, tariffs, schedules, policies — benefits from the same shape. Compute the real numbers first, retrieve the real rules, and only then let the model talk.


Malik Ali Hassan — .NET & full-stack developer, final-year Software Engineering student. I build Python automation, AI assistants, and web apps.

Top comments (1)

Collapse
 
ontomato profile image
ontomato •

Invented bill numbers are worse than a clean refuse.

From my experience a retrieval hit is only a candidate, not permission to answer. The reply has to open the source lines that hold the figure. If those lines are missing or conflict, the run abstains instead of filling gaps from nearby chunks.