引言
在处理大规模数据库时,SQL问答成为生成有效查询的重要方式。然而,当数据库中包含大量的表、列以及高基数的列时,将所有相关信息在每次提示中倾倒是不可行的。因此,我们需要找到方法,动态地将最相关的信息插入到提示中。在这篇文章中,我们将展示如何识别这些相关信息,并将其用于生成查询。
主要内容
识别相关表的子集
在处理包含众多表的数据库时,关键是找出与用户查询密切相关的表。要实现这一点,可以使用工具调用(tool-calling)功能,通过模型根据用户的输入选择相关表。
# 通过工具调用识别相关的SQL表
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):
name: str = Field(description="Name of table in SQL database.")
# 获取可用表名
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 = llm.bind_tools([Table])
output_parser = PydanticToolsParser(tools=[Table])
# 创建表链
table_chain = prompt | llm_with_tools | output_parser
# 调用链
table_chain.invoke({"input": "What are all the genres of Alanis Morisette songs"})
识别相关列值的子集
对于高基数列,如艺术家姓名和专辑名称,可以使用向量存储方式来存储所有不同的专有名词并检索最相关的值。
# 创建向量数据库
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问答:
# 设置SQL查询链
from operator import itemgetter
from langchain.chains import create_sql_query_chain
from langchain_core.runnables import RunnablePassthrough
query_chain = create_sql_query_chain(llm, db)
table_chain = {"input": itemgetter("question")} | table_chain # 转换key
full_chain = RunnablePassthrough.assign(table_names_to_use=table_chain) | query_chain
# 执行查询
query = full_chain.invoke(
{"question": "What are all the genres of Alanis Morisette songs"}
)
print(query)
# 执行SQL查询
db.run(query)
常见问题和解决方案
挑战1:高基数列处理
- 解决方案:使用向量数据库存储所有不同的专有名词,并在查询用户输入时检索相关值。
挑战2:表关联复杂
- 解决方案:通过为表创建类别,将表分组简化模型的任务。
总结和进一步学习资源
在处理大规模数据库的SQL问答任务中,巧妙地动态提取相关信息是解决问题的关键。本篇文章中介绍的方法,如工具调用和向量数据库策略,为复杂查询生成提供了有效的手段。
参考资料
- Langchain Community Documentation
- SQLAlchemy Official Website
- Chinook Database Schema
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---