← back to all projects

Natural language to SQL agent

2 agents routed per turn, SQL or conversation

LangGraph · LangChain · OpenAI · PGVector · PostgreSQL · SQLAlchemy · FastAPI · Docker · LangSmith · Python (uv, Ruff)

Text-to-SQL demos are easy. Text-to-SQL that runs against a real database without eventually doing something destructive is the actual problem. This agent translates natural language into SQL and executes it against a live PostgreSQL database, with the orchestration and guardrails that make that defensible.

Routing before generating

Not every turn is a query. “What were Q3 sales” and “what did you just do” need different machinery, so the graph routes each turn between two specialists: a SQL agent that handles database questions with retrieved context, and a ReAct chat agent with its own tools that handles conversational turns. Session memory carries state across turns, so follow-up questions resolve against what was already asked.

Teaching the schema by example

Rather than stuffing the entire schema into every prompt, the agent retrieves few-shot SQL examples relevant to the current question using PGVector, over embeddings of both the SQL context and prior queries. The index lives in the same PostgreSQL instance as the data it describes.

Guardrails and a human in the loop

Generated SQL is validated before it runs, and anything risky stops for explicit human approval rather than executing optimistically. This is the part that separates a demo from something you would point at a database you care about.

Built to be operated

LangGraph holds the control flow as an explicit graph, so routing, retrieval, generation, approval and execution are inspectable nodes instead of behaviour buried in a prompt chain. LangSmith traces every run and tracks token spend and cost per session. SQLAlchemy and psycopg handle execution, FastAPI serves it, Docker packages it, and the Python tooling is uv and Ruff on 3.12.