前言
在项目开发中,数据库设计是早期的核心工作之一。我们需要考虑业务表结构、关联关系及索引优化,并预想未来核心需求。对于刚入门数据库的学习者而言,熟练掌握 SQL 可能具有一定难度。然而在 AIGC 时代,我们拥有了全新的编程范式。NLP 和大模型作为编程助理,让我们可以快速介入复杂的数据库业务。
我们只需要设计好相应的 Prompt,LLM 就能理解需求并生成 SQL,供我们执行。目前 GitHub 上已有不少 TextToSQL 的 AIGC 项目,值得参考。对于初学者来说,AIGC 是提升学习力的好工具,在学习每一项编程技能时,都可以思考如何利用 AIGC 优化学习路线或工作思路。
AIGC 新的数据库查询范式
上图展示了 AIGC 重构传统数据库查询业务的流程图。数据库查询业务的开始端回归文本表达,这得益于 LLM 的自然语言处理能力。随着大模型能力的提升和 Agent 的产品力增强,未来与数据库交互甚至管理,可能会由非技术人员完成,极大降低了门槛。
流程如下:
- LLM 理解 Question 的数据需求。
- 生成 SQL 语句。
- 通过 LangChain 等开发的 SQL Agent 交给数据库执行。
- 执行结果再由 LLM 进行处理(如输出格式)。
- 用户得到最终结果。
这就是现在非常流行的 Agent 概念,这里是 SQL Agent,重构了原来比较专业、复杂的数据库流程。
SQL Agent
AI 应用的开发,本质上是将之前的业务转成 AI Agent 来实现。使用 SQL Agent,用户既不需要知道数据库的结构,也不需要会写 SQL。我们只需要与 SQL Agent 对话,就可以得到所需的结果。
创建数据表
假设我们要做一个干货店的项目。选用 SQLite,因为它是轻量级的磁盘文件数据库,没有复杂的服务器部署,非常适合初创项目使用。虽然 SQLite 是轻量级的,但它支持大部分 SQL 特性,如事务、触发器和视图等。因此,它非常适合需要保存数据但不需要大型数据库系统的移动应用或 Web 应用。
Python 内置了 sqlite3 模块,可以直接使用。
# 导入 sqlite3 库,python 内置
import sqlite3
# 连接到数据库
conn = sqlite3.connect('DryGood.db')
cursor = conn.cursor()
# 执行 SQL 命令来创建 DryGoods 表
cursor.execute('''
CREATE TABLE DryGoods (
ID INTEGER PRIMARY KEY,
Name TEXT NOT NULL,
Type TEXT NOT NULL,
Source TEXT NOT NULL,
PurchasePrice REAL,
SalePrice REAL
);
''')
# 插入初始化数据
dry_goods = [
('海带', 'DryFood', '辽宁', 5.2, 8.9),
('香菇', 'DryFood', '广东', 26.5, 33.2),
('木耳', 'DryFood', '山东', 34.6, 44.2)
]
for item in dry_goods:
cursor.execute('''
INSERT INTO DryGoods (Name, Type, Source, PurchasePrice, SalePrice)
VALUES (?, ?, ?, ?, ?);
''', item)
# 提交更改
conn.commit()
# 关闭数据库连接
conn.close()
首先,我们连接到数据库 DryGood,接着创建了一个数据表 DryGoods,包含 ID、类型、产地、进价、售价等字段。接着准备了一些初始化数据,循环插入数据表。完成后,关闭数据库的连接。
LangChain 来接管数据库
LangChain 数据库查询功能在某些版本中处于实验阶段,我们需要安装 langchain-experimental。相应代码:
pip install langchain-experimental
LangChain 为我们准备了 SQLDatabaseChain 来完成该工作。
# SQLDatabase 可以让我们连接数据库
from langchain.utilities import SQLDatabase
# 使用 OpenAI 大模型
from langchain.llms import OpenAI
# SQLDatabaseChain chain 任务
from langchain_experimental.sql import SQLDatabaseChain
# 连接到 DryGood 数据库
db = SQLDatabase.from_uri("sqlite:///DryGood.db")
# 创建 llm 实例
llm = OpenAI(temperature=0, verbose=True)
# 创建 SQLChain 实例,目前还在实验阶段
db_chain = SQLDatabaseChain.from_llm(llm, db, api_key='', verbose=True)
# 运行与干货运营相关的问题
response = db_chain.run("有多少种不同的干货?")
print(response)
response = db_chain.run("平均销售价格是多少?")
print(response)
db_chain.run() 查询了一些与干货运营相关的问题,Chain 会将这些自然语言转换成 SQL 语句,并查询数据库,拿到查询结果后,又转换成自然语言输出。
上 Agent
除了通过 SQLDatabaseChain 完成数据库 LLM 查询,LangChain 还提供了 SQL Agent 也能完成。在早期,我是这样理解的,LangChain 里的 Chain 是将某种具体任务和 LLM 结合的工作方式,当某些工作成为一个产品或业务场景使用比较频繁时,LangChain 就会推出相应的 Agent,来展现魔法。
相比较 Chain,SQL Agent 有更强大的能力,比如它具有更强的纠错能力。数据库操作出错时,它会重新生成并执行新的查询。
from langchain.utilities import SQLDatabase
from langchain.llms import OpenAI
# sql agent
from langchain.agents import create_sql_agent
# 工具包,可以创建并执行查询 检索语法 等
from langchain.agents.agent_toolkits import SQLDatabaseToolkit
from langchain.agents.agent_types import AgentType
# 连接到 DryGood 数据库
db = SQLDatabase.from_uri("sqlite:///DryGood.db")
llm = OpenAI(temperature=0, verbose=True, openai_sdk='')
# 创建 SQL Agent
agent_executor = create_sql_agent(
llm=llm,
toolkit=SQLDatabaseToolkit(db=db, llm=llm),
verbose=True,
agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
)
# 使用 Agent 执行 SQL 查询
questions = [
"有多少种干货?",
"平均销售价格是多少?",
]
for question in questions:
response = agent_executor.run(question)
print(response)
输出以 agent 的感觉来了,让我想起了 AutoGen。
总结与最佳实践
- LangChain 通过 SQLDatabaseChain,调用大模型,神奇地完成了从自然语言查询任务描述到自然语言的新型 SQL 查询范式。
- LangChain Agent 实力强大,TextToSQL 可以开启这个场景的深度学习了。
在实际应用中,建议注意以下几点:
- 温度设置:生成 SQL 时通常将 temperature 设为 0,以保证输出的确定性和准确性。
- Schema 提示:如果数据库结构复杂,建议在 Prompt 中明确提供表结构和字段说明,以提高准确率。
- 错误处理:Agent 模式相比 Chain 模式具有自我修正能力,适合处理更复杂的查询逻辑。
- 成本考量:每次查询都会消耗 Token 资源,对于高频查询场景需评估成本效益。
通过上述步骤,我们可以快速构建一个基于大模型的智能数据库查询系统,降低数据分析的门槛。

