【大模型】8.6自然语言转SQL并自动执行查询的智能问答系统

春联生成模型-中文-base

春联生成模型是达摩院AliceMind团队利用基础生成大模型在春联场景的应用,该模型可以通过输入两字随机祝福词,生成和祝福词相关的春联。

1. 代码功能简要说明

该代码基于LangChain框架整合OpenAI的gpt-3.5-turbo模型和MySQL数据库,实现自然语言转SQL并自动执行查询的智能问答系统,核心流程如下:

  1. 数据库连接:通过SQLAlchemy语法配置MySQL连接信息,初始化数据库交互对象;
  2. SQL生成:利用create_sql_query_chain将用户自然语言问题(如“员工表中有多少条数据?”)转为可执行的SQL语句;
  3. SQL执行:通过QuerySQLDataBaseTool自动执行生成的SQL,获取查询结果;
  4. 结果整合:结合“用户问题+生成的SQL+执行结果”,通过提示模板和模型生成自然语言回答,全程无需手动编写/执行SQL,实现自然语言与数据库的无缝交互。

2. 带逐行详细注释的完整代码

# 导入os库:1.配置网络代理(解决国内访问OpenAI API的网络限制) 2.配置LangChain环境变量
import os
# 导入itemgetter:用于从字典中提取指定key的值(本案例提取生成的SQL语句)
from operator import itemgetter

# 导入bs4(BeautifulSoup):本代码未实际使用,预留网页数据加载能力
import bs4
# 导入create_stuff_documents_chain:(未使用)基础RAG问答链,预留检索增强能力
from langchain.chains.combine_documents import create_stuff_documents_chain
# 导入create_history_aware_retriever:(未使用)历史感知检索器,预留上下文关联能力
from langchain.chains.history_aware_retriever import create_history_aware_retriever
# 导入create_retrieval_chain:(未使用)顶层RAG链,预留检索+问答整合能力
from langchain.chains.retrieval import create_retrieval_chain
# 导入create_sql_query_chain:核心组件,将自然语言问题转为SQL语句
from langchain.chains.sql_database.query import create_sql_query_chain
# 导入Chroma:(未使用)向量数据库,预留RAG能力
from langchain_chroma import Chroma
# 导入WebBaseLoader:(未使用)网页加载器,预留外部数据加载能力
from langchain_community.document_loaders import WebBaseLoader
# 导入QuerySQLDataBaseTool:SQL执行工具,自动执行生成的SQL语句并返回结果
from langchain_community.tools import QuerySQLDataBaseTool
# 导入SQLDatabase:LangChain封装的数据库交互类,支持MySQL/PostgreSQL等
from langchain_community.utilities import SQLDatabase
# 导入StrOutputParser:输出解析器,将模型返回的消息对象转为纯字符串
from langchain_core.output_parsers import StrOutputParser
# 导入提示模板相关:
# - ChatPromptTemplate:聊天型提示模板(未使用)
# - MessagesPlaceholder:会话历史占位符(未使用)
# - PromptTemplate:基础文本提示模板(用于整合SQL结果生成回答)
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, PromptTemplate
# 导入Runnable相关:
# - RunnableWithMessageHistory:(未使用)会话历史包装器
# - RunnablePassthrough:参数透传/赋值组件,串联SQL生成→执行→回答流程
from langchain_core.runnables import RunnableWithMessageHistory, RunnablePassthrough
# 导入RecursiveCharacterTextSplitter:(未使用)文本切割器,预留RAG能力
from langchain_text_splitters import RecursiveCharacterTextSplitter
# 导入ChatMessageHistory:(未使用)会话历史存储,预留上下文能力
from langchain_community.chat_message_histories import ChatMessageHistory
# 导入OpenAI相关组件:
# - ChatOpenAI:gpt-3.5-turbo聊天模型,负责生成SQL和自然语言回答
# - OpenAIEmbeddings:(未使用)文本嵌入模型,预留RAG能力
from langchain_openai import ChatOpenAI, OpenAIEmbeddings

# 配置HTTP代理:127.0.0.1:7890是代理工具的本地端口,确保访问OpenAI API
os.environ['http_proxy'] = '127.0.0.1:7890'
# 配置HTTPS代理:OpenAI API基于HTTPS,需配置该代理确保请求正常
os.environ['https_proxy'] = '127.0.0.1:7890'

# 开启LangChain Tracing V2:追踪链的执行过程(SQL生成、执行、回答),便于调试
os.environ["LANGCHAIN_TRACING_V2"] = "true"
# 配置LangChain项目名称:追踪数据归类到该项目,便于管理不同应用
os.environ["LANGCHAIN_PROJECT"] = "LangchainDemo"
# 配置LangChain API Key:认证LangChain Smith服务(追踪功能必需),替换为自己的密钥
os.environ["LANGCHAIN_API_KEY"] = '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'
# os.environ["TAVILY_API_KEY"] = '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'  # 未使用Tavily,注释掉

# ===================== 核心步骤1:初始化OpenAI聊天模型 =====================
# 聊天机器人案例
# 创建ChatOpenAI模型实例:指定gpt-3.5-turbo(性价比高,适合SQL生成/简单问答)
model = ChatOpenAI(model='gpt-3.5-turbo')

# ===================== 核心步骤2:配置并连接MySQL数据库 =====================
# sqlalchemy 初始化MySQL数据库的连接(SQLAlchemy标准URL格式)
# 数据库连接参数:
HOSTNAME = '127.0.0.1'  # 数据库服务器地址(本地)
PORT = '3306'           # MySQL默认端口
DATABASE = 'test_db8'   # 要连接的数据库名
USERNAME = 'root'       # 数据库用户名
PASSWORD = '123123'     # 数据库密码

# 构建MySQL连接URL(mysqlclient驱动):
# 格式:mysql+mysqldb://用户名:密码@地址:端口/数据库名?字符集
MYSQL_URI = 'mysql+mysqldb://{}:{}@{}:{}/{}?charset=utf8mb4'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)

# 初始化数据库交互对象:通过URL连接MySQL,封装数据库操作(查询、执行SQL等)
db = SQLDatabase.from_uri(MYSQL_URI)

# 测试连接是否成功(注释):
# print(db.get_usable_table_names())  # 输出数据库中可访问的表名(如t_emp)
# print(db.run('select * from t_emp limit 10;'))  # 执行SQL,输出前10条员工数据

# ===================== 核心步骤3:创建自然语言转SQL的链 =====================
# 直接使用大模型和数据库整合, 只能根据你的问题生成SQL
# 初始化生成SQL的chain:输入自然语言问题,输出对应的SQL语句
# - model:gpt-3.5-turbo模型(懂SQL语法和自然语言)
# - db:数据库对象(模型会读取表结构,生成适配的SQL)
test_chain = create_sql_query_chain(model, db)

# 测试SQL生成(注释):
# resp = test_chain.invoke({'question': '请问:员工表中有多少条数据?'})
# print(resp)  # 输出:SELECT COUNT(*) FROM t_emp;

# ===================== 核心步骤4:创建回答提示模板 =====================
# 定义回答模板:整合“用户问题+生成的SQL+执行结果”,让模型生成自然语言回答
answer_prompt = PromptTemplate.from_template(
    """给定以下用户问题、SQL语句和SQL执行后的结果,回答用户问题。
    Question: {question}  # 变量:用户的自然语言问题
    SQL Query: {query}    # 变量:模型生成的SQL语句
    SQL Result: {result}  # 变量:SQL执行后的结果
    回答: """             # 模型需要生成的内容
)

# ===================== 核心步骤5:创建SQL执行工具 =====================
# 创建一个执行sql语句的工具:封装db的run方法,输入SQL语句,输出执行结果
execute_sql_tool = QuerySQLDataBaseTool(db=db)

# ===================== 核心步骤6:构建完整的“生成SQL→执行→回答”链 =====================
# 1、生成SQL,2、执行SQL,3、生成回答
# 链的执行逻辑拆解:
# - RunnablePassthrough.assign(query=test_chain):透传用户输入,同时调用test_chain生成SQL,存入query变量
# - .assign(result=itemgetter('query') | execute_sql_tool):提取query变量(生成的SQL),传给execute_sql_tool执行,结果存入result变量
# - | answer_prompt:将question/query/result填充到回答模板
# - | model:模型基于填充后的模板生成自然语言回答
# - | StrOutputParser():将模型返回的消息对象转为纯字符串(便于输出)
chain = (RunnablePassthrough.assign(query=test_chain).assign(result=itemgetter('query') | execute_sql_tool)
         | answer_prompt
         | model
         | StrOutputParser()
         )

# ===================== 核心步骤7:调用链并获取回答 =====================
# 优化print:先打印用户问题,再执行链,最后打印完整结果(生成的SQL、执行结果、最终回答)
print('=== 自然语言转SQL问答结果 ===')
user_question = '请问:员工表中有多少条数据?'
print(f'用户问题:{user_question}')

# 手动获取生成的SQL(便于展示)
generated_sql = test_chain.invoke({'question': user_question})
print(f'模型生成的SQL:{generated_sql}')

# 手动执行SQL(便于展示)
sql_result = execute_sql_tool.invoke(generated_sql)
print(f'SQL执行结果:{sql_result}')

# 调用完整链获取最终回答
rep = chain.invoke(input={'question': user_question})
print(f'模型最终回答:{rep}')

3. 无任何注释的代码版本

import os
from operator import itemgetter

import bs4
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains.history_aware_retriever import create_history_aware_retriever
from langchain.chains.retrieval import create_retrieval_chain
from langchain.chains.sql_database.query import create_sql_query_chain
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.tools import QuerySQLDataBaseTool
from langchain_community.utilities import SQLDatabase
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, PromptTemplate
from langchain_core.runnables import RunnableWithMessageHistory, RunnablePassthrough
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_openai import ChatOpenAI, OpenAIEmbeddings

os.environ['http_proxy'] = '127.0.0.1:7890'
os.environ['https_proxy'] = '127.0.0.1:7890'

os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "LangchainDemo"
os.environ["LANGCHAIN_API_KEY"] = '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'

model = ChatOpenAI(model='gpt-3.5-turbo')

HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'test_db8'
USERNAME = 'root'
PASSWORD = '123123'
MYSQL_URI = 'mysql+mysqldb://{}:{}@{}:{}/{}?charset=utf8mb4'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)

db = SQLDatabase.from_uri(MYSQL_URI)

test_chain = create_sql_query_chain(model, db)

answer_prompt = PromptTemplate.from_template(
    """给定以下用户问题、SQL语句和SQL执行后的结果,回答用户问题。
    Question: {question}
    SQL Query: {query}
    SQL Result: {result}
    回答: """
)

execute_sql_tool = QuerySQLDataBaseTool(db=db)

chain = (RunnablePassthrough.assign(query=test_chain).assign(result=itemgetter('query') | execute_sql_tool)
         | answer_prompt
         | model
         | StrOutputParser()
         )

print('=== 自然语言转SQL问答结果 ===')
user_question = '请问:员工表中有多少条数据?'
print(f'用户问题:{user_question}')

generated_sql = test_chain.invoke({'question': user_question})
print(f'模型生成的SQL:{generated_sql}')

sql_result = execute_sql_tool.invoke(generated_sql)
print(f'SQL执行结果:{sql_result}')

rep = chain.invoke(input={'question': user_question})
print(f'模型最终回答:{rep}')

4. 核心知识点详解(系统梳理+表格)

4.1 核心组件/概念对照表
核心组件/概念导入路径通俗解释核心用法本案例作用
SQLDatabaselangchain_community.utilities.SQLDatabaseLangChain封装的数据库交互类,支持多数据库连接SQLDatabase.from_uri(数据库URL)连接MySQL数据库,提供表结构查询、SQL执行能力
create_sql_query_chainlangchain.chains.sql_database.query.create_sql_query_chain自然语言转SQL的核心链,模型基于表结构生成适配SQLcreate_sql_query_chain(模型, 数据库对象)将“员工表有多少条数据?”转为SELECT COUNT(*) FROM t_emp;
QuerySQLDataBaseToollangchain_community.tools.QuerySQLDataBaseToolSQL执行工具,封装数据库run方法,输入SQL输出结果QuerySQLDataBaseTool(db=数据库对象)执行生成的SQL语句,返回员工表数据条数(如50)
RunnablePassthrough.assignlangchain_core.runnables.RunnablePassthrough参数赋值组件,透传输入并新增变量(如query/result)RunnablePassthrough.assign(变量名=链/工具)透传用户问题,同时生成SQL(query)、执行SQL(result)
itemgetteroperator.itemgetter字典键提取工具,快速获取指定key的值itemgetter('key')(字典)提取生成的SQL(query变量),传给执行工具
PromptTemplatelangchain_core.prompts.PromptTemplate基础文本提示模板,支持变量填充PromptTemplate.from_template(模板字符串)整合“问题+SQL+结果”,引导模型生成自然语言回答
StrOutputParserlangchain_core.output_parsers.StrOutputParser输出解析器,将模型消息转为纯字符串StrOutputParser().invoke(模型响应)将模型返回的AIMessage转为纯文本回答(如“员工表有50条数据”)
4.2 关键知识点深度解释
(1)MySQL连接URL格式

本案例使用mysql+mysqldb驱动(需安装mysqlclient库),其他常见驱动格式:

  • mysql+pymysql:使用pymysql驱动(需安装pymysql),URL为mysql+pymysql://用户名:密码@地址:端口/数据库名
  • 核心参数:charset=utf8mb4确保支持emoji等特殊字符,避免中文乱码。
(2)create_sql_query_chain的核心能力

模型会自动:

  1. 读取数据库的表结构(如t_emp的字段、类型);
  2. 将自然语言问题转为符合MySQL语法的SQL;
  3. 避免危险操作(如DROP/DELETE,默认配置会过滤);
  4. 适配表名/字段名(如用户说“员工表”,模型匹配到t_emp)。
(3)完整链的执行流程(可视化)

flowchart TD
A[用户问题:员工表有多少条数据?] --> B[RunnablePassthrough.assign]
B --> C1[test_chain生成SQL:SELECT COUNT(*) FROM t_emp;]
B --> C2[透传question变量]
C1 --> D[itemgetter提取SQL,传给execute_sql_tool]
D --> E[执行SQL,返回结果:50]
C2 & C1 & E --> F[answer_prompt填充变量]
F --> G[gpt-3.5-turbo生成回答]
G --> H[StrOutputParser转为纯字符串]
H --> I[最终回答:员工表中有50条数据。]

(4)StrOutputParser的必要性

模型返回的原始响应是AIMessage(content='员工表中有50条数据。')StrOutputParser会提取content字段转为纯字符串,避免直接打印出现AIMessage对象的冗余信息。

5. print函数修改说明

5.1 优化对比与原因
原代码print优化后print核心改进
print(rep)print('=== 自然语言转SQL问答结果 ===')
print(f'用户问题:{user_question}')
print(f'模型生成的SQL:{generated_sql}')
print(f'SQL执行结果:{sql_result}')
print(f'模型最终回答:{rep}')
1. 标注模块标题,清晰区分问答流程;
2. 分步展示“问题→生成SQL→执行结果→最终回答”,小白能理解全流程;
3. 避免仅打印最终回答导致的“黑盒感”,便于调试(如SQL生成错误可快速定位)
5.2 输出示例(参考)
=== 自然语言转SQL问答结果 ===
用户问题:请问:员工表中有多少条数据?
模型生成的SQL:SELECT COUNT(*) FROM t_emp;
SQL执行结果:50
模型最终回答:员工表中有50条数据。
5.3 环境依赖说明

运行代码前需安装以下库(终端执行):

pip install langchain langchain-openai langchain-community chromadb beautifulsoup4 mysqlclient sqlalchemy
  • mysqlclient:MySQL连接驱动(若安装失败,可换pymysql,并修改URL为mysql+pymysql://...);
  • sqlalchemy:数据库ORM框架,LangChain依赖其实现数据库连接。

总结(关键点回顾)

  1. 核心能力:实现“自然语言→SQL→执行→自然语言回答”的全流程自动化,无需手动编写/执行SQL;
  2. 核心流程:数据库连接→SQL生成→SQL执行→结果整合→自然语言回答;
  3. 关键组件
    • create_sql_query_chain是自然语言转SQL的核心;
    • QuerySQLDataBaseTool实现SQL自动执行;
    • RunnablePassthrough.assign串联多步骤,StrOutputParser简化输出;
  4. 实用技巧
    • 数据库URL需指定charset=utf8mb4避免中文乱码;
    • 测试时先打印生成的SQL,确认无误后再执行,避免误操作;
    • 可通过LangChain Tracing查看SQL生成/执行的详细日志,便于调试。

您可能感兴趣的与本文相关的镜像

春联生成模型-中文-base

春联生成模型-中文-base

文本生成
GPT-3

春联生成模型是达摩院AliceMind团队利用基础生成大模型在春联场景的应用,该模型可以通过输入两字随机祝福词,生成和祝福词相关的春联。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值