LangChain SQL Agent教程:用自然语言查询数据库
技术背景
传统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
设置数据库
要查询数据库,首先需要设置一个。
- 加载加州住房数据集: 从 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
- 连接到 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查询生成、验证、执行到自然语言回答的完整流程。文章不仅提供代码实现,还剖析了核心原理、架构设计、常见错误及生产优化方案,帮助开发者掌握构建智能数据交互应用的关键技术。
- --
内容来源与验证
- 内容等级:PREMIUM_A
- 质量等级:A
- 难度:中级
- 验证等级:V1
- 原文作者:
- 原文日期:
- 来源许可:Apache-2.0
- 来源版本:
cd902b4e474edeeee79cbf3cecd3fa875b46d55a - 查看原文
站内还有更多完整实战教程
加入会员,解锁全部教程、完整代码与持续更新内容。
加入会员