Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ€– NL2SQL Agent

An AI-powered agentic system that converts plain English business questions into safe, optimized SQL queries β€” with a full Streamlit UI, FastAPI backend, and PostgreSQL demo database.

Python FastAPI Streamlit Groq PostgreSQL Docker License


✨ Features

  • 2-stage AI pipeline β€” intent extraction β†’ SQL generation with chain-of-thought reasoning
  • Self-correction loop β€” automatically retries up to 2 times if SQL fails to execute
  • Clarification agent β€” asks for clarification when the question is ambiguous
  • Security layer β€” SELECT-only enforcement, dangerous keyword blocklist, auto LIMIT injection
  • Live schema introspection β€” agent always reads the real DB schema at query time
  • Evaluation framework β€” tracks latency, token usage, self-corrections, and error rate per query
  • Human feedback β€” rate any query result via API or UI
  • Demo e-commerce DB β€” auto-seeded with 50 customers, 20 products, 200 orders

πŸ—οΈ Architecture

User Question
      β”‚
      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Stage 1: IntentExtraction       β”‚
β”‚                                     β”‚
β”‚  LLaMA 3.3 70B extracts:            β”‚
β”‚  β€’ intent_type (aggregation/join/…) β”‚
β”‚  β€’ entities  (tables/columns)       β”‚
β”‚  β€’ time_range                       β”‚
β”‚  β€’ ambiguity_flags                  β”‚
β”‚                                     β”‚
β”‚  ambiguity_flags non-empty?         β”‚
β”‚  β†’ return ClarificationRequest      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ QueryIntent
               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Stage 2: SQLGeneration          β”‚
β”‚                                     β”‚
β”‚  1. Fetch live DB schema            β”‚
β”‚  2. LLaMA reasons step-by-step:     β”‚
β”‚     Step 1 – identify tables        β”‚
β”‚     Step 2 – determine joins        β”‚
β”‚     Step 3 – write SQL              β”‚
β”‚     Step 4 – self-review            β”‚
β”‚  3. Security validation             β”‚
β”‚  4. Execute SQL                     β”‚
β”‚  5. Self-correction loop (≀ 2Γ—)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ GeneratedSQL + Results
               β–Ό
         QueryResponse
  sql Β· explanation Β· results
  latency Β· tokens Β· cost Β· corrections

πŸš€ Quick Start

Prerequisites

1. Clone & configure

git clone https://github.com/jenish0908/nl2sql.git
cd nl2sql
cp .env.example .env

Open .env and set your key:

GROQ_API_KEY=gsk_xxxxxxxxxxxxxxxxxxxx

2. Launch

docker-compose up --build

On first boot the app will:

  1. Create all database tables
  2. Seed the demo e-commerce dataset
  3. Start the FastAPI backend
  4. Start the Streamlit UI
Service URL
πŸ–₯️ Streamlit UI http://localhost:8501
⚑ FastAPI docs http://localhost:8001/docs
πŸ—„οΈ PostgreSQL localhost:5433

πŸ’¬ Example Questions

Which category had the highest revenue last month?
Show me the top 5 customers by total order value
Which products are running low on stock?
What is the average order value by city?
How many orders were placed last week by status?
Which supplier has the best-rated products?
Show total revenue per month for the last 3 months
What is the profit margin per product category?
Which customers placed more than 3 orders?
Show me cancelled orders from the last 30 days

πŸ“‘ API Reference

POST /query

{
  "question": "Which city had the highest order value last month?"
}

Response:

{
  "query_id": 1,
  "sql": "SELECT delivery_city, SUM(total_amount) AS total ...",
  "explanation": "This query groups orders by delivery city ...",
  "results": [{"delivery_city": "New York", "total": 14230.50}],
  "row_count": 5,
  "intent": {"intent_type": "aggregation", "time_range": "last month"},
  "latency_ms": 1240,
  "tokens_used": 980,
  "cost_usd": 0.0,
  "self_corrections": 0
}

POST /query/clarify

Re-run with extra context when the agent asks for clarification.

{
  "question": "Show me sales",
  "clarification": "I mean total revenue by product category for last month"
}

GET /schema

Returns the full live database schema (tables, columns, types, foreign keys).

GET /history

Returns the last 20 queries with SQL, results summary, and metrics.

GET /evaluations/summary

{
  "total_queries": 47,
  "avg_latency_ms": 1340,
  "avg_cost_usd": 0.0,
  "self_correction_rate": 0.04,
  "clarification_rate": 0.06,
  "error_rate": 0.02
}

POST /evaluations/{query_id}/feedback

{
  "sql_correct": true,
  "result_correct": true,
  "rating": 5,
  "comment": "perfect"
}

GET /health


πŸ”’ Security

Layer Detail
SELECT-only Non-SELECT statements are rejected immediately
Keyword blocklist DROP, DELETE, UPDATE, INSERT, ALTER, CREATE, EXEC, TRUNCATE, XP_, SP_
Comment stripping -- and /* */ comments removed before validation
Auto LIMIT LIMIT 100 appended if no LIMIT clause present
Parameterized execution All queries run through SQLAlchemy's safe layer

πŸ“Š Evaluation Metrics

Every query automatically records:

Metric Description
latency_ms Total wall-clock time from question to response
tokens_used Combined input + output tokens across both agent stages
cost_usd $0 on Groq free tier
self_corrections SQL retry count (0–2)
clarification_requested Whether the intent stage flagged ambiguity
execution_error Whether all retries were exhausted

πŸ—‚οΈ Project Structure

nl2sql-agent/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ main.py                   FastAPI app + lifespan
β”‚   β”œβ”€β”€ config.py                 Settings (pydantic-settings)
β”‚   β”œβ”€β”€ agents/
β”‚   β”‚   β”œβ”€β”€ intent_extraction.py  Stage 1 – Groq intent parsing
β”‚   β”‚   β”œβ”€β”€ sql_generation.py     Stage 2 – Groq SQL + self-correction
β”‚   β”‚   └── clarification.py      Clarification subagent
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”œβ”€β”€ query.py              POST /query, POST /query/clarify
β”‚   β”‚   β”œβ”€β”€ schema.py             GET /schema
β”‚   β”‚   └── evaluations.py        GET /history, /evaluations/summary, feedback
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ db.py                 Async SQLAlchemy engine + session
β”‚   β”‚   β”œβ”€β”€ schema_inspector.py   Live schema introspection
β”‚   β”‚   └── sql_executor.py       Safe SQL execution + security checks
β”‚   └── models/
β”‚       β”œβ”€β”€ database.py           SQLAlchemy ORM models
β”‚       └── schemas.py            Pydantic v2 request/response schemas
β”œβ”€β”€ streamlit_app.py              Streamlit demo UI
β”œβ”€β”€ scripts/
β”‚   └── seed_demo_data.py         Demo e-commerce data seeder
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ entrypoint.sh
β”œβ”€β”€ requirements.txt
└── .env.example

πŸ› οΈ Local Development (without Docker)

# Start only Postgres via Docker
docker run -d \
  -e POSTGRES_USER=nl2sql \
  -e POSTGRES_PASSWORD=nl2sql \
  -e POSTGRES_DB=nl2sql_db \
  -p 5432:5432 \
  postgres:15-alpine

# Install dependencies
pip install -r requirements.txt

# Configure env (use localhost URLs)
cp .env.example .env

# Create tables + seed data
python scripts/seed_demo_data.py

# Start API
uvicorn app.main:app --reload

# Start UI (separate terminal)
streamlit run streamlit_app.py

πŸ“¦ Tech Stack

Layer Technology
LLM Groq β€” LLaMA 3.3 70B Versatile (free)
Backend FastAPI + Uvicorn
Database PostgreSQL 15 + SQLAlchemy (async)
UI Streamlit
Validation Pydantic v2
Infra Docker + Docker Compose

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages