构建一个SQL数据问答系统:从初学到进阶
引言
随着人工智能的发展,能够查询和解读结构化数据的问答系统变得越来越重要。与处理非结构化文本数据不同,处理结构化数据通常需要生成并执行DSL(如SQL)查询来获取结果。在这篇文章中,我们将探讨如何创建一个基于数据库的问答系统,涵盖其基本实现和高级用法,包括使用链和代理。我们会使用一个SQLite数据库示例,并展示如何将其与一个强大的大语言模型(LLM)结合使用来回答数据库中的问题。
主要内容
1. 系统架构
问答系统的高层次步骤如下:
- 将用户问题转换为SQL查询:模型将用户输入转换为SQL查询。
- 执行SQL查询:执行生成的SQL查询。
- 回答问题:使用查询结果生成自然语言回答。
2. 设置环境
首先,我们需要安装必要的包并设置环境变量:
%pip install --upgrade --quiet langchain langchain-community langchain-openai faiss-cpu
import getpass
import os
if not os.environ.get("OPENAI_API_KEY"):
os.environ["OPENAI_API_KEY"] = getpass.getpass()
if not os.environ.get("LANGCHAIN_API_KEY"):
os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
os.environ["LANGCHAIN_TRACING_V2"] = "true"
我们将使用OpenAI模型和FAISS向量存储。
3. 连接数据库
接下来,我们将使用SQLite连接来创建一个示例数据库,并使用SQLAlchemy进行接口连接:
from langchain_community.utilities import SQLDatabase
db = SQLDatabase.from_uri("sqlite:///Chinook.db")
print(db.dialect)
print(db.get_usable_table_names())
db.run("SELECT * FROM Artist LIMIT 10;")
4. 创建SQL查询链
我们可以创建一个简单的链,将问题转换为SQL查询,执行查询,并生成答案:
from langchain_openai import ChatOpenAI
from langchain.chains import create_sql_query_chain
llm = ChatOpenAI(model="gpt-4o-mini")
chain = create_sql_query_chain(llm, db)
response = chain.invoke({"question": "How many employees are there"})
print(response)
5. 执行SQL查询并生成答案
为了自动生成和执行查询,我们需要一个工具来执行SQL查询,并将结果与原始问题结合生成最终答案:
from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool
from operator import itemgetter
execute_query = QuerySQLDataBaseTool(db=db)
write_query = create_sql_query_chain(llm, db)
chain = write_query | execute_query
response = chain.invoke({"question": "How many employees are there"})
print(response)
6. 使用代理
代理提供了更灵活的查询方式,能够依赖数据库架构和内容来回答问题,并处理多次查询和错误恢复等复杂任务:
from langchain_community.agent_toolkits import SQLDatabaseToolkit
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
tools = toolkit.get_tools()
from langchain_core.messages import SystemMessage
from langgraph.prebuilt import create_react_agent
from langchain_core.messages import HumanMessage
system_message = SystemMessage(content="Your SQL system prompt here")
agent_executor = create_react_agent(llm, tools, messages_modifier=system_message)
for s in agent_executor.stream({"messages": [HumanMessage(content="Which country's customers spent the most?")]}):
print(s)
print("----")
代码示例
完整的代码示例如下:
import getpass
import os
%pip install --upgrade --quiet langchain langchain-community langchain-openai faiss-cpu
if not os.environ.get("OPENAI_API_KEY"):
os.environ["OPENAI_API_KEY"] = getpass.getpass()
from langchain_community.utilities import SQLDatabase
db = SQLDatabase.from_uri("sqlite:///Chinook.db")
print(db.dialect)
print(db.get_usable_table_names())
db.run("SELECT * FROM Artist LIMIT 10;")
from langchain_openai import ChatOpenAI
from langchain.chains import create_sql_query_chain
llm = ChatOpenAI(model="gpt-4o-mini")
chain = create_sql_query_chain(llm, db)
response = chain.invoke({"question": "How many employees are there"})
print(response)
常见问题和解决方案
- 安全性问题:确保数据库连接权限尽可能小。
- 查询错误:使用代理的错误恢复机制处理常见查询错误。
- 高基数列:使用向量存储来处理高基数列中的专有名词。
总结和进一步学习资源
这篇文章介绍了如何创建一个基于SQL数据库的问答系统,包括从基本实现到高级使用的步骤。希望这能帮助你更好地理解和实现类似的系统。
参考资料
- LangChain: langchain.com/
- SQLAlchemy: www.sqlalchemy.org/
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---