How I built an RAG engine for Singapore Laws

Published: (February 6, 2026 at 11:50 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

Cover image for How I built an RAG engine for Singapore Laws

Hi everyone!

I’m a student developer. Recently, I created Explore Singapore, a RAG‑based search engine that scrapes about 20,000 pages of Singaporean government acts and laws.

After releasing the MVP, I received essential feedback about hallucinations and query depth. I took that feedback, focused on improvements, and just released Version 2.

The Design & UI

I aimed to avoid a dull government website.

Design: Heavily inspired by Apple’s minimalist style.
Tech: Custom frontend interacting with a Python backend.

The V2 Engineering Overhaul

The community challenged me on three main points. Here’s how I addressed them:

1. The “Personality” Fix

Issue: I use a “Triple Failover” system with three models as backup. When the main model failed, the backups sounded entirely different.

Solution: Added Dynamic System Instructions. When the backend switches to Model B, it uses a specific prompt designed for Model B’s features, making it mimic the structure and tone of the primary model. The user never notices the change.

2. The “Deep Search” Fix

Issue: A simple semantic search for “Starting a business” misses related laws like “Tax” or “Labor” acts.

Solution: Implemented Multi‑Query Retrieval (MQR). An LLM now intercepts your query, breaks it down into sub‑intents (e.g., “Business Registration,” “Corporate Tax,” “Employment Rules”), searches for all of them simultaneously, and combines the results.

Result: Much richer, context‑aware answers.

3. The “Hallucination” Fix

Issue: Garbage In, Garbage Out. If FAISS retrieves a bad document, the LLM produces inaccurate information.

Solution: Added a Cross‑Encoder Re‑Ranking layer.

  1. FAISS grabs the top 10 results.
  2. A specialized Cross‑Encoder model evaluates them for relevance.
  3. Irrelevant parts are removed before they reach the Chat LLM.

The Tech Stack

  • Embeddings: BGE‑M3 (running locally)
  • Vector DB: FAISS
  • Backend: Python + Custom Triple‑Model Failover (runs on Hugging Face)
  • Logic: Multi‑Query + Re‑Ranking (new in V2)

Try it out

I am still learning. I’d love to hear your thoughts on the new logic.

Feedback on the platform—especially regarding failover speed—is welcome! 👇

0 views
Back to Blog

Related posts

Read more »

The Origin of the Lettuce Project

Two years ago, Jason and I started what became known as the BLT Lettuce Project with a very simple goal: make it easier for newcomers to OWASP to find their way...