文章目录
前言
在大模型交互的时候,我们有时需要大模型借助已有的数据来作答,通常业务数据会存储在数据库里,需要大模型具备生成正确sql并查询数据库的能力。因此我们一起来练习如何使用LangChain库使用大模型(如GPT-4)与SQL数据库进行交互。
一、手动告知大模型数据库结构
要想大模型生成我们需要的数据首先要解决的重要问题是,大模型(例如GPT-4)如何知道数据库表的结构。为了实现这一点,我们需要在提示中包含关于数据库模式(schema)的信息。这样,模型可以利用这些信息生成正确的SQL查询。
1. 示例
以下是一个完整示例,展示如何将数据库表结构信息包含在提示中:
1)首先,你需要确保安装了相关的Python包。你可以使用以下命令安装:
pip install langchain openai sqlalchemy
2)接下来是示例代码:
import os
from langchain import OpenAI, PromptTemplate
from langchain.chains import LLMChain
from sqlalchemy import create_engine, text
# 设置OpenAI API密钥
os.environ['OPENAI_API_KEY'] = 'your_openai_api_key'
# 创建SQLAlchemy引擎连接到SQLite数据库(或其他数据库)
engine = create_engine('sqlite:///example.db')
# 创建一个示例表和一些数据
with engine.connect() as conn:
conn.execute(text('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER
)
'''))
conn.execute(text('''
INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 24), ('Charlie', 29)
'''))
conn.execute(text('''
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
amount DECIMAL,
FOREIGN KEY(user_id) REFERENCES users(id)
)
'''))
conn.execute(text('''
INSERT INTO orders (user_id, amount) VALUES (1, 99.99), (2, 50.00), (3, 75.50)
'''))
# 定义一个函数来执行SQL查询
def execute_query(query):
with engine.connect() as conn:
result = conn.execute(text(query))
return result.fetchall()
# 获取数据库的表结构信息
def get_table_schema():
with engine.connect() as conn:
result = conn.execute(text("SELECT name FROM sqlite_master WHERE type='table';"))
tables = result.fetchall()
schema = {}
for table in tables:
table_name = table[0]
result = conn.execute(text(f"PRAGMA table_info({table_name});"))
columns = result.fetchall()
schema[table_name] = [column[1] for column in columns]
return schema
# 创建一个LangChain模型
llm = OpenAI(model_name='text-davinci-003')
# 定义查询数据库的函数
def query_database(prompt, schema):
# 将表结构信息包含在提示中
schema_info = "\n".join([f"Table {table}: {', '.join(columns)}" for table, columns in schema.items()])
full_prompt = f"""
以下是数据库的表结构信息:
{schema_info}
请根据以下描述生成一个SQL查询:
描述: {prompt}
生成的SQL查询:
"""
chain = LLMChain(llm=llm, prompt=PromptTemplate(full_prompt))
query = chain.run()
result = execute_query(query)
return result
# 获取数据库表结构
schema = get_table_schema()
# 示例:生成一个查询并执行
prompt = "查询所有年龄大于25岁的用户的姓名。"
result = query_database(prompt, schema)
print(result)
2. 解释
1) 获取数据库表结构:
- get_table_schema()
函数从数据库中提取表结构信息,并返回一个包含表名和列名的字典。
2) 包含表结构信息的提示:
- 在 query_database()
函数中,将表结构信息添加到提示中,使得模型能够了解数据库的模式。
3) 完整的提示模板:
- 在生成SQL查询时,包含表结构信息的完整提示会传递给模型,从而帮助其生成正确的SQL查询。
通过这种方式,大模型能够根据提供的表结构信息生成适当的SQL查询。这样可以确保模型能够理解数据库的结构,并生成符合该结构的查询。
二、LangChain 提供了一些内置工具和实用程序来简化与数据库的交互
LangChain 提供了一些内置工具和实用程序来简化与数据库的交互,包括自动获取表结构信息并生成相应的SQL查询。create_sql_query_chain
和 SQLDatabase
类确实可以用来实现这一功能。
以下是一个更完整的示例,演示如何使用这两个类与数据库交互:
1. 安装所需的包
确保安装了所需的包:
pip install langchain openai sqlalchemy langchain_community
2. 示例代码
import os
from langchain import OpenAI
from langchain.chains import create_sql_query_chain
from langchain_community.utilities import SQLDatabase
from sqlalchemy import create_engine, text
# 设置OpenAI API密钥
os.environ['OPENAI_API_KEY'] = 'your_openai_api_key'
# 创建SQLAlchemy引擎连接到SQLite数据库(或其他数据库)
engine = create_engine('sqlite:///example.db')
# 创建一个示例表和一些数据
with engine.connect() as conn:
conn.execute(text('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER
)
'''))
conn.execute(text('''
INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 24), ('Charlie', 29)
'''))
conn.execute(text('''
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
amount DECIMAL,
FOREIGN KEY(user_id) REFERENCES users(id)
)
'''))
conn.execute(text('''
INSERT INTO orders (user_id, amount) VALUES (1, 99.99), (2, 50.00), (3, 75.50)
'''))
# 使用SQLDatabase连接到数据库
db = SQLDatabase(engine)
# 创建一个LangChain模型
llm = OpenAI(model_name='text-davinci-003')
# 创建SQL查询链
sql_chain = create_sql_query_chain(llm, db)
# 定义查询数据库的函数
def query_database(prompt):
result = sql_chain.run(prompt)
return result
# 示例:生成一个查询并执行
prompt = "查询所有年龄大于25岁的用户的姓名。"
result = query_database(prompt)
print(result)
3. 解释
1)环境设置:确保你有一个OpenAI API密钥,并将其设置为环境变量。这里假设你使用的是OpenAI的API。
2) 数据库设置:使用SQLAlchemy连接到SQLite数据库,并创建一个示例表 users
和 orders
。
3) 连接数据库:使用 SQLDatabase
类连接到数据库。SQLDatabase
将帮助获取数据库的表结构信息。
4) 创建LangChain模型:使用 OpenAI
类创建一个模型实例。
5) 创建SQL查询链:使用 create_sql_query_chain
创建一个SQL查询链,这个链会根据提供的自然语言提示生成SQL查询。
6) 定义查询函数:
- query_database(prompt)
:通过SQL查询链生成SQL查询并执行。
7) 示例用法:
- 提供一个描述性提示,如“查询所有年龄大于25岁的用户的姓名”。
- 通过LangChain模型生成SQL查询,并执行查询。
通过这种方式,LangChain的工具将自动处理数据库的表结构信息,并生成符合该结构的SQL查询。这大大简化了与数据库交互的过程,并减少了手动编码的需求。
三、create_sql_query_chain
和 SQLDatabase
的原理是什么
create_sql_query_chain
是 LangChain 提供的一个便利工具,用于简化与SQL数据库的交互。它结合了自然语言处理和SQL查询生成的能力,使得用户能够使用自然语言指令查询数据库。让我们深入探讨一下它的工作原理。
数据库模式提取:
SQLDatabase 会自动连接数据库并提取其模式信息。这包括查询数据库元数据以获取所有表和列的详细信息。
提示生成:
create_sql_query_chain 使用数据库模式信息和用户提供的自然语言查询,自动生成一个适合的SQL查询提示。
查询生成和执行:
大模型根据提示生成SQL查询,SQL查询链负责执行该查询并返回结果。
通过这种自动化流程,用户可以直接使用自然语言查询数据库,而无需手动编写SQL查询或提取数据库结构信息。这极大地简化了与数据库的交互,并使得非技术用户也能方便地进行复杂的数据查询。
四、mysql数据库示例
使用MySQL代替SQLite进行数据库连接和查询只需要进行少量修改。主要是在创建数据库连接时要使用MySQL的连接字符串,并确保安装了MySQL的Python连接器(如 mysql-connector-python
或 pymysql
)。
以下是如何使用MySQL进行相同操作的示例:
1. 安装所需的包
首先,确保安装了MySQL连接器,例如 mysql-connector-python
:
pip install mysql-connector-python langchain openai sqlalchemy langchain_community
2. 示例代码
import os
from langchain import OpenAI
from langchain.chains import create_sql_query_chain
from langchain_community.utilities import SQLDatabase
from sqlalchemy import create_engine, text
# 设置OpenAI API密钥
os.environ['OPENAI_API_KEY'] = 'your_openai_api_key'
# 创建SQLAlchemy引擎连接到MySQL数据库
# 请根据您的MySQL数据库信息填写连接字符串
engine = create_engine('mysql+mysqlconnector://username:password@host:port/database')
# 创建一个示例表和一些数据(可选,如果数据库已经有表结构则跳过此部分)
with engine.connect() as conn:
conn.execute(text('''
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
age INT
)
'''))
conn.execute(text('''
INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 24), ('Charlie', 29)
'''))
conn.execute(text('''
CREATE TABLE IF NOT EXISTS orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
amount DECIMAL(10, 2),
FOREIGN KEY(user_id) REFERENCES users(id)
)
'''))
conn.execute(text('''
INSERT INTO orders (user_id, amount) VALUES (1, 99.99), (2, 50.00), (3, 75.50)
'''))
# 使用SQLDatabase连接到数据库
db = SQLDatabase(engine)
# 创建一个LangChain模型
llm = OpenAI(model_name='text-davinci-003')
# 创建SQL查询链
sql_chain = create_sql_query_chain(llm, db)
# 定义查询数据库的函数
def query_database(prompt):
result = sql_chain.run(prompt)
return result
# 示例:生成一个查询并执行
prompt = "查询所有年龄大于25岁的用户的姓名。"
result = query_database(prompt)
print(result)
3. 详细解释
1) 环境设置:
- 设置OpenAI API密钥,并连接到MySQL数据库。这里需要提供MySQL数据库的连接字符串。
2) 数据库连接:
- 使用SQLAlchemy的
create_engine
方法连接到MySQL数据库。连接字符串格式为:mysql+mysqlconnector://username:password@host:port/database
。
3) 创建表和插入数据(可选):
- 如果数据库已经存在表结构和数据,这一步可以跳过。否则,创建示例表和数据。
4) 连接数据库:
- 使用
SQLDatabase
类连接到MySQL数据库。SQLDatabase
类会自动提取数据库的模式信息。
5) 创建LangChain模型:
- 使用
OpenAI
类实例化一个大模型(例如GPT-4)。
6) 创建SQL查询链:
create_sql_query_chain
函数将大模型和SQLDatabase
实例结合在一起,生成SQL查询链。
7) 定义查询函数:
query_database(prompt)
函数接收自然语言查询,通过SQL查询链生成SQL查询并执行,返回结果。
8) 执行查询:
- 通过自然语言提示,例如“查询所有年龄大于25岁的用户的姓名”,使用
query_database
函数生成并执行SQL查询,并返回结果。
4. 注意事项
- MySQL连接器:确保已安装MySQL连接器库,例如
mysql-connector-python
或pymysql
。在连接字符串中使用相应的连接器,如mysql+mysqlconnector://
或mysql+pymysql://
。 - 数据库信息:根据实际的MySQL数据库信息填写连接字符串中的用户名、密码、主机、端口和数据库名称。
- 权限:确保提供的MySQL用户具有创建表和插入数据的权限,特别是在示例代码中创建表和插入数据的部分。
通过这些修改,你就可以使用MySQL数据库进行相同的操作,自动提取数据库结构并生成对应的SQL查询。
总结
以上的例子,大家可以一起练习一下,当然今天的例子应该是业务使用中的一环,并不是所有的问答都需要查询数据库。那么如何自定义一个agent 然后把sql的这部分包装进去呢?请看 如何使用LangChain自定义agent的制作(1) - 自定义一个可以执行 SQL 查询的 Agent