TellWorldAI World Archive
Ask中文

Home›Practice›Practice

Practice

A SQL agent with LangChain

Build an agent that answers questions about a SQLite database by writing SQL, then add human review before queries run.

Who this is for and what you will build

This article is for readers who want to ask a database questions in plain language and understand how an agent works step by step. By the end you will run a SQL agent on the SQLite sample database, follow its tool calls, and add a human review step before any query runs.

How the agent works

The agent first fetches the tables and their schemas, then decides which tables matter for the question. It reads the relevant schemas, writes a query, double-checks it with an LLM, and runs it. If the database reports an error, the agent corrects the query until it succeeds, and then it writes the answer from the results[1].

Safety first

Running model-generated SQL carries inherent risks. Database connection permissions should be limited to what the agent actually needs[1]. The database tools in the example are thin demonstration wrappers. They are not secure and are not meant for production use, so they need narrow permissions and validation specific to your application[1].

Prerequisites

  • Dependencies: Python uses pip install langchain langgraph, and JavaScript uses npm i langchain @langchain/core sqlite3 zod[1].
  • The sample database is chinook, a SQLite database provided as Chinook.db on a public GCS bucket. SQLite is lightweight and easy to set up[1].
  • A model that supports tool calling[1].
  • Tracing is optional. The two variables below let you inspect each step in LangSmith[1]:
export LANGSMITH_TRACING="true"
export LANGSMITH_API_KEY="..."

The Python version and its database tools

The Python version uses the built-in sqlite3 module. The sample output shows the dialect sqlite and 11 tables, including Album, Artist, Customer and Track[1].

The database tools are @tool functions from langchain.tools, and there are four of them. sql_db_query runs a query, sql_db_schema returns table schemas with sample rows, sql_db_list_tables lists the tables, and sql_db_query_checker checks a query before it runs[1]. The model reads these descriptions:

sql_db_query: Input to this tool is a detailed and correct SQL query, output is a result from the database.
    If the query is not correct, an error message will be returned.
    If an error is returned, rewrite the query, check the query, and try again.
    If you encounter an issue with Unknown column 'xxxx' in 'field list', use sql_db_schema to query the correct table fields.
sql_db_schema: Input to this tool is a comma-separated list of tables, output is the schema and sample rows for those tables.
    Be sure that the tables actually exist by calling sql_db_list_tables first!
    Example Input: table1, table2, table3
sql_db_list_tables: Input is an empty string, output is a comma-separated list of tables in the database.
sql_db_query_checker: Use this tool to double check if your query is correct before executing it.
    Always use this tool before executing a query with sql_db_query!

create_agent builds the agent. It is a ReAct agent, and a specific system prompt shapes its behavior[1].

Running it once

The sample question is "Which genre on average has the longest tracks?" The trace shows the agent listing the tables, reading the schemas of Track and Genre, checking the query with sql_db_query_checker, running it with sql_db_query, and then answering[1]. The sample answer names "Sci Fi & Fantasy", at about 2,911,783 milliseconds on average[1].

Adding human review

Letting a person see the SQL before it runs guards against mistakes and slow queries. LangChain's human-in-the-loop middleware can pause the agent before sql_db_query runs. Pausing and resuming requires a checkpointer[1]. After this is configured, a run stops with output like the following[1]:

...
INTERRUPTED:
Tool execution pending approval
Tool: sql_db_query
Args: {'query': 'SELECT g.Name AS Genre, AVG(t.Milliseconds) AS AvgTrackLength FROM Track t JOIN Genre g ON t.GenreId = g.GenreId GROUP BY g.Name ORDER BY AvgTrackLength DESC LIMIT 1;'}

To continue, resume with Command. In the example, accepting the query lets the run finish[1]. For more on the middleware options, see the human-in-the-loop guide, and for checkpointers see the short-term memory guide[1].

The JavaScript version

The JavaScript version defines an execute_sql tool. Before it runs a query, a check named _safe_sql is applied, and the human review step is configured on that tool[1]. In the sample output, Sci Fi & Fantasy has an average track length of about 48.5 minutes, or about 2,911,783 milliseconds[1].

Chatting in Studio (optional)

LangSmith Studio provides a client-side loop with memory, so the agent can be used as a chat interface. Questions such as "Tell me the scheme of the database" or "Show me the invoices for the 5 top customers" work there[1]. Studio needs pip install -U langgraph-cli[inmem]>=0.4.0 and a langgraph.json file in the directory where it runs[1]:

{
  "dependencies": ["."],
  "graphs": {
      "agent": "./sql_agent.py:agent",
      "graph": "./sql_agent_langgraph.py:graph"
  },
  "env": ".env"
}

Common problems

  • Over-broad database permissions: the most important thing to avoid. Restrict the account to read-only access on the tables it needs, as described in the safety section[1].
  • Different model output: the sample output was produced with OpenAI, and other models can answer differently[1].
  • Model choice: the model must support tool calling for this agent to work[1].

Next steps

Try the flow on the sample database first. Then point the agent at your own database and keep the human review step in place[1].

Adapted from the Build a SQL agent page of LangChain's open-source documentation[1], released under the MIT License.

Sources

  1. 1
    Build a SQL agentLangChain docs (MIT)

Cite this page: A SQL agent with LangChain. TellWorld, https://www.tellworld.net/practice/practice-langchain-sql-agent. Updated 2026-11-14

Related news

View all