Downloads · 30 days
14
4% of all-time downloads
tojpaj/legal-aid-routing-model
legal-aid-routing-model is a text classification model from tojpaj. Use it when you need a label for a piece of text. The card lists the license as cc-by-4.0.
Built for the Adaption AutoScientist Challenge — Legal Category, Round 1 🏆 This project would not exist without Adaption and its AutoScientist platform. The quality leap that made this model work — a D-to-A jump in t…
Downloads · 30 days
14
4% of all-time downloads
All-time downloads
340
Public
Parameters
67M
512 MB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors490 MB · 95%
From the Hugging Face model README
Built for the Adaption AutoScientist Challenge — Legal Category, Round 1
🏆 This project would not exist without Adaption and its AutoScientist platform. The quality leap that made this model work — a D-to-A jump in training-data quality — was done entirely by AutoScientist, automatically. See below.
⚡ The multilingual Gemma 4 LoRA adapter, the RAG grounded-answer layer, and the voice-input transcription in this project are all powered by Together AI — making large-model inference accessible, affordable, and fast.
Every legal aid NGO faces the same crisis: far more people need help than there are specialists to serve them. The triage step — reading each intake submission and deciding which practice area it belongs to (housing? family? domestic violence? immigration?) — is done manually, case by case, by a caseworker who already has a full load.
This creates a queue. Cases sit in a generic backlog waiting to be read and routed. For most matters, a delay of a day or two is an inconvenience. For a subset of cases, it is catastrophic:
The routing decision itself is not a specialist task — it takes a trained caseworker about 30 seconds to read a description and assign a category. But those seconds add up across hundreds of daily intakes. The bottleneck is not legal reasoning; it is triage volume.
This model reads the client's own words — exactly as they would write them on an intake form or speak them at a walk-in clinic — and instantly predicts which of 16 practice areas the case belongs to, so it can be routed to the right specialist queue without a human reading it first.
"My landlord hasn't fixed the heating and now says I owe back rent."
↓ model ↓
housing (82%) • courts (7%) • consumer (4%)
That 82%-confidence routing fires in under 50 ms on CPU. The specialist for housing law sees the case before the intake worker even closes the browser tab.
| Who | Situation | How this helps |
|---|---|---|
| Legal aid NGO | 300 intake submissions a day, 4 housing specialists, 2 family specialists, 1 immigration specialist | Auto-route all 300 at submission time; each specialist's queue fills only with their cases |
| Domestic violence survivor | Needs a restraining order, terrified, submitting a form online at midnight | Case is flagged domestic_violence and moves to the top of the urgent queue immediately |
| Elderly client at walk-in clinic | Can't type; caseworker holds up a tablet and asks them to speak | Voice → Whisper → classifier in the same 3-second pipeline; caseworker sees the routing before the client finishes talking |
| Hindi-speaking client in India | Describes the problem in Hindi on a web form | Gemma 4 multilingual adapter reads the Hindi, routes it, returns a preliminary analysis in Hindi, cites BNS/BNSS sections |
| Client asking "what are my rights?" | Wants to know what Indian law says before seeing a lawyer | RAG layer retrieves and cites the exact sections of the Bharatiya Nyaya Sanhita / BNSS / BSA that apply, grounded on real statute text |
| Legal tech developer | Building an intake system for a new NGO or legal aid app | Drop in the pre-trained classifier as a first-pass router; use the RAG module as a statute-grounding layer |
The system is designed for the linguistic and literacy reality of who legal aid actually serves:
bge-m3 embedder)The AutoScientist Challenge asked for solutions to "fast-track resolution" in the legal domain. This system addresses the resolution bottleneck at its earliest, highest-leverage point: the moment a client first describes their problem. Every second saved in triage is a second added to the specialist's time with the client. For time-sensitive cases, routing in seconds versus hours is not a marginal improvement — it is the difference between getting help in time and not.
Legal-aid intake data is inherently messy. Real posts from people in crisis are short, emotional, vague, full of abbreviations, missing context — the kind of text that confuses classifiers trained on clean benchmarks. Before AutoScientist, the raw LegalBench data had a quality score of 4.0 / 10 (Grade D, 7.6th percentile) — low-quality prompts, near-zero completion quality (avg 1.02 / 10).
AutoScientist — Adaption's automated AI-scientist platform — transformed that dataset without any manual prompt engineering:
| Before AutoScientist | After AutoScientist | Gain | |
|---|---|---|---|
| Overall quality score | 4.0 / 10 (Grade D) | 9.3 / 10 (Grade A) | +132.5% |
| Quality percentile | 7.6th | 57.7th | |
| Message quality (avg) | 6.81 / 10 | 9.05 / 10 | +32.9% |
| Completion quality (avg) | 1.02 / 10 | 9.54 / 10 | +835.3% |
The enhanced_prompt column AutoScientist produced became the actual training signal for this model. The +11.2% macro-F1 improvement over the TF-IDF baseline — which matters enormously for rare practice areas like education, benefits, and immigration where clients most need help — is a direct consequence of that data quality lift.
Without AutoScientist, we'd be training on Grade-D data. The model would be training on noise. AutoScientist is what turned this from a low-quality experiment into a submission-ready system.
Adaption built AutoScientist to act as an automated research scientist for AI data: it analyses your dataset, hypothesises improvements, runs controlled experiments, and selects the transformations that verifiably improve training quality — all without you writing a single data-cleaning script. You bring a CSV; it brings a Grade-A dataset.
Together AI provides the infrastructure that makes the large-model components of this project viable at low cost:
| Component | Together AI model used | Role |
|---|---|---|
| Multilingual Gemma 4 LoRA | google/gemma-4-31B-it (fine-tuned via Together) | Routing in EN/HI/PA with preliminary analysis |
| RAG grounded answers | google/gemma-4-31B-it (inference) | Statute-grounded answers citing BNS/BNSS/BSA sections |
| Voice input / accessibility | openai/whisper-large-v3 | Speech-to-text for clients who can't type (50+ languages, $0.0015/min) |
| Punjabi translation | google/gemma-4-31B-it | Gurmukhi-script translations of training data |
The DistilBERT classifier and FAISS retrieval run locally for free. Together AI is invoked only for tasks requiring large multilingual models — keeping inference costs predictable.
google/gemma-4-31B-it, openai/whisper-large-v3| Path | What |
|---|---|
model.safetensors + config.json + tokenizer | DistilBERT classifier weights (16-class routing) |
rag/rag.py | Retrieval + grounded-answer module |
rag/rag_index.faiss | FAISS cosine index over 1,059 Indian statute sections |
rag/rag_meta.parquet | Section metadata (act, section number, title, text) |
rag/build_rag_kb.py | Script to reproduce the FAISS index from scratch |
rag/demo_app.py | Full Gradio demo (routing + voice input + RAG tab) |
rag/RAG_KB.md | RAG knowledge-base documentation |
scripts/build_dataset.py | Pulls LegalBench learned_hands_*, builds train/test CSVs |
scripts/baseline.py | TF-IDF + Logistic Regression baseline |
scripts/train_model.py | Fine-tunes this DistilBERT on the AutoScientist-adapted data |
scripts/build_rag_kb.py | Builds the FAISS RAG index |
from transformers import pipeline
clf = pipeline(
"text-classification",
model="tojpaj/legal-aid-routing-model",
top_k=5,
)
# English example
result = clf("My landlord is trying to evict me without giving proper notice.")
for r in result[0]:
print(f"{r['label']:22s} {r['score']:.1%}")
# housing 82.3%
# courts 6.9%
# family 4.1%
# ...
16 practice areas: benefits · business · consumer · courts · crime · divorce · domestic_violence · education · employment · estates · family · health · housing · immigration · torts · traffic
Retrieve relevant sections from the Bharatiya Nyaya Sanhita / Nagarik Suraksha Sanhita / Sakshya Adhiniyam 2023 in English, Hindi, or Punjabi. Embedding and retrieval run locally for free; grounded summaries use the Together AI API.
pip install faiss-cpu sentence-transformers pandas pyarrow
# Optional — for Gemma 4 grounded summaries:
pip install together
import sys
sys.path.insert(0, "rag/") # path to rag.py + rag_index.faiss + rag_meta.parquet
import rag
# English
sections = rag.retrieve("My employer has not paid my wages for three months.", k=5)
for s in sections:
print(f"[{s['act']} §{s['section_number']}] {s['section_title']} (score: {s['score']:.3f})")
print(s["text"][:300], "\n")
# Hindi
sections = rag.retrieve("मेरे मकान मालिक ने बिना नोटिस मुझे निकाला।", k=3)
# Punjabi (Gurmukhi)
sections = rag.retrieve("ਮੇਰੇ ਮਾਲਕ ਨੇ ਮੈਨੂੰ ਬਿਨਾਂ ਨੋਟਿਸ ਕੱਢ ਦਿੱਤਾ।", k=3)
import os, sys
os.environ["TOGETHER_API_KEY"] = "your_together_api_key"
sys.path.insert(0, "rag/")
import rag
answer, sources = rag.grounded_answer(
"My employer hasn't paid me for 3 months. What does Indian law say?",
k=5,
)
print(answer)
print("\n--- Cited sections ---")
for s in sources:
print(f" [{s['act']} §{s['section_number']}] {s['section_title']}")
Example output:
Under the Bharatiya Nyaya Sanhita 2023, withholding earned wages may
constitute criminal breach of trust (BNS §316) or cheating (BNS §318)
depending on circumstances. Additionally, BNSS §223 outlines how to
approach a magistrate to file a cognizance complaint...
--- Cited sections ---
[BNS §316] Criminal breach of trust
[BNS §318] Cheating
[BNSS §223] Cognizance of offences by magistrates
[BNS §3] Definitions
[BNSS §35] Arrest without warrant
| Model | Accuracy | Macro-F1 |
|---|---|---|
| Majority-class floor | 43.3% | 3.8% |
| TF-IDF + LogReg (baseline) | 75.2% | 53.9% |
| DistilBERT on raw data (est.) | ~68% | ~45% |
| This model — DistilBERT on AutoScientist-adapted data | 74.2% | 60.0% |
| Gain over baseline (macro-F1) | +11.2% |
Evaluated on the held-out 755-row test.csv. Macro-F1 is the key metric — accuracy is dominated by the majority "housing" class. The +11.2% macro-F1 gain means meaningfully better routing for rare practice areas where clients most need correct routing (education, benefits, immigration, domestic violence).
A LoRA adapter for google/gemma-4-31B-it (fine-tuned via Together AI) extends routing to Hindi and Punjabi with a short preliminary analysis. Training data: 2,898 rows = 1,000 EN + 1,000 HI + 898 PA — all sourced from the AutoScientist enhanced_prompt, not the raw pre-adaptation text.
MuRIL cross-lingual transfer experiment (zero-shot Hindi/Punjabi):
| Test set | Seen in training? | Accuracy | Macro-F1 |
|---|---|---|---|
| English | yes | 48.7% | 6.6% |
| Hindi | never seen | 45.4% | 5.0% |
| Punjabi | never seen | 39.9% | 3.6% |
Transfer is real — Hindi accuracy tracks within ~3 pts of English with zero Hindi training examples.
rag/)The classifier is trained on US LegalBench content (honestly documented). The RAG layer patches this: retrieval only needs embeddable statute text — no intake labels — so the RAG layer is genuinely grounded on real Indian law, not translated US content.
Knowledge base: GSMS-B/indian-legal-sections-bns-bnss-bsa-2023 (Apache-2.0)
Embedder: BAAI/bge-m3 — multilingual (EN/HI/PA), runs locally, free.
pip install faiss-cpu sentence-transformers datasets pandas pyarrow
python rag/build_rag_kb.py
# → rag_index.faiss + rag_meta.parquet (takes ~5 min on CPU)
pip install gradio transformers torch joblib together sentence-transformers faiss-cpu
python rag/demo_app.py
Three tabs:
git clone https://huggingface.co/tojpaj/legal-aid-routing-model
cd legal-aid-routing-model
pip install transformers datasets scikit-learn torch \
sentence-transformers faiss-cpu gradio together
# 1. Rebuild the dataset from LegalBench
python scripts/build_dataset.py # → train.csv, test.csv
# 2. Run the TF-IDF baseline
python scripts/baseline.py # → baseline_model.joblib, baseline_results.json
# 3. Fine-tune DistilBERT (needs GPU, ~1 hr on T4)
python scripts/train_model.py # → model.safetensors
# 4. Rebuild the Indian-law FAISS index
python rag/build_rag_kb.py # → rag_index.faiss, rag_meta.parquet
# 5. Launch the Gradio demo
python rag/demo_app.py
| Resource | Link |
|---|---|
| AutoScientist Challenge | adaptionlabs.ai/blog/autoscientist-challenge |
| Adaption platform | adaptionlabs.ai |
| Adaption SDK docs | docs.adaptionlabs.ai |
| Together AI | together.ai |
| Together AI docs | docs.together.ai |
| Training dataset (HF) | tojpaj/legal-aid-intake-routing |
| Training dataset (Kaggle) | jjtojpaj/legal-aid-intake-routing |
| Model weights (Kaggle mirror) | jjtojpaj/legal-aid-routing-model |
| Source data | nguha/legalbench learned_hands_* (CC-BY-4.0) |
| Indian law KB | GSMS-B/indian-legal-sections-bns-bnss-bsa-2023 (Apache-2.0) |