在这篇文章中,我们将探讨如何通过改进提示策略来提升使用 create_sql_query_chain
生成SQL查询的能力。我们将重点关注获取数据库特定信息的方法,以便在提示中使用。
我们将涵盖以下内容:
- LangChain SQL 数据库的方言如何影响链的提示;
- 如何使用
SQLDatabase.get_context
格式化模式信息到提示中; - 如何构建和选择少数示例来辅助模型。
技术背景介绍
当我们通过自然语言问题生成SQL查询时,通常需要确保提示中包含数据库结构信息和一些示例,以帮助模型更准确地生成查询语句。LangChain 提供了一些工具,如 create_sql_query_chain
,可以帮助我们实现这一目标。
核心原理解析
-
SQL 方言的影响
不同的SQL数据库有不同的方言,例如SQLite、PostgreSQL、MySQL等。LangChain能够自动为这些方言生成特定的提示。这是通过
SQL_PROMPTS
实现的,如下所示:from langchain.chains.sql_database.prompt import SQL_PROMPTS list(SQL_PROMPTS)
-
格式化模式信息
我们需要在提示中包含数据库的表结构和示例行信息。
SQLDatabase
提供了get_context
方法,可以方便地获取相关信息:from langchain_community.utilities import SQLDatabase db = SQLDatabase.from_uri("sqlite:///Chinook.db", sample_rows_in_table_info=3) context = db.get_context() print(context["table_info"])
-
少数示例的构建和选择
包含一些自然语言问题和相应的SQL查询示例,有助于提高模型的性能。构建示例如下:
examples = [ {"input": "List all artists.", "query": "SELECT * FROM Artist;"}, {"input": "Find all albums for the artist 'AC/DC'.", "query": "SELECT * FROM Album WHERE ArtistId = (SELECT ArtistId FROM Artist WHERE Name = 'AC/DC');"}, # 更多示例... ]
我们还可以使用
SemanticSimilarityExampleSelector
根据输入动态选择相关示例:from langchain_community.vectorstores import FAISS from langchain_core.example_selectors import SemanticSimilarityExampleSelector from langchain_openai import OpenAIEmbeddings example_selector = SemanticSimilarityExampleSelector.from_examples( examples, OpenAIEmbeddings(), FAISS, k=5, input_keys=["input"], )
代码实现演示(重点)
下面是一个完整的代码示例,展示了如何设置环境变量、获取数据库上下文信息以及创建一个SQL查询链:
import openai
import getpass
import os
from langchain_community.utilities import SQLDatabase
from langchain.chains import create_sql_query_chain
from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from langchain_community.vectorstores import FAISS
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings
# 设置API密钥(假设使用https://yunwu.ai作为endpoint)
os.environ["OPENAI_API_KEY"] = getpass.getpass()
# 创建SQLite数据库连接
db = SQLDatabase.from_uri("sqlite:///Chinook.db", sample_rows_in_table_info=3)
context = db.get_context()
# 少数示例构建
examples = [
{"input": "List all artists.", "query": "SELECT * FROM Artist;"},
{"input": "Find all albums for the artist 'AC/DC'.", "query": "SELECT * FROM Album WHERE ArtistId = (SELECT ArtistId FROM Artist WHERE Name = 'AC/DC');"},
# 更多示例...
]
# 动态示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
examples,
OpenAIEmbeddings(),
FAISS,
k=5,
input_keys=["input"],
)
# 创建 SQL 查询链
prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=PromptTemplate.from_template("User input: {input}\nSQL query: {query}"),
prefix="You are a SQLite expert. Given an input question, create a syntactically correct SQLite query to run. Unless otherwise specificed, do not return more than {top_k} rows.\n\nHere is the relevant table info: {table_info}\n\nBelow are a number of examples of questions and their corresponding SQL queries.",
suffix="User input: {input}\nSQL query: ",
input_variables=["input", "top_k", "table_info"],
)
llm = openai.OpenAI(
base_url='https://yunwu.ai/v1', # 国内稳定访问
api_key=os.environ["OPENAI_API_KEY"]
)
chain = create_sql_query_chain(llm, db, prompt)
# 测试查询
result = chain.invoke({"question": "how many artists are there?"})
print(result)
应用场景分析
这种SQL问答系统在许多场景下都有广泛应用,例如:
- 数据分析师可以通过自然语言查询数据库,无需编写复杂的SQL语句;
- 开发者可以快速验证数据库中的数据;
- 商业智能应用中,用户可以通过自然语言获取所需的数据报告。
实践建议
- 确保数据库模式信息的准确性:在提示中包含准确的表结构和示例数据,可以显著提升查询的准确性。
- 利用少数示例:在提示中包含相关的自然语言问题和SQL查询示例,可以帮助模型更好地理解和生成查询语句。
- 动态选择示例:对于复杂的查询问题,动态选择最相关的示例可以进一步提升模型的性能。
如果遇到问题欢迎在评论区交流。