# bavuong2005/legal-qa-system architecture

> Architecture diagram of the GitHub repository bavuong2005/legal-qa-system, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/bavuong2005/legal-qa-system
- Repository: https://github.com/bavuong2005/legal-qa-system

## Overview

RoadLawQA turns Vietnamese traffic-law text into cited answers and multiple-choice quizzes. Its documented content workflow chunks statutes into context-enriched records, embeds and indexes them, then retrieves and reranks relevant passages for generation. Users can start through the Streamlit chat or quiz tabs, or the CLI pipelines; both ultimately use shared retrieval and Gemini generation. The README also documents hybrid BM25/dense search, adjustable result counts, source attribution, and performance metrics. Some source excerpts are partial, so the graph omits uncertain internal wiring while retaining documented product capabilities.

Main entry points: [`backend/retriever_custom.py`](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py) (Hybrid retrieval), [`backend/generator.py`](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/generator.py) (Answer and quiz generator), [`frontend/app.py`](https://github.com/bavuong2005/legal-qa-system/blob/main/frontend/app.py) (Streamlit chat and quiz), [`backend/rag_qa.py`](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/rag_qa.py) (QA pipeline)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_prep["Law preparation"]
  node_raw["Raw statutes"]
  node_chunker["Hierarchical chunker<br/>[clean_and_split.py]"]
  node_chunks["Enriched chunks"]
  node_indexer["Index builder<br/>[build_index.py]"]
end

subgraph group_search["Retrieval"]
  node_weaviate[("LawChunks store<br/>[docker-compose.yml]")]
  node_retriever["Hybrid retrieval"]
  node_bm25["BM25 search"]
  node_dense["Dense search"]
  node_alpha["Alpha tuning"]
  node_reranker["Cross-encoder rerank"]
  node_context["Ranked legal context"]
end

subgraph group_gen["Generation"]
  node_qa["QA pipeline<br/>[rag_qa.py]"]
  node_quizpipe["Quiz pipeline<br/>[rag_quiz.py]"]
  node_generator["Answer and quiz generator<br/>[generator.py]"]
  node_quizprompt["Quiz prompt<br/>[prompts.py]"]
  node_gemini{{"Gemini service"}}
end

subgraph group_ui["User interfaces"]
  node_frontend["Streamlit chat and quiz<br/>[app.py]"]
  node_answer["Cited answer"]
  node_quiz["Quiz questions"]
end

node_user(("Questioner"))

node_user -->|"asks or selects"| node_frontend
node_user -.->|"asks via CLI"| node_qa
node_user -.->|"requests via CLI"| node_quizpipe
node_raw -->|"reads statutes"| node_chunker
node_chunker -->|"writes chunks"| node_chunks
node_chunks -->|"reads chunks"| node_indexer
node_indexer -->|"embeds and indexes"| node_weaviate
node_frontend -->|"retrieves context"| node_retriever
node_frontend -->|"generates quiz"| node_generator
node_frontend -->|"generates answer"| node_generator
node_qa -->|"retrieves context"| node_retriever
node_qa -->|"generates answer"| node_generator
node_quizpipe -->|"retrieves chunks"| node_retriever
node_quizpipe -->|"generates quiz"| node_generator
node_retriever -->|"queries vectors"| node_weaviate
node_retriever -->|"scores keywords"| node_bm25
node_retriever -->|"searches vectors"| node_dense
node_retriever -->|"tunes weighting"| node_alpha
node_retriever -->|"reranks candidates"| node_reranker
node_retriever -->|"returns top results"| node_context
node_generator -->|"generates text"| node_gemini
node_generator -->|"formats quiz prompt"| node_quizprompt
node_generator -->|"returns answer and sources"| node_answer
node_generator -->|"returns quiz"| node_quiz
node_frontend -->|"displays citations and metrics"| node_answer
node_frontend -->|"displays questions"| node_quiz

click node_raw "https://github.com/bavuong2005/legal-qa-system/tree/main/data/raw"
click node_chunker "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/clean_and_split.py"
click node_chunks "https://github.com/bavuong2005/legal-qa-system/tree/main/data/processed"
click node_indexer "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/build_index.py"
click node_weaviate "https://github.com/bavuong2005/legal-qa-system/blob/main/docker/docker-compose.yml"
click node_retriever "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py"
click node_bm25 "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py"
click node_dense "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py"
click node_alpha "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py"
click node_reranker "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py"
click node_context "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py"
click node_qa "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/rag_qa.py"
click node_quizpipe "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/rag_quiz.py"
click node_generator "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/generator.py"
click node_quizprompt "https://github.com/bavuong2005/legal-qa-system/blob/main/backend/prompts.py"
click node_frontend "https://github.com/bavuong2005/legal-qa-system/blob/main/frontend/app.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_raw,node_chunker,node_chunks,node_indexer toneBlue
class node_weaviate,node_retriever,node_bm25,node_dense,node_alpha,node_reranker,node_context toneAmber
class node_qa,node_quizpipe,node_generator,node_quizprompt,node_gemini toneMint
class node_frontend,node_answer,node_quiz toneRose
class node_user toneIndigo
```

## Components

### Law preparation

- [Raw statutes](https://github.com/bavuong2005/legal-qa-system/tree/main/data/raw): `data/raw`
- [Hierarchical chunker](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/clean_and_split.py): `backend/clean_and_split.py`
- [Enriched chunks](https://github.com/bavuong2005/legal-qa-system/tree/main/data/processed): `data/processed`
- [Index builder](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/build_index.py): `backend/build_index.py`

### Retrieval

- [LawChunks store](https://github.com/bavuong2005/legal-qa-system/blob/main/docker/docker-compose.yml): `docker/docker-compose.yml`
- [Hybrid retrieval](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py): `backend/retriever_custom.py`
- [BM25 search](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py): `backend/retriever_custom.py`
- [Dense search](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py): `backend/retriever_custom.py`
- [Alpha tuning](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py): `backend/retriever_custom.py`
- [Cross-encoder rerank](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py): `backend/retriever_custom.py`
- [Ranked legal context](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/retriever_custom.py): `backend/retriever_custom.py`

### Generation

- [QA pipeline](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/rag_qa.py): `backend/rag_qa.py`
- [Quiz pipeline](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/rag_quiz.py): `backend/rag_quiz.py`
- [Answer and quiz generator](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/generator.py): `backend/generator.py`
- [Quiz prompt](https://github.com/bavuong2005/legal-qa-system/blob/main/backend/prompts.py): `backend/prompts.py`
- **Gemini service**

### User interfaces

- [Streamlit chat and quiz](https://github.com/bavuong2005/legal-qa-system/blob/main/frontend/app.py): `frontend/app.py`
- **Cited answer**
- **Quiz questions**

### Other components

- **Questioner**

## Connections

- Questioner → Streamlit chat and quiz: asks or selects
- Questioner → QA pipeline: asks via CLI
- Questioner → Quiz pipeline: requests via CLI
- Raw statutes → Hierarchical chunker: reads statutes
- Hierarchical chunker → Enriched chunks: writes chunks
- Enriched chunks → Index builder: reads chunks
- Index builder → LawChunks store: embeds and indexes
- Streamlit chat and quiz → Hybrid retrieval: retrieves context
- Streamlit chat and quiz → Answer and quiz generator: generates quiz
- Streamlit chat and quiz → Answer and quiz generator: generates answer
- QA pipeline → Hybrid retrieval: retrieves context
- QA pipeline → Answer and quiz generator: generates answer
- Quiz pipeline → Hybrid retrieval: retrieves chunks
- Quiz pipeline → Answer and quiz generator: generates quiz
- Hybrid retrieval → LawChunks store: queries vectors
- Hybrid retrieval → BM25 search: scores keywords
- Hybrid retrieval → Dense search: searches vectors
- Hybrid retrieval → Alpha tuning: tunes weighting
- Hybrid retrieval → Cross-encoder rerank: reranks candidates
- Hybrid retrieval → Ranked legal context: returns top results
- Answer and quiz generator → Gemini service: generates text
- Answer and quiz generator → Quiz prompt: formats quiz prompt
- Answer and quiz generator → Cited answer: returns answer and sources
- Answer and quiz generator → Quiz questions: returns quiz
- Streamlit chat and quiz → Cited answer: displays citations and metrics
- Streamlit chat and quiz → Quiz questions: displays questions
