# sahilnegi4444/ai-analyst-agent architecture

> Architecture diagram of the GitHub repository sahilnegi4444/ai-analyst-agent, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-18). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/sahilnegi4444/ai-analyst-agent
- Repository: https://github.com/sahilnegi4444/ai-analyst-agent

## Overview

1. **High-level shape**
   - This repo is a two-part system: a **FastAPI backend** that serves an AI analyst API, and a **React/Vite frontend** that renders a conversational dashboard with charts.
   - The backend is the real architecture center: it routes each user question through a **LangGraph workflow** that decides whether to use SQL, document retrieval, analytics calculations, or a hybrid path.

2. **Primary request flow**
   - A user query enters through `app/api/endpoints.py`, which calls the backend workflow.
   - Before invoking the agent, `app/services/cache_service.py` checks Redis using a normalized query key.
   - On a cache miss, the request goes into `app/agents/workflow.py`, then to `app/agents/router.py` for intent classification, and finally to one or more tool nodes.
   - The final response is returned to the API, cached, and sent back to the frontend.

3. **Agent orchestration boundary**
   - `app/agents/router.py` is the intent classifier, powered by Groq LLMs in JSON mode.
   - `app/agents/workflow.py` is the orchestration layer that chooses between `SQL_QUERY`, `RAG_QUERY`, `HYBRID_QUERY`, `ANALYTICS_QUERY`, or `UNSUPPORTED_QUERY`.
   - This is the main control boundary of the backend: it separates natural-language understanding from actual data access and calculation.

4. **Tool layer and execution safety**
   - The backend does not let the LLM directly touch storage; it must go through tools in `app/tools/`.
   - `sql_tool.py` enforces read-only SQL and validates generated queries with a dry-run `EXPLAIN`, rolling back on failure.
   - `rag_tool.py` performs semantic document retrieval over PostgreSQL `pgvector`.
   - `analytics_tool.py` delegates numeric business calculations to the analytics service instead of letting the model do math.

5. **Data sources and storage**
   - The system uses **PostgreSQL** as the main persistent store for structured data and vector search.
   - SQLAlchemy models are defined in `app/models/__init__.py`, with session/engine wiring in `app/database/__init__.py`.
   - Alembic is included for schema migration management.
   - The repository also implies a document corpus under `data/documents/`, which is ingested into vectorized chunks for RAG.

6. **Retrieval-augmented generation path**
   - Document search is backed by `pgvector` in PostgreSQL rather than a separate vector database.
   - Embeddings are generated locally using Sentence Transformers via `app/services/embedding.py`, specifically the offline `all-MiniLM-L6-v2` model.
   - Retrieved passages are surfaced with source attribution and similarity confidence, which matters for how the frontend presents evidence.

7. **Analytics path**
   - `app/services/analytics_service.py` handles deterministic business calculations such as growth rates, ratios, and distribution comparisons.
   - This path is intentionally non-generative: the LLM may classify the request, but the actual math is done in Python/Pandas.
   - That creates a separate execution boundary for precise analytical answers versus SQL results or document-grounded answers.

8. **Caching and resilience**
   - `app/services/cache_service.py` provides Redis-backed query caching keyed by the normalized text of the question.
   - The cache layer is fault-tolerant: if Redis is unavailable, it falls back to an in-memory thread-safe cache.
   - Architecturally, this sits in front of the workflow so repeated queries can bypass both routing and generation.

9. **Observability and traceability**
   - `app/utils/logger.py` writes execution traces to `data/observability_runs.jsonl`.
   - Logged data includes the original query, intent classification, selected tools, generated SQL, status, and latency breakdown.
   - This makes the system auditable and supports post-run analysis of agent behavior.

10. **Frontend responsibilities**
   - The frontend in `frontend/` is a Vite/React/TypeScript dashboard.
   - `App.tsx` is the main UI entry point and likely handles query submission, response rendering, and chart selection.
   - Based on the README, it also visualizes structured results using charting logic and exposes SQL/doc evidence in the UI.

11. **Backend service composition**
   - `app/schemas/` defines the request/response contracts used between API, workflow, and tools.
   - `app/repositories/` provides a repository abstraction over persistence, keeping database access separate from orchestration logic.
   - `app/config.py` centralizes environment-driven configuration such as database, Redis, and Groq settings.

12. **Offline and deployment concerns**
   - The repo is designed to run with containerization: `Dockerfile` and `docker-compose.yml` support multi-service deployment.
   - The environment also assumes offline-friendly embedding behavior via `HF_HUB_OFFLINE` and `TRANSFORMERS_OFFLINE`.
   - In practice, the external dependencies that materially shape the architecture are PostgreSQL, Redis, and Groq LLM endpoints.

13. **Ingestion, validation, and lifecycle scripts**
   - `scripts/ingest_all.py` appears to populate tables and vector embeddings, making it the main data bootstrap path.
   - `scripts/verify_db.py`, `generate_documents.py`, `generate_dataset.py`, and `validate_dataset.py` support data preparation and consistency checks.
   - `alembic/versions/` contains the initial schema migration, which indicates the database lifecycle is managed separately from runtime code.

14. **Quality assurance and evaluation**
   - `tests/test_agent.py` covers routing, SQL safety, caching, and RAG behavior.
   - `app/evaluation/` contains a benchmark dataset and evaluator that produces `data/evaluation_report.json`.
   - This suggests the repo treats agent quality as a first-class subsystem, not just application logic.

15. **How to draw the architecture**
   - The most important boundaries to show are: **frontend → API → cache → LangGraph workflow → tools → storage/services**.
   - Split the backend into three zones: **orchestration** (`agents`), **execution** (`tools` and `services`), and **persistence** (`database`, PostgreSQL, Redis, traces).
   - Show the LLM as a control component for routing and generation, but keep actual SQL access, retrieval, and analytics in deterministic tool/service layers.

Main entry points: [`app/api/endpoints.py`](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/api/endpoints.py) (API Routes), [`app/agents/workflow.py`](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/agents/workflow.py) (Workflow), [`app/config.py`](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/config.py) (Config), [`app/services/cache_service.py`](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/services/cache_service.py) (Cache)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Frontend"]
  node_frontend_shell["UI Shell<br/>react-ui<br/>[App.tsx]"]
  node_frontend_boot["Boot<br/>react-entry<br/>[main.tsx]"]
end

subgraph group_backend["Backend"]
  node_api_routes["API Routes<br/>fastapi<br/>[endpoints.py]"]
  node_app_entry["App Entry<br/>fastapi-app<br/>[main.py]"]
  node_query_cache[("Cache<br/>[cache_service.py]")]
  node_workflow{{"Workflow<br/>langgraph<br/>[workflow.py]"}}
  node_router{{"Router<br/>llm-classifier<br/>[router.py]"}}
  node_sql_tool["SQL Tool<br/>read-only-sql<br/>[sql_tool.py]"]
  node_rag_tool["RAG Tool<br/>retrieval<br/>[rag_tool.py]"]
  node_analytics_tool["Analytics Tool<br/>calc-tool<br/>[analytics_tool.py]"]
  node_embedding_service["Embeddings<br/>embedding-model<br/>[embedding.py]"]
  node_analytics_service["Analytics Core<br/>pandas-service"]
  node_config["Config<br/>settings<br/>[config.py]"]
  node_schemas["Contracts<br/>schemas<br/>[chat.py]"]
end

subgraph group_data["Data Layer"]
  node_db_core[("Database<br/>sqlalchemy-db<br/>[__init__.py]")]
  node_models["Models<br/>[__init__.py]"]
  node_repo_base["Repos<br/>[base.py]"]
  node_ingestion["Ingestion<br/>bootstrap-pipeline<br/>[ingestion.py]"]
end

subgraph group_ops["Ops"]
  node_logger["Tracing<br/>jsonl-logger<br/>[logger.py]"]
  node_evaluation["Evaluation<br/>benchmark<br/>[evaluator.py]"]
  node_agent_tests["Agent Tests<br/>test-harness<br/>[test_agent.py]"]
end

node_postgres[("PostgreSQL<br/>external-db")]
node_redis[("Redis<br/>external-cache")]
node_groq(("Groq LLM<br/>external-llm"))

node_frontend_boot -->|"mounts"| node_frontend_shell
node_frontend_shell -->|"queries"| node_api_routes
node_app_entry -->|"serves"| node_api_routes
node_api_routes -->|"check cache"| node_query_cache
node_query_cache -.->|"cache hit"| node_api_routes
node_api_routes -->|"invoke"| node_workflow
node_workflow -->|"classify"| node_router
node_router -->|"uses"| node_groq
node_workflow -->|"route"| node_sql_tool
node_workflow -->|"route"| node_rag_tool
node_workflow -->|"route"| node_analytics_tool
node_sql_tool -->|"queries"| node_db_core
node_sql_tool -.->|"abstracts"| node_repo_base
node_rag_tool -->|"embed"| node_embedding_service
node_rag_tool -->|"vector search"| node_postgres
node_analytics_tool -->|"delegate"| node_analytics_service
node_analytics_service -->|"reads data"| node_postgres
node_ingestion -->|"build vectors"| node_embedding_service
node_ingestion -->|"load data"| node_db_core
node_db_core -->|"maps"| node_models
node_api_routes -.->|"contracts"| node_schemas
node_workflow -->|"trace"| node_logger
node_api_routes -->|"trace"| node_logger
node_evaluation -->|"reports"| node_logger
node_agent_tests -.->|"verifies"| node_workflow
node_api_routes -->|"store answer"| node_query_cache
node_config -.->|"configures"| node_query_cache
node_config -.->|"configures"| node_db_core
node_config -.->|"configures"| node_workflow
node_config -.->|"auth"| node_groq

click node_frontend_shell "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/frontend/src/App.tsx"
click node_frontend_boot "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/frontend/src/main.tsx"
click node_api_routes "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/api/endpoints.py"
click node_app_entry "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/main.py"
click node_query_cache "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/services/cache_service.py"
click node_workflow "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/agents/workflow.py"
click node_router "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/agents/router.py"
click node_sql_tool "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/tools/sql_tool.py"
click node_rag_tool "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/tools/rag_tool.py"
click node_analytics_tool "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/tools/analytics_tool.py"
click node_embedding_service "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/services/embedding.py"
click node_analytics_service "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/services/analytics_service.py"
click node_config "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/config.py"
click node_schemas "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/schemas/chat.py"
click node_db_core "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/database/__init__.py"
click node_models "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/models/__init__.py"
click node_repo_base "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/repositories/base.py"
click node_ingestion "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/services/ingestion.py"
click node_logger "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/utils/logger.py"
click node_evaluation "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/evaluation/evaluator.py"
click node_agent_tests "https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/tests/test_agent.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_frontend_shell,node_frontend_boot toneBlue
class node_api_routes,node_app_entry,node_query_cache,node_workflow,node_router,node_sql_tool,node_rag_tool,node_analytics_tool,node_embedding_service,node_analytics_service,node_config,node_schemas toneAmber
class node_db_core,node_models,node_repo_base,node_ingestion toneMint
class node_logger,node_evaluation,node_agent_tests toneRose
class node_postgres,node_redis,node_groq toneNeutral
```

## Components

### Frontend

React/Vite conversational dashboard

- [UI Shell](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/frontend/src/App.tsx): react-ui · Chat dashboard and chart rendering entrypoint · `frontend/src/App.tsx`
- [Boot](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/frontend/src/main.tsx): react-entry · Frontend application bootstrap · `frontend/src/main.tsx`

### Backend

FastAPI app with agent orchestration and tools

- [API Routes](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/api/endpoints.py): fastapi · Chat and analyst API endpoints · `app/api/endpoints.py`
- [App Entry](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/main.py): fastapi-app · Backend application startup and wiring · `app/main.py`
- [Cache](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/services/cache_service.py): redis-cache · Normalized query cache with fallback memory store · `app/services/cache_service.py`
- [Workflow](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/agents/workflow.py): langgraph · Agent orchestration and query path selection · `app/agents/workflow.py`
- [Router](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/agents/router.py): llm-classifier · Intent classification in JSON mode · `app/agents/router.py`
- [SQL Tool](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/tools/sql_tool.py): read-only-sql · Safe SQL execution with EXPLAIN validation · `app/tools/sql_tool.py`
- [RAG Tool](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/tools/rag_tool.py): retrieval · Document retrieval over pgvector · `app/tools/rag_tool.py`
- [Analytics Tool](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/tools/analytics_tool.py): calc-tool · Deterministic business calculations boundary · `app/tools/analytics_tool.py`
- [Embeddings](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/services/embedding.py): embedding-model · Offline sentence-transformer embeddings · `app/services/embedding.py`
- [Analytics Core](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/services/analytics_service.py): pandas-service · Numeric and distribution calculations · `app/services/analytics_service.py`
- [Config](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/config.py): settings · Environment-driven settings for services · `app/config.py`
- [Contracts](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/schemas/chat.py): schemas · Request and response schemas · `app/schemas/chat.py`

### Data Layer

Persistence, ingestion, embeddings, and storage

- [Database](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/database/__init__.py): sqlalchemy-db · Engine and session wiring · `app/database/__init__.py`
- [Models](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/models/__init__.py): orm-models · SQLAlchemy domain models · `app/models/__init__.py`
- [Repos](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/repositories/base.py): repository-layer · Persistence abstraction over storage · `app/repositories/base.py`
- [Ingestion](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/services/ingestion.py): bootstrap-pipeline · Loads documents, rows, and embeddings · `app/services/ingestion.py`

### Ops

Logging and evaluation

- [Tracing](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/utils/logger.py): jsonl-logger · Execution traces and run history · `app/utils/logger.py`
- [Evaluation](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/app/evaluation/evaluator.py): benchmark · Agent quality evaluation pipeline · `app/evaluation/evaluator.py`
- [Agent Tests](https://github.com/sahilnegi4444/ai-analyst-agent/blob/main/tests/test_agent.py): test-harness · Focused coverage for routing, safety, cache, and RAG · `tests/test_agent.py`

### Other components

- **PostgreSQL**: external-db · Structured storage and pgvector retrieval
- **Redis**: external-cache · Primary cache backend
- **Groq LLM**: external-llm · LLM provider for routing and generation

## Connections

- Boot → UI Shell: mounts · Bootstraps the UI shell
- UI Shell → API Routes: queries · Submits user questions to the backend API
- App Entry → API Routes: serves · FastAPI application exposes the endpoints
- API Routes → Cache: check cache · Looks up normalized questions before agent execution
- Cache → API Routes: cache hit · Returns stored answer when available
- API Routes → Workflow: invoke · Hands cache misses to the agent workflow
- Workflow → Router: classify · Determines SQL, RAG, hybrid, analytics, or unsupported path
- Router → Groq LLM: uses · LLM-backed intent classification
- Workflow → SQL Tool: route · Executes structured-data questions
- Workflow → RAG Tool: route · Executes document-grounded questions
- Workflow → Analytics Tool: route · Executes deterministic calculations
- SQL Tool → Database: queries · Runs validated SQL through the database layer
- SQL Tool → Repos: abstracts · Uses repository boundaries for persistence access
- RAG Tool → Embeddings: embed · Creates vector representations for retrieval
- RAG Tool → PostgreSQL: vector search · Retrieves passages from pgvector storage
- Analytics Tool → Analytics Core: delegate · Pushes numeric business logic into deterministic code
- Analytics Core → PostgreSQL: reads data · Consumes stored structured data when needed
- Ingestion → Embeddings: build vectors · Generates embeddings during corpus bootstrap
- Ingestion → Database: load data · Populates persistent tables and indexes
- Database → Models: maps · Session and engine wiring target ORM models
- API Routes → Contracts: contracts · Uses shared request and response shapes
- Workflow → Tracing: trace · Logs intent, tools, latency, and status
- API Routes → Tracing: trace · Records request and response lifecycle
- Evaluation → Tracing: reports · Produces evaluation artifacts from run traces
- Agent Tests → Workflow: verifies · Covers routing and tool safety behavior
- API Routes → Cache: store answer · Caches successful responses for repeat queries
- Config → Cache: configures · Provides Redis and cache settings
- Config → Database: configures · Provides database settings
- Config → Workflow: configures · Provides model and runtime settings
- Config → Groq LLM: auth · Supplies LLM connection settings
