引言
在处理SQL问答任务时,面对大型数据库,我们经常会遇到难题。例如,当数据表过多或列的基数过高时,我们无法在每个提示中导入数据库的完整信息。在这篇文章中,我们将探讨如何动态地选择并在提示中仅插入最相关的信息,从而生成有效的SQL查询。
主要内容
识别相关的表子集
第一步是识别与用户问题相关的表。通常我们无法在一个提示中包含所有表的架构,因此我们需要提取与用户输入相关的表名,并仅包含这些表的架构。
使用工具调用
通过工具调用,我们可以从数据库中提取相关表名,并将其绑定到模型中。这可以通过以下方式实现:
from langchain_community.utilities import SQLDatabase
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers.openai_tools import PydanticToolsParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
class Table(BaseModel):
"""Table in SQL database."""
name: str = Field(description="Name of table in SQL database.")
db = SQLDatabase.from_uri("sqlite:///Chinook.db")
table_names = "\n".join(db.get_usable_table_names())
system = f"""Return the names of ALL the SQL tables that MIGHT be relevant to the user question.
The tables are:
{table_names}
Remember to include ALL POTENTIALLY RELEVANT tables, even if you're not sure that they're needed."""
prompt = ChatPromptTemplate.from_messages(
[
("system", system),
("human", "{input}"),
]
)
llm_with_tools = ChatOpenAI(model="gpt-4").bind_tools([Table])
output_parser = PydanticToolsParser(tools=[Table])
table_chain = prompt | llm_with_tools | output_parser
识别相关的列值
当处理高基数列时,如包含地址、歌曲名称或艺术家名称的列,为了正确过滤数据,我们需要确保拼写准确。可以通过创建向量存储来管理这些列:
import ast
import re
def query_as_list(db, query):
res = db.run(query)
res = [el for sub in ast.literal_eval(res) for el in sub if el]
res = [re.sub(r"\b\d+\b", "", string).strip() for string in res]
return res
proper_nouns = query_as_list(db, "SELECT Name FROM Artist")
然后,我们将这些唯一值嵌入并存储在一个向量数据库中,以便在查询时使用:
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
vector_db = FAISS.from_texts(proper_nouns, OpenAIEmbeddings())
retriever = vector_db.as_retriever(search_kwargs={"k": 15})
代码示例
下面是一个示例,展示如何结合上述步骤动态生成适合的SQL查询:
from langchain.chains import create_sql_query_chain
query_chain = create_sql_query_chain(llm_with_tools, db)
query = query_chain.invoke(
{"question": "What are all the genres of Alanis Morissette songs"}
)
print(query)
常见问题和解决方案
-
问题:当表的数量过多时,如何确保仅选择相关表?
- 解决方案:通过先根据用户的输入筛选出可能相关的表,再只传递这些表的架构信息。
-
问题:如何处理拼写错误的情况?
- 解决方案:利用向量数据库进行拼写校正,将最相关的值注入提示中。
总结和进一步学习资源
通过动态选择相关的信息,我们可以在处理大型数据库的SQL问答任务中实现更高效的查询。如果你想进一步了解相关技术,推荐阅读LangChain社区的SQL: Agents指南。
参考资料
结束语:如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---