# Sahayak — An AI Legal Assistant That Says "I Don't Know" When It Should

> Source: <https://dev.to/divyansh0208/sahayak-an-ai-legal-assistant-that-says-i-dont-know-when-it-should-42l2>
> Published: 2026-09-27 19:54:40+00:00

Legal help is expensive, jargon-heavy, and often out of reach for people who need it most. For PromptWars: Virtual (Exclusive Edition) — a hackathon by Hack2Skill — I built **Sahayak**, a RAG-based legal assistant that answers questions and summarizes documents in plain language, grounded in real context instead of confident guesses.

🔗 Live: [https://legal-ai-eight-liart.vercel.app/](https://legal-ai-eight-liart.vercel.app/)

🔗 Code: [https://github.com/Divyansh0208/Legal-AI](https://github.com/Divyansh0208/Legal-AI) (MIT)

## 
  
  
  What it does

- 
**Ask** — a tenancy, consumer-rights, or contract question. Answers are retrieved from indexed context, not hallucinated. No matching context? It says so, instead of guessing.
- 
**Upload** — a PDF (scanned or native) → plain-language summary: what kind of document it is, what it obligates you to, what's worth double-checking.
- 
**Voice** — ask by speaking, transcribed via Whisper.
Every response is grounded in retrieved context and explicit about what it can't confirm — no confident guessing when the docs don't cover something.

## 
  
  
  Architecture

The RAG hot path is intentionally thin — no framework ceremony for a single retrieval + one chat completion call:

## 
  
  
  The part I'm actually proud of: the guardrails

Anyone can wire an LLM to a text box. The parts that took real effort:

- 
**Untrusted-context system prompt** — uploaded documents and retrieved chunks are treated as*data* , never instructions. Prompt-injection resistant by design.
- 
**Real upload validation** —`python-magic` sniffs actual file bytes; a relabeled`.exe` doesn't sneak through as`.pdf` .
- 
**Rate limiting** —`slowapi` on query, upload, and voice endpoints.
- 
**Security headers** — CSP, X-Frame-Options, HSTS in production.
- 
**5 CI workflows on every push** — lint, pytest, bandit (SAST), gitleaks (secrets), pip-audit (deps), axe-core (a11y) — auto-deploy to Render/Vercel on merge to`main` .
None of that shows up in a demo GIF. All of it is why the demo GIF is trustworthy.

## 
  
  
  Stack

| Layer | Tech | 
| Backend | FastAPI | 
| LLM | Groq ( `openai/gpt-oss-120b` ) | 
| Retrieval | ChromaDB + sentence-transformers ( `all-MiniLM-L6-v2` ) | 
| Parsing | PyMuPDF, pytesseract | 
| Speech | Groq Whisper | 
| Frontend | React + Vite, Tailwind | 
| DB | SQLite | 
| Deploy | Render + Vercel | 

## 
  
  
  What's next

- Multi-language support (deferred)
- Persisted chat sessions (currently in-memory)
- More jurisdiction-specific templates
If you've hit a real legal-access gap, or want to poke holes in the grounding/refusal behavior — feedback welcome. MIT-licensed, issues/PRs open.
