# khixar/enterprise-rag architecture

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

- Interactive diagram: https://gitdiagram.com/khixar/enterprise-rag
- Repository: https://github.com/khixar/enterprise-rag

## Overview

Enterprise RAG is a multi-tenant HR document copilot: users create tenants, upload documents, and query their tenant’s material for grounded answers with citations or an escalation when evidence is irrelevant. The query API invokes a LangGraph workflow that retrieves vector and BM25 candidates, fuses rankings, classifies relevance, then answers or escalates; answering reranks candidates and uses an LLM. Ingestion parses and chunks documents, embeds them, and stores tenant-scoped records. The README also documents Langfuse tracing. Endpoint details beyond the sampled query route are inferred from the README and tree; their internal wiring is shown only at the service boundary.

Main entry points: [`app/db/session.py`](https://github.com/khixar/enterprise-rag/blob/main/app/db/session.py) (PostgreSQL + pgvector), [`app/agent/nodes.py`](https://github.com/khixar/enterprise-rag/blob/main/app/agent/nodes.py) (Retrieve node), [`app/agent/graph.py`](https://github.com/khixar/enterprise-rag/blob/main/app/agent/graph.py) (Agent graph), [`app/main.py`](https://github.com/khixar/enterprise-rag/blob/main/app/main.py) (FastAPI app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["API and tenancy"]
  node_app["FastAPI app<br/>[main.py]"]
  node_tenant_api["Tenant endpoints<br/>[tenants.py]"]
  node_tenant_service["Tenant service<br/>[tenant_service.py]"]
  node_query_api["Query endpoint<br/>[query.py]"]
end

subgraph group_ingestion["Document ingestion"]
  node_document_api["Document endpoints<br/>[documents.py]"]
  node_document_service["Ingestion service"]
  node_parsing["Parse and chunk<br/>[parsing.py]"]
end

subgraph group_query["Query agent"]
  node_agent_graph["Agent graph<br/>[graph.py]"]
  node_retrieve["Retrieve node<br/>[nodes.py]"]
  node_classify["Classify node<br/>[nodes.py]"]
  node_answer["Answer node<br/>[nodes.py]"]
  node_escalate["Escalate node<br/>[nodes.py]"]
end

subgraph group_data["Search and storage"]
  node_embedding["Embedding service"]
  node_bm25["BM25 search<br/>[bm25_service.py]"]
  node_fusion["Rank fusion<br/>[rrf.py]"]
  node_reranker["Reranker service"]
  node_database[("PostgreSQL + pgvector<br/>[session.py]")]
  node_documents["Document records<br/>[document.py]"]
  node_chunks["Chunk records<br/>[chunk.py]"]
  node_tenants["Tenant records<br/>[tenant.py]"]
end

subgraph group_integrations["External integrations"]
  node_openai["OpenAI"]
  node_cohere["Cohere"]
  node_langfuse["Langfuse"]
end

node_user(("Copilot user"))

node_user -->|"sends requests"| node_app
node_app -->|"routes tenant calls"| node_tenant_api
node_app -->|"routes uploads"| node_document_api
node_app -->|"routes questions"| node_query_api
node_tenant_api -->|"manages tenants"| node_tenant_service
node_tenant_service -->|"reads and writes"| node_database
node_document_api -->|"ingests files"| node_document_service
node_document_service -->|"extracts and chunks"| node_parsing
node_document_service -->|"embeds chunks"| node_embedding
node_document_service -->|"persists records"| node_database
node_database -->|"stores"| node_documents
node_database -->|"stores"| node_chunks
node_database -->|"stores"| node_tenants
node_query_api -->|"invokes graph"| node_agent_graph
node_agent_graph -->|"dispatches retrieval"| node_retrieve
node_retrieve -->|"embeds question"| node_embedding
node_retrieve -->|"requests keyword search"| node_bm25
node_retrieve -->|"searches vectors"| node_database
node_retrieve -->|"fuses rankings"| node_fusion
node_bm25 -->|"searches tenant chunks"| node_database
node_agent_graph -->|"dispatches classification"| node_classify
node_classify -->|"classifies relevance"| node_openai
node_agent_graph -->|"dispatches answer"| node_answer
node_agent_graph -->|"dispatches fallback"| node_escalate
node_answer -->|"reranks candidates"| node_reranker
node_answer -->|"generates grounded answer"| node_openai
node_embedding -->|"requests embeddings"| node_openai
node_reranker -->|"reranks text"| node_cohere
node_query_api -.->|"traces query"| node_langfuse
node_retrieve -.->|"records retrieval"| node_langfuse
node_classify -.->|"records routing"| node_langfuse
node_answer -.->|"records answer"| node_langfuse

click node_app "https://github.com/khixar/enterprise-rag/blob/main/app/main.py"
click node_tenant_api "https://github.com/khixar/enterprise-rag/blob/main/app/api/v1/endpoints/tenants.py"
click node_tenant_service "https://github.com/khixar/enterprise-rag/blob/main/app/services/tenant_service.py"
click node_document_api "https://github.com/khixar/enterprise-rag/blob/main/app/api/v1/endpoints/documents.py"
click node_document_service "https://github.com/khixar/enterprise-rag/blob/main/app/services/document_service.py"
click node_parsing "https://github.com/khixar/enterprise-rag/blob/main/app/services/parsing.py"
click node_query_api "https://github.com/khixar/enterprise-rag/blob/main/app/api/v1/endpoints/query.py"
click node_agent_graph "https://github.com/khixar/enterprise-rag/blob/main/app/agent/graph.py"
click node_retrieve "https://github.com/khixar/enterprise-rag/blob/main/app/agent/nodes.py"
click node_classify "https://github.com/khixar/enterprise-rag/blob/main/app/agent/nodes.py"
click node_answer "https://github.com/khixar/enterprise-rag/blob/main/app/agent/nodes.py"
click node_escalate "https://github.com/khixar/enterprise-rag/blob/main/app/agent/nodes.py"
click node_embedding "https://github.com/khixar/enterprise-rag/blob/main/app/services/embedding_service.py"
click node_bm25 "https://github.com/khixar/enterprise-rag/blob/main/app/services/bm25_service.py"
click node_fusion "https://github.com/khixar/enterprise-rag/blob/main/app/services/rrf.py"
click node_reranker "https://github.com/khixar/enterprise-rag/blob/main/app/services/reranker_service.py"
click node_database "https://github.com/khixar/enterprise-rag/blob/main/app/db/session.py"
click node_documents "https://github.com/khixar/enterprise-rag/blob/main/app/models/document.py"
click node_chunks "https://github.com/khixar/enterprise-rag/blob/main/app/models/chunk.py"
click node_tenants "https://github.com/khixar/enterprise-rag/blob/main/app/models/tenant.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_app,node_tenant_api,node_tenant_service,node_query_api,node_user toneBlue
class node_document_api,node_document_service,node_parsing toneAmber
class node_agent_graph,node_retrieve,node_classify,node_answer,node_escalate toneMint
class node_embedding,node_bm25,node_fusion,node_reranker,node_database,node_documents,node_chunks,node_tenants toneRose
class node_openai,node_cohere,node_langfuse toneIndigo
```

## Components

### API and tenancy

- [FastAPI app](https://github.com/khixar/enterprise-rag/blob/main/app/main.py): `app/main.py`
- [Tenant endpoints](https://github.com/khixar/enterprise-rag/blob/main/app/api/v1/endpoints/tenants.py): `app/api/v1/endpoints/tenants.py`
- [Tenant service](https://github.com/khixar/enterprise-rag/blob/main/app/services/tenant_service.py): `app/services/tenant_service.py`
- [Query endpoint](https://github.com/khixar/enterprise-rag/blob/main/app/api/v1/endpoints/query.py): `app/api/v1/endpoints/query.py`

### Document ingestion

- [Document endpoints](https://github.com/khixar/enterprise-rag/blob/main/app/api/v1/endpoints/documents.py): `app/api/v1/endpoints/documents.py`
- [Ingestion service](https://github.com/khixar/enterprise-rag/blob/main/app/services/document_service.py): `app/services/document_service.py`
- [Parse and chunk](https://github.com/khixar/enterprise-rag/blob/main/app/services/parsing.py): `app/services/parsing.py`

### Query agent

- [Agent graph](https://github.com/khixar/enterprise-rag/blob/main/app/agent/graph.py): `app/agent/graph.py`
- [Retrieve node](https://github.com/khixar/enterprise-rag/blob/main/app/agent/nodes.py): `app/agent/nodes.py`
- [Classify node](https://github.com/khixar/enterprise-rag/blob/main/app/agent/nodes.py): `app/agent/nodes.py`
- [Answer node](https://github.com/khixar/enterprise-rag/blob/main/app/agent/nodes.py): `app/agent/nodes.py`
- [Escalate node](https://github.com/khixar/enterprise-rag/blob/main/app/agent/nodes.py): `app/agent/nodes.py`

### Search and storage

- [Embedding service](https://github.com/khixar/enterprise-rag/blob/main/app/services/embedding_service.py): `app/services/embedding_service.py`
- [BM25 search](https://github.com/khixar/enterprise-rag/blob/main/app/services/bm25_service.py): `app/services/bm25_service.py`
- [Rank fusion](https://github.com/khixar/enterprise-rag/blob/main/app/services/rrf.py): `app/services/rrf.py`
- [Reranker service](https://github.com/khixar/enterprise-rag/blob/main/app/services/reranker_service.py): `app/services/reranker_service.py`
- [PostgreSQL + pgvector](https://github.com/khixar/enterprise-rag/blob/main/app/db/session.py): `app/db/session.py`
- [Document records](https://github.com/khixar/enterprise-rag/blob/main/app/models/document.py): `app/models/document.py`
- [Chunk records](https://github.com/khixar/enterprise-rag/blob/main/app/models/chunk.py): `app/models/chunk.py`
- [Tenant records](https://github.com/khixar/enterprise-rag/blob/main/app/models/tenant.py): `app/models/tenant.py`

### External integrations

- **OpenAI**
- **Cohere**
- **Langfuse**

### Other components

- **Copilot user**

## Connections

- Copilot user → FastAPI app: sends requests
- FastAPI app → Tenant endpoints: routes tenant calls
- FastAPI app → Document endpoints: routes uploads
- FastAPI app → Query endpoint: routes questions
- Tenant endpoints → Tenant service: manages tenants
- Tenant service → PostgreSQL + pgvector: reads and writes
- Document endpoints → Ingestion service: ingests files
- Ingestion service → Parse and chunk: extracts and chunks
- Ingestion service → Embedding service: embeds chunks
- Ingestion service → PostgreSQL + pgvector: persists records
- PostgreSQL + pgvector → Document records: stores
- PostgreSQL + pgvector → Chunk records: stores
- PostgreSQL + pgvector → Tenant records: stores
- Query endpoint → Agent graph: invokes graph
- Agent graph → Retrieve node: dispatches retrieval
- Retrieve node → Embedding service: embeds question
- Retrieve node → BM25 search: requests keyword search
- Retrieve node → PostgreSQL + pgvector: searches vectors
- Retrieve node → Rank fusion: fuses rankings
- BM25 search → PostgreSQL + pgvector: searches tenant chunks
- Agent graph → Classify node: dispatches classification
- Classify node → OpenAI: classifies relevance
- Agent graph → Answer node: dispatches answer
- Agent graph → Escalate node: dispatches fallback
- Answer node → Reranker service: reranks candidates
- Answer node → OpenAI: generates grounded answer
- Embedding service → OpenAI: requests embeddings
- Reranker service → Cohere: reranks text
- Query endpoint → Langfuse: traces query
- Retrieve node → Langfuse: records retrieval
- Classify node → Langfuse: records routing
- Answer node → Langfuse: records answer
