# aravind00006/hybrid-rag architecture

> Architecture diagram of the GitHub repository aravind00006/hybrid-rag, 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/aravind00006/hybrid-rag
- Repository: https://github.com/aravind00006/hybrid-rag

## Overview

HYBRID-RAG answers plain-English questions over SEC 10-K PDFs with retrieved context and page citations. The workflow loads and cleans PDF text, chunks it, indexes chunks for keyword and semantic search, fuses results, then generates a grounded answer. Users can replace the active PDF through either the Streamlit interface or the API. The README also documents RAGAS quality scoring as a separate capability. Edges reflect documented wiring; hybrid internals and evaluation are described in the README, while their implementation details were not sampled.

Main entry points: [`api/routes.py`](https://github.com/aravind00006/hybrid-rag/blob/main/api/routes.py) (HTTP routes), [`app.py`](https://github.com/aravind00006/hybrid-rag/blob/main/app.py) (Streamlit UI), [`api/main.py`](https://github.com/aravind00006/hybrid-rag/blob/main/api/main.py) (FastAPI startup), [`ingestion/embedder.py`](https://github.com/aravind00006/hybrid-rag/blob/main/ingestion/embedder.py) (Embed and store)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interfaces["User interfaces"]
  node_streamlit["Streamlit UI<br/>[app.py]"]
  node_api_app["FastAPI startup<br/>[main.py]"]
  node_api_routes["HTTP routes<br/>[routes.py]"]
  node_contracts["API contracts<br/>[schemas.py]"]
end

subgraph group_ingestion["Document ingestion"]
  node_pdf_loader["PDF loader<br/>[loader.py]"]
  node_chunker["Chunk and filter<br/>[chunker.py]"]
  node_embedder["Embed and store<br/>[embedder.py]"]
end

subgraph group_retrieval["Hybrid retrieval"]
  node_vector_store[("Chroma vector store")]
  node_bm25["BM25 search<br/>[bm25_retriever.py]"]
  node_semantic["Semantic search"]
  node_hybrid["RRF fusion<br/>[hybrid.py]"]
end

subgraph group_generation["Grounded generation"]
  node_prompts["Grounding prompts<br/>[prompts.py]"]
  node_generator["Answer generation<br/>[generator.py]"]
end

subgraph group_evaluation["Quality evaluation"]
  node_ragas["RAGAS scoring<br/>[ragas_eval.py]"]
end

node_user(("Questioner"))
node_api_client(("API client"))
node_openai["OpenAI services"]
node_default_pdf["Default 10-K PDF<br/>[aapl-10k-2024.pdf]"]
node_eval_samples["Eval samples"]

node_user -->|"asks via"| node_streamlit
node_streamlit -->|"loads PDF"| node_pdf_loader
node_streamlit -->|"chunks pages"| node_chunker
node_streamlit -->|"indexes uploads"| node_embedder
node_streamlit -->|"builds index"| node_bm25
node_streamlit -->|"runs query"| node_hybrid
node_streamlit -->|"generates answer"| node_generator
node_api_client -->|"sends requests"| node_api_routes
node_api_routes -->|"validates payloads"| node_contracts
node_api_app -->|"loads default"| node_pdf_loader
node_api_app -->|"chunks pages"| node_chunker
node_api_app -->|"builds or loads"| node_embedder
node_api_app -->|"builds index"| node_bm25
node_default_pdf -->|"reads"| node_pdf_loader
node_api_routes -->|"loads upload"| node_pdf_loader
node_api_routes -->|"chunks upload"| node_chunker
node_api_routes -->|"indexes upload"| node_embedder
node_api_routes -->|"rebuilds index"| node_bm25
node_embedder -->|"requests embeddings"| node_openai
node_embedder -->|"writes vectors"| node_vector_store
node_api_app -->|"loads persisted index"| node_vector_store
node_semantic -->|"searches vectors"| node_vector_store
node_hybrid -->|"requests rankings"| node_bm25
node_hybrid -->|"requests rankings"| node_semantic
node_api_routes -->|"runs query"| node_hybrid
node_api_routes -->|"generates answer"| node_generator
node_generator -->|"builds context prompt"| node_prompts
node_generator -->|"requests completion"| node_openai
node_eval_samples -->|"provides samples"| node_ragas
node_ragas -->|"uses judge models"| node_openai

click node_default_pdf "https://github.com/aravind00006/hybrid-rag/blob/main/data/raw/aapl-10k-2024.pdf"
click node_streamlit "https://github.com/aravind00006/hybrid-rag/blob/main/app.py"
click node_api_app "https://github.com/aravind00006/hybrid-rag/blob/main/api/main.py"
click node_api_routes "https://github.com/aravind00006/hybrid-rag/blob/main/api/routes.py"
click node_contracts "https://github.com/aravind00006/hybrid-rag/blob/main/api/schemas.py"
click node_pdf_loader "https://github.com/aravind00006/hybrid-rag/blob/main/ingestion/loader.py"
click node_chunker "https://github.com/aravind00006/hybrid-rag/blob/main/ingestion/chunker.py"
click node_embedder "https://github.com/aravind00006/hybrid-rag/blob/main/ingestion/embedder.py"
click node_bm25 "https://github.com/aravind00006/hybrid-rag/blob/main/retrieval/bm25_retriever.py"
click node_semantic "https://github.com/aravind00006/hybrid-rag/blob/main/retrieval/semantic_retriever.py"
click node_hybrid "https://github.com/aravind00006/hybrid-rag/blob/main/retrieval/hybrid.py"
click node_prompts "https://github.com/aravind00006/hybrid-rag/blob/main/generation/prompts.py"
click node_generator "https://github.com/aravind00006/hybrid-rag/blob/main/generation/generator.py"
click node_ragas "https://github.com/aravind00006/hybrid-rag/blob/main/evaluation/ragas_eval.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_streamlit,node_api_app,node_api_routes,node_contracts,node_api_client toneBlue
class node_pdf_loader,node_chunker,node_embedder toneAmber
class node_vector_store,node_bm25,node_semantic,node_hybrid toneMint
class node_prompts,node_generator toneRose
class node_ragas,node_user,node_openai,node_eval_samples toneIndigo
class node_default_pdf toneTeal
```

## Components

### User interfaces

- [Streamlit UI](https://github.com/aravind00006/hybrid-rag/blob/main/app.py): `app.py`
- [FastAPI startup](https://github.com/aravind00006/hybrid-rag/blob/main/api/main.py): `api/main.py`
- [HTTP routes](https://github.com/aravind00006/hybrid-rag/blob/main/api/routes.py): `api/routes.py`
- [API contracts](https://github.com/aravind00006/hybrid-rag/blob/main/api/schemas.py): `api/schemas.py`

### Document ingestion

- [PDF loader](https://github.com/aravind00006/hybrid-rag/blob/main/ingestion/loader.py): `ingestion/loader.py`
- [Chunk and filter](https://github.com/aravind00006/hybrid-rag/blob/main/ingestion/chunker.py): `ingestion/chunker.py`
- [Embed and store](https://github.com/aravind00006/hybrid-rag/blob/main/ingestion/embedder.py): `ingestion/embedder.py`

### Hybrid retrieval

- **Chroma vector store**
- [BM25 search](https://github.com/aravind00006/hybrid-rag/blob/main/retrieval/bm25_retriever.py): `retrieval/bm25_retriever.py`
- [Semantic search](https://github.com/aravind00006/hybrid-rag/blob/main/retrieval/semantic_retriever.py): `retrieval/semantic_retriever.py`
- [RRF fusion](https://github.com/aravind00006/hybrid-rag/blob/main/retrieval/hybrid.py): `retrieval/hybrid.py`

### Grounded generation

- [Grounding prompts](https://github.com/aravind00006/hybrid-rag/blob/main/generation/prompts.py): `generation/prompts.py`
- [Answer generation](https://github.com/aravind00006/hybrid-rag/blob/main/generation/generator.py): `generation/generator.py`

### Quality evaluation

- [RAGAS scoring](https://github.com/aravind00006/hybrid-rag/blob/main/evaluation/ragas_eval.py): `evaluation/ragas_eval.py`

### Other components

- **Questioner**
- **API client**
- **OpenAI services**
- [Default 10-K PDF](https://github.com/aravind00006/hybrid-rag/blob/main/data/raw/aapl-10k-2024.pdf): `data/raw/aapl-10k-2024.pdf`
- **Eval samples**

## Connections

- Questioner → Streamlit UI: asks via
- Streamlit UI → PDF loader: loads PDF
- Streamlit UI → Chunk and filter: chunks pages
- Streamlit UI → Embed and store: indexes uploads
- Streamlit UI → BM25 search: builds index
- Streamlit UI → RRF fusion: runs query
- Streamlit UI → Answer generation: generates answer
- API client → HTTP routes: sends requests
- HTTP routes → API contracts: validates payloads
- FastAPI startup → PDF loader: loads default
- FastAPI startup → Chunk and filter: chunks pages
- FastAPI startup → Embed and store: builds or loads
- FastAPI startup → BM25 search: builds index
- Default 10-K PDF → PDF loader: reads
- HTTP routes → PDF loader: loads upload
- HTTP routes → Chunk and filter: chunks upload
- HTTP routes → Embed and store: indexes upload
- HTTP routes → BM25 search: rebuilds index
- Embed and store → OpenAI services: requests embeddings
- Embed and store → Chroma vector store: writes vectors
- FastAPI startup → Chroma vector store: loads persisted index
- Semantic search → Chroma vector store: searches vectors
- RRF fusion → BM25 search: requests rankings
- RRF fusion → Semantic search: requests rankings
- HTTP routes → RRF fusion: runs query
- HTTP routes → Answer generation: generates answer
- Answer generation → Grounding prompts: builds context prompt
- Answer generation → OpenAI services: requests completion
- Eval samples → RAGAS scoring: provides samples
- RAGAS scoring → OpenAI services: uses judge models
