# breaseabrol/rag-system architecture

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

- Interactive diagram: https://gitdiagram.com/breaseabrol/rag-system
- Repository: https://github.com/breaseabrol/rag-system

## Overview

This is a local hybrid RAG application: users query ingested documents through a terminal-style React UI, while a synchronous FastAPI backend retrieves relevant chunks, fuses lexical and vector rankings, and generates cited answers. A separate ingest endpoint loads URLs, chunks and embeds their content, and stores it for later retrieval. The graph follows shown calls and README-documented integrations; unsampled implementation details are represented only where the README supports them.

Main entry points: [`backend/app/ingestion/pipeline.py`](https://github.com/breaseabrol/rag-system/blob/main/backend/app/ingestion/pipeline.py) (Ingest pipeline), [`backend/app/core/retrieval.py`](https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/retrieval.py) (Hybrid retrieval), [`backend/app/main.py`](https://github.com/breaseabrol/rag-system/blob/main/backend/app/main.py) (FastAPI app), [`backend/app/api/routes_query.py`](https://github.com/breaseabrol/rag-system/blob/main/backend/app/api/routes_query.py) (Query endpoint)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Query interface"]
  node_console["Query console<br/>[App.tsx]"]
  node_api_client["Query client<br/>[client.ts]"]
end

subgraph group_api["Backend API"]
  node_fastapi["FastAPI app<br/>[main.py]"]
  node_query_route["Query endpoint<br/>[routes_query.py]"]
  node_ingest_route["Ingest endpoint<br/>[routes_ingest.py]"]
  node_schemas["API schemas<br/>[model.py]"]
  node_db_session["DB sessions<br/>[session.py]"]
end

subgraph group_ingestion["Ingestion"]
  node_loader["URL loader<br/>[loader.py]"]
  node_pipeline["Ingest pipeline<br/>[pipeline.py]"]
  node_chunker["Structure-aware chunker<br/>[chunking.py]"]
  node_embedder["Local embeddings<br/>[embeddings.py]"]
  node_db_models[("Document and chunk records<br/>[models.py]")]
end

subgraph group_retrieval["Retrieval and generation"]
  node_retriever["Hybrid retrieval<br/>[retrieval.py]"]
  node_bm25["BM25 index<br/>[lexical_index.py]"]
  node_vector_search["Vector search<br/>[vector_store.py]"]
  node_generator["Answer generation<br/>[generation.py]"]
end

node_user(("User"))
node_postgres[("PostgreSQL / pgvector")]
node_ollama["Ollama"]
node_source_site(("Source URLs"))

node_user -->|"submits query"| node_console
node_console -->|"requests answer"| node_api_client
node_api_client -->|"POST /query"| node_fastapi
node_fastapi -->|"routes query"| node_query_route
node_query_route -->|"retrieves chunks"| node_retriever
node_query_route -->|"generates answer"| node_generator
node_query_route -->|"uses response models"| node_schemas
node_console -->|"renders answer and sources"| node_schemas
node_user -->|"POST /ingest"| node_fastapi
node_fastapi -->|"routes ingest"| node_ingest_route
node_ingest_route -->|"ingests URL"| node_pipeline
node_ingest_route -->|"uses request models"| node_schemas
node_pipeline -->|"loads document"| node_loader
node_loader -.->|"fetches content"| node_source_site
node_pipeline -->|"chunks text"| node_chunker
node_pipeline -->|"embeds chunks"| node_embedder
node_pipeline -->|"creates records"| node_db_models
node_pipeline -->|"rebuilds index"| node_bm25
node_pipeline -->|"persists documents and vectors"| node_postgres
node_retriever -->|"searches lexical index"| node_bm25
node_retriever -->|"embeds query"| node_embedder
node_retriever -->|"runs ANN search"| node_vector_search
node_vector_search -->|"searches vectors"| node_postgres
node_retriever -->|"fetches ranked chunks"| node_db_models
node_generator -->|"generates grounded answer"| node_ollama
node_db_session -->|"opens database sessions"| node_postgres
node_fastapi -->|"provides startup session"| node_db_session

click node_console "https://github.com/breaseabrol/rag-system/blob/main/frontend/src/App.tsx"
click node_api_client "https://github.com/breaseabrol/rag-system/blob/main/frontend/src/api/client.ts"
click node_fastapi "https://github.com/breaseabrol/rag-system/blob/main/backend/app/main.py"
click node_query_route "https://github.com/breaseabrol/rag-system/blob/main/backend/app/api/routes_query.py"
click node_ingest_route "https://github.com/breaseabrol/rag-system/blob/main/backend/app/api/routes_ingest.py"
click node_schemas "https://github.com/breaseabrol/rag-system/blob/main/backend/app/schemas/model.py"
click node_loader "https://github.com/breaseabrol/rag-system/blob/main/backend/app/ingestion/loader.py"
click node_pipeline "https://github.com/breaseabrol/rag-system/blob/main/backend/app/ingestion/pipeline.py"
click node_chunker "https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/chunking.py"
click node_embedder "https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/embeddings.py"
click node_retriever "https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/retrieval.py"
click node_bm25 "https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/lexical_index.py"
click node_vector_search "https://github.com/breaseabrol/rag-system/blob/main/backend/app/db/vector_store.py"
click node_generator "https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/generation.py"
click node_db_session "https://github.com/breaseabrol/rag-system/blob/main/backend/app/db/session.py"
click node_db_models "https://github.com/breaseabrol/rag-system/blob/main/backend/app/db/models.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_console,node_api_client,node_user toneBlue
class node_fastapi,node_query_route,node_ingest_route,node_schemas,node_db_session,node_postgres toneAmber
class node_loader,node_pipeline,node_chunker,node_embedder,node_db_models toneMint
class node_retriever,node_bm25,node_vector_search,node_generator toneRose
class node_ollama,node_source_site toneIndigo
```

## Components

### Query interface

- [Query console](https://github.com/breaseabrol/rag-system/blob/main/frontend/src/App.tsx): `frontend/src/App.tsx`
- [Query client](https://github.com/breaseabrol/rag-system/blob/main/frontend/src/api/client.ts): `frontend/src/api/client.ts`

### Backend API

- [FastAPI app](https://github.com/breaseabrol/rag-system/blob/main/backend/app/main.py): `backend/app/main.py`
- [Query endpoint](https://github.com/breaseabrol/rag-system/blob/main/backend/app/api/routes_query.py): `backend/app/api/routes_query.py`
- [Ingest endpoint](https://github.com/breaseabrol/rag-system/blob/main/backend/app/api/routes_ingest.py): `backend/app/api/routes_ingest.py`
- [API schemas](https://github.com/breaseabrol/rag-system/blob/main/backend/app/schemas/model.py): `backend/app/schemas/model.py`
- [DB sessions](https://github.com/breaseabrol/rag-system/blob/main/backend/app/db/session.py): `backend/app/db/session.py`

### Ingestion

- [URL loader](https://github.com/breaseabrol/rag-system/blob/main/backend/app/ingestion/loader.py): `backend/app/ingestion/loader.py`
- [Ingest pipeline](https://github.com/breaseabrol/rag-system/blob/main/backend/app/ingestion/pipeline.py): `backend/app/ingestion/pipeline.py`
- [Structure-aware chunker](https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/chunking.py): `backend/app/core/chunking.py`
- [Local embeddings](https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/embeddings.py): `backend/app/core/embeddings.py`
- [Document and chunk records](https://github.com/breaseabrol/rag-system/blob/main/backend/app/db/models.py): `backend/app/db/models.py`

### Retrieval and generation

- [Hybrid retrieval](https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/retrieval.py): `backend/app/core/retrieval.py`
- [BM25 index](https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/lexical_index.py): `backend/app/core/lexical_index.py`
- [Vector search](https://github.com/breaseabrol/rag-system/blob/main/backend/app/db/vector_store.py): `backend/app/db/vector_store.py`
- [Answer generation](https://github.com/breaseabrol/rag-system/blob/main/backend/app/core/generation.py): `backend/app/core/generation.py`

### Other components

- **User**
- **PostgreSQL / pgvector**
- **Ollama**
- **Source URLs**

## Connections

- User → Query console: submits query (evidence: `frontend/src/App.tsx`)
- Query console → Query client: requests answer (evidence: `frontend/src/App.tsx`)
- Query client → FastAPI app: POST /query (evidence: `README.md`)
- FastAPI app → Query endpoint: routes query (evidence: `backend/app/main.py`)
- Query endpoint → Hybrid retrieval: retrieves chunks (evidence: `backend/app/api/routes_query.py`)
- Query endpoint → Answer generation: generates answer (evidence: `backend/app/api/routes_query.py`)
- Query endpoint → API schemas: uses response models (evidence: `backend/app/api/routes_query.py`)
- Query console → API schemas: renders answer and sources (evidence: `README.md`)
- User → FastAPI app: POST /ingest (evidence: `README.md`)
- FastAPI app → Ingest endpoint: routes ingest (evidence: `backend/app/main.py`)
- Ingest endpoint → Ingest pipeline: ingests URL (evidence: `backend/app/api/routes_ingest.py`)
- Ingest endpoint → API schemas: uses request models (evidence: `backend/app/api/routes_ingest.py`)
- Ingest pipeline → URL loader: loads document (evidence: `backend/app/ingestion/pipeline.py`)
- URL loader → Source URLs: fetches content (evidence: `README.md`)
- Ingest pipeline → Structure-aware chunker: chunks text (evidence: `backend/app/ingestion/pipeline.py`)
- Ingest pipeline → Local embeddings: embeds chunks (evidence: `backend/app/ingestion/pipeline.py`)
- Ingest pipeline → Document and chunk records: creates records (evidence: `backend/app/ingestion/pipeline.py`)
- Ingest pipeline → BM25 index: rebuilds index (evidence: `backend/app/ingestion/pipeline.py`)
- Ingest pipeline → PostgreSQL / pgvector: persists documents and vectors (evidence: `README.md`)
- Hybrid retrieval → BM25 index: searches lexical index (evidence: `backend/app/core/retrieval.py`)
- Hybrid retrieval → Local embeddings: embeds query (evidence: `backend/app/core/retrieval.py`)
- Hybrid retrieval → Vector search: runs ANN search (evidence: `backend/app/core/retrieval.py`)
- Vector search → PostgreSQL / pgvector: searches vectors (evidence: `README.md`)
- Hybrid retrieval → Document and chunk records: fetches ranked chunks (evidence: `backend/app/core/retrieval.py`)
- Answer generation → Ollama: generates grounded answer (evidence: `README.md`)
- DB sessions → PostgreSQL / pgvector: opens database sessions (evidence: `backend/app/db/session.py`)
- FastAPI app → DB sessions: provides startup session (evidence: `backend/app/main.py`)
