# mustafadngl/regulatory-rag architecture

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

- Interactive diagram: https://gitdiagram.com/mustafadngl/regulatory-rag
- Repository: https://github.com/mustafadngl/regulatory-rag

## Overview

Regulatory RAG ingests EU regulatory documents into a cited, searchable corpus, then answers questions using retrieved extracts and an OpenAI-compatible model. Its separate golden-set evaluator measures retrieval, citations, and refusals and applies a quality gate. The main paths are visible in the sampled API, ingestion, RAG, and evaluation code. README capabilities also inform the corpus-source and evaluation branches; unsampled subsystem details are not inferred. Although the README diagram mentions Redis, no sampled runtime code shows it in use.

Main entry points: [`app/rag.py`](https://github.com/mustafadngl/regulatory-rag/blob/main/app/rag.py) (RAG service), [`app/main.py`](https://github.com/mustafadngl/regulatory-rag/blob/main/app/main.py) (App setup), [`app/corpus/ingest.py`](https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/ingest.py) (Ingestion command), [`app/evaluation/run.py`](https://github.com/mustafadngl/regulatory-rag/blob/main/app/evaluation/run.py) (Evaluation runner)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["Question API"]
  node_ask["Ask endpoint<br/>[ask.py]"]
  node_health["Health endpoint<br/>[health.py]"]
  node_app["App setup<br/>[main.py]"]
end

subgraph group_corpus["Corpus ingestion"]
  node_ingest["Ingestion command<br/>[ingest.py]"]
  node_cellar["EU Cellar"]
  node_parser["Regulation parser<br/>[eurlex.py]"]
  node_chunker["Structure chunker<br/>[chunking.py]"]
  node_models["Article and chunk models<br/>[models.py]"]
end

subgraph group_answering["Retrieval and answering"]
  node_rag["RAG service<br/>[rag.py]"]
  node_embedder["Embedding client<br/>[embeddings.py]"]
  node_store[("Chunk store<br/>[store.py]")]
  node_chat["Chat client<br/>[generation.py]"]
  node_text["Text normalization<br/>[text.py]"]
end

subgraph group_evaluation["Quality evaluation"]
  node_golden["Golden questions<br/>[golden_set.yaml]"]
  node_runner["Evaluation runner<br/>[run.py]"]
  node_metrics["Quality metrics<br/>[metrics.py]"]
  node_report["Evaluation report<br/>[report.json]"]
end

subgraph group_shared["Shared infrastructure"]
  node_upstream["Provider HTTP client<br/>[upstream.py]"]
  node_limiter["Rate limiter<br/>[rate_limit.py]"]
end

node_user(("Questioner"))
node_postgres[("PostgreSQL and pgvector")]
node_provider["Model provider"]

node_user -->|"submits question"| node_ask
node_ask -->|"calls answer"| node_rag
node_app -->|"registers route"| node_ask
node_app -->|"registers route"| node_health
node_app -->|"builds service"| node_rag
node_app -->|"constructs store"| node_store
node_app -->|"constructs client"| node_embedder
node_app -->|"constructs client"| node_chat
node_rag -->|"embeds query"| node_embedder
node_rag -->|"searches chunks"| node_store
node_rag -->|"generates answer"| node_chat
node_rag -->|"normalizes answer"| node_text
node_store -->|"reads and writes"| node_postgres
node_ingest -->|"fetches regulation"| node_cellar
node_ingest -->|"parses document"| node_parser
node_parser -->|"creates articles"| node_models
node_ingest -->|"chunks articles"| node_chunker
node_chunker -->|"creates chunks"| node_models
node_ingest -->|"embeds passages"| node_embedder
node_ingest -->|"stores chunks"| node_store
node_embedder -->|"posts embeddings"| node_upstream
node_chat -->|"posts completions"| node_upstream
node_upstream -->|"paces requests"| node_limiter
node_upstream -->|"sends HTTP requests"| node_provider
node_runner -->|"loads questions"| node_golden
node_runner -->|"evaluates answers"| node_rag
node_runner -->|"scores outcomes"| node_metrics
node_runner -->|"writes report"| node_report

click node_ask "https://github.com/mustafadngl/regulatory-rag/blob/main/app/api/ask.py"
click node_health "https://github.com/mustafadngl/regulatory-rag/blob/main/app/api/health.py"
click node_app "https://github.com/mustafadngl/regulatory-rag/blob/main/app/main.py"
click node_ingest "https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/ingest.py"
click node_parser "https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/eurlex.py"
click node_chunker "https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/chunking.py"
click node_models "https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/models.py"
click node_rag "https://github.com/mustafadngl/regulatory-rag/blob/main/app/rag.py"
click node_embedder "https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/embeddings.py"
click node_store "https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/store.py"
click node_chat "https://github.com/mustafadngl/regulatory-rag/blob/main/app/generation.py"
click node_text "https://github.com/mustafadngl/regulatory-rag/blob/main/app/text.py"
click node_upstream "https://github.com/mustafadngl/regulatory-rag/blob/main/app/upstream.py"
click node_limiter "https://github.com/mustafadngl/regulatory-rag/blob/main/app/rate_limit.py"
click node_golden "https://github.com/mustafadngl/regulatory-rag/blob/main/evaluation/golden_set.yaml"
click node_runner "https://github.com/mustafadngl/regulatory-rag/blob/main/app/evaluation/run.py"
click node_metrics "https://github.com/mustafadngl/regulatory-rag/blob/main/app/evaluation/metrics.py"
click node_report "https://github.com/mustafadngl/regulatory-rag/blob/main/evaluation/report.json"

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_ask,node_health,node_app toneBlue
class node_ingest,node_cellar,node_parser,node_chunker,node_models,node_postgres toneAmber
class node_rag,node_embedder,node_store,node_chat,node_text toneMint
class node_golden,node_runner,node_metrics,node_report toneRose
class node_upstream,node_limiter,node_user,node_provider toneIndigo
```

## Components

### Question API

- [Ask endpoint](https://github.com/mustafadngl/regulatory-rag/blob/main/app/api/ask.py): `app/api/ask.py`
- [Health endpoint](https://github.com/mustafadngl/regulatory-rag/blob/main/app/api/health.py): `app/api/health.py`
- [App setup](https://github.com/mustafadngl/regulatory-rag/blob/main/app/main.py): `app/main.py`

### Corpus ingestion

- [Ingestion command](https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/ingest.py): `app/corpus/ingest.py`
- **EU Cellar**
- [Regulation parser](https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/eurlex.py): `app/corpus/eurlex.py`
- [Structure chunker](https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/chunking.py): `app/corpus/chunking.py`
- [Article and chunk models](https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/models.py): `app/corpus/models.py`

### Retrieval and answering

- [RAG service](https://github.com/mustafadngl/regulatory-rag/blob/main/app/rag.py): `app/rag.py`
- [Embedding client](https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/embeddings.py): `app/corpus/embeddings.py`
- [Chunk store](https://github.com/mustafadngl/regulatory-rag/blob/main/app/corpus/store.py): `app/corpus/store.py`
- [Chat client](https://github.com/mustafadngl/regulatory-rag/blob/main/app/generation.py): `app/generation.py`
- [Text normalization](https://github.com/mustafadngl/regulatory-rag/blob/main/app/text.py): `app/text.py`

### Quality evaluation

- [Golden questions](https://github.com/mustafadngl/regulatory-rag/blob/main/evaluation/golden_set.yaml): `evaluation/golden_set.yaml`
- [Evaluation runner](https://github.com/mustafadngl/regulatory-rag/blob/main/app/evaluation/run.py): `app/evaluation/run.py`
- [Quality metrics](https://github.com/mustafadngl/regulatory-rag/blob/main/app/evaluation/metrics.py): `app/evaluation/metrics.py`
- [Evaluation report](https://github.com/mustafadngl/regulatory-rag/blob/main/evaluation/report.json): `evaluation/report.json`

### Shared infrastructure

- [Provider HTTP client](https://github.com/mustafadngl/regulatory-rag/blob/main/app/upstream.py): `app/upstream.py`
- [Rate limiter](https://github.com/mustafadngl/regulatory-rag/blob/main/app/rate_limit.py): `app/rate_limit.py`

### Other components

- **Questioner**
- **PostgreSQL and pgvector**
- **Model provider**

## Connections

- Questioner → Ask endpoint: submits question (evidence: `README.md`)
- Ask endpoint → RAG service: calls answer (evidence: `app/api/ask.py`)
- App setup → Ask endpoint: registers route (evidence: `app/main.py`)
- App setup → Health endpoint: registers route (evidence: `app/main.py`)
- App setup → RAG service: builds service (evidence: `app/main.py`)
- App setup → Chunk store: constructs store (evidence: `app/main.py`)
- App setup → Embedding client: constructs client (evidence: `app/main.py`)
- App setup → Chat client: constructs client (evidence: `app/main.py`)
- RAG service → Embedding client: embeds query (evidence: `app/rag.py`)
- RAG service → Chunk store: searches chunks (evidence: `app/rag.py`)
- RAG service → Chat client: generates answer (evidence: `app/rag.py`)
- RAG service → Text normalization: normalizes answer (evidence: `app/rag.py`)
- Chunk store → PostgreSQL and pgvector: reads and writes (evidence: `app/corpus/store.py`)
- Ingestion command → EU Cellar: fetches regulation (evidence: `README.md`)
- Ingestion command → Regulation parser: parses document (evidence: `app/corpus/ingest.py`)
- Regulation parser → Article and chunk models: creates articles (evidence: `app/corpus/eurlex.py`)
- Ingestion command → Structure chunker: chunks articles (evidence: `app/corpus/ingest.py`)
- Structure chunker → Article and chunk models: creates chunks (evidence: `app/corpus/chunking.py`)
- Ingestion command → Embedding client: embeds passages (evidence: `app/corpus/ingest.py`)
- Ingestion command → Chunk store: stores chunks (evidence: `app/corpus/ingest.py`)
- Embedding client → Provider HTTP client: posts embeddings (evidence: `app/corpus/embeddings.py`)
- Chat client → Provider HTTP client: posts completions (evidence: `app/generation.py`)
- Provider HTTP client → Rate limiter: paces requests (evidence: `app/upstream.py`)
- Provider HTTP client → Model provider: sends HTTP requests (evidence: `app/upstream.py`)
- Evaluation runner → Golden questions: loads questions (evidence: `app/evaluation/run.py`)
- Evaluation runner → RAG service: evaluates answers (evidence: `app/evaluation/run.py`)
- Evaluation runner → Quality metrics: scores outcomes (evidence: `app/evaluation/run.py`)
- Evaluation runner → Evaluation report: writes report (evidence: `app/evaluation/run.py`)
