LangChain SQL Agent教程:用自然语言查询数据库

本教程面向有编程基础的开发者,深入讲解如何利用LangChain和Gemini API构建自然语言查询SQL数据库的系统。通过加州住房数据集示例,逐步演示从环境配置、数据库连接、SQL查询生成、验证、执行到自然语言回答的完整流程。文章不仅提供代码实现,还剖析了核心原理、架构设计、常见错误及生产优化方案,帮助开发者掌握构建智能数据交互应用的关键技术。

技术背景

传统SQL查询需要用户掌握结构化查询语言,对非技术用户门槛高。自然语言查询SQL(NL2SQL)旨在让用户用日常语言获取数据库信息,提升数据可访问性。LangChain提供链式抽象,简化LLM与外部工具(如数据库)的集成。Gemini模型具备强大的文本理解和生成能力,能准确将自然语言转换为SQL。此技术适用于数据分析、商业智能、客服系统等场景,但受限于模型对复杂查询的理解、数据库结构变化及安全性问题。

核心原理

核心原理是利用LLM将自然语言问题转换为SQL查询,通过LangChain的链式组件串联多个步骤:1) 使用create_sql_query_chain生成初始SQL(基于数据库schema和示例);2) 通过验证链提取并校验SQL;3) 使用QuerySQLDataBaseTool执行查询;4) 最后用LLM将查询结果组织成自然语言回答。数据流为:用户问题→LLM生成SQL→验证→执行→结果→LLM生成回答。关键设计决策包括使用temperature=0保证确定性、验证步骤防止SQL注入或语法错误、以及使用RunnablePassthrough传递上下文。

架构分析

系统采用模块化链式架构,各组件职责单一:SQLDatabase封装数据库连接和元数据;create_sql_query_chain负责SQL生成;validate_chain确保SQL有效性;execute_query执行SQL;answer_chain生成最终回答。这种设计便于替换组件(如更换LLM或数据库),并支持流式处理。LangChain的Runnable协议允许灵活组合,RunnablePassthrough用于传递中间结果,itemgetter提取特定字段。生产环境可考虑增加缓存、重试机制和日志监控。

完整实战教程

##### 版权所有 2026 Google LLC.

# @title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

Gemini API: 使用 LangChain 与 SQL 对话

对于人类来说,阅读SQL数据库可能具有挑战性。然而,通过准确的提示,Gemini模型可以基于数据生成答案。通过使用Gemini API,您将能够通过与SQL数据库聊天来检索必要的信息。

%pip install -U -q "google-genai>=2.9.0" langchain langchain-community langchain-google-genai
import sqlite3

from langchain.chains import create_sql_query_chain, LLMChain
from langchain.prompts import PromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.output_parsers import StrOutputParser
from langchain_community.utilities import SQLDatabase
from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool
from operator import itemgetter
from langchain_core.runnables import RunnablePassthrough
from google import genai
from IPython.display import Markdown

配置你的 API 密钥

要运行以下单元格,你的 API 密钥必须存储在名为 GEMINI_API_KEY 的 Colab 密钥中。如果你还没有 API 密钥,或者不确定如何创建 Colab 密钥,请参阅 身份验证 示例。

import os
from google.colab import userdata
GEMINI_API_KEY=userdata.get('GEMINI_API_KEY')

os.environ["GEMINI_API_KEY"] = GEMINI_API_KEY

设置数据库

要查询数据库,首先需要设置一个。

  1. 加载加州住房数据集: 从 sklearn.datasets 加载数据集,并将其提取到 DataFrame 中。
from sklearn.datasets import fetch_california_housing

california_housing_bunch = fetch_california_housing(as_frame=True)
california_housing_df = california_housing_bunch.frame
  1. 连接到 SQLite 数据库: 数据库将存储在指定的文件中。
conn = sqlite3.connect("mydatabase.db")

# Write the DataFrame to a SQL table named 'housing'.
california_housing_df.to_sql("housing", conn, index=False)
# Create an SQLDatabase object
db = SQLDatabase.from_uri("sqlite:///mydatabase.db")

查询问题

建立数据库连接后,SQLDatabase 对象现在包含了关于我们数据库的信息,模型可以访问这些信息。

现在你可以开始让 LLM 生成查询了。

# you can see what information is available
Markdown(db.get_table_info())
# Define query chain
llm = ChatGoogleGenerativeAI(model="gemini-3.7-flash", temperature=0)
write_query_chain = create_sql_query_chain(llm, db)

你可以使用适合我们数据库的 create_sql_query_chain。它为各种类型的 SQL 提供了默认提示,包括 Oracle、Google SQL、MySQL 等。

在这种情况下,默认提示适合该任务。不过,你也可以随意尝试自己编写这部分链,以满足你的偏好。

Markdown(write_query_chain.get_prompts()[0].template)
response = write_query_chain.invoke({"question": "What is the total population?"})
display(Markdown(response))
db.run('SELECT SUM("Population") FROM housing')

很好!SQL 查询是正确的,但在数据库直接执行之前,需要适当的格式化。

验证查询

您将把上一个查询的输出传递给一个模型,该模型将仅提取SQL查询并确保其有效性。

validate_prompt = PromptTemplate(
    input_variables=["not_formatted_query"],
    template="""
        You are going to receive a text that contains a SQL query. Extract that query.
        Make sure that it is a valid SQL command that can be passed directly to the Database.
        Avoid using Markdown for this task.
        Text: {not_formatted_query}
    """
)
validate_chain = write_query_chain | validate_prompt | llm | StrOutputParser()
validate_chain.invoke({"question": "What is the total population?"})

自动查询

现在,让我们使用 *QuerySQLDataBaseTool* 来自动化查询数据库的过程。该工具可以接收链中先前部分的文本,执行查询,并返回答案。

execute_query = QuerySQLDataBaseTool(db=db)
execute_chain = validate_chain | execute_query
execute_chain.invoke({"question": "What is the total population?"})

生成回答

你几乎完成了!

为了增强我们的输出,你不仅会使用LLM来获取数字,还会生成格式正确且自然的语言回答。

answer_prompt = PromptTemplate.from_template("""
    You are going to receive a original user question, generated SQL query, and result of said query. You should use this information to answer the original question. Use only information provided to you.

    Original Question: {question}
    SQL Query: {query}
    SQL Result: {result}
    Answer: """
)

answer_chain = (
    RunnablePassthrough.assign(query=validate_chain).assign(
        result=itemgetter("query") | execute_query
    )
    | answer_prompt | llm | StrOutputParser()
)

answer_chain.invoke({"question": "What is the total population?"})

后续步骤

恭喜!您已成功创建了一个可与 SQL 交互的功能链。现在,请随意提出不同的问题,进一步探索。

常见问题

常见错误:1) API密钥未正确设置,导致认证失败;2) 数据库连接字符串错误,需检查SQLite文件路径;3) 生成的SQL语法错误,可通过验证链或手动检查;4) 模型输出包含Markdown格式,需在提示中明确避免;5) 查询结果过大导致内存问题,可限制返回行数。排查方法:打印中间链输出,使用db.run测试SQL,检查日志。生产优化:使用连接池、异步执行、缓存常用查询、限制查询权限、使用参数化查询防止注入。

企业应用扩展

可扩展方向:1) 支持更多数据库类型(如PostgreSQL、MySQL);2) 增加多轮对话能力,维护对话状态;3) 集成可视化工具展示查询结果;4) 使用向量数据库存储历史查询以优化提示;5) 实现查询审核和权限控制;6) 结合RAG技术处理非结构化数据。

总结

本教程面向有编程基础的开发者,深入讲解如何利用LangChain和Gemini API构建自然语言查询SQL数据库的系统。通过加州住房数据集示例,逐步演示从环境配置、数据库连接、SQL查询生成、验证、执行到自然语言回答的完整流程。文章不仅提供代码实现,还剖析了核心原理、架构设计、常见错误及生产优化方案,帮助开发者掌握构建智能数据交互应用的关键技术。

内容来源与验证

继续系统学习

站内还有更多完整实战教程

加入会员,解锁全部教程、完整代码与持续更新内容。

加入会员
查看全部API 与工程实践教程