构建一个SQL数据问答系统:从初学到进阶

52 阅读3分钟

构建一个SQL数据问答系统:从初学到进阶

引言

随着人工智能的发展,能够查询和解读结构化数据的问答系统变得越来越重要。与处理非结构化文本数据不同,处理结构化数据通常需要生成并执行DSL(如SQL)查询来获取结果。在这篇文章中,我们将探讨如何创建一个基于数据库的问答系统,涵盖其基本实现和高级用法,包括使用链和代理。我们会使用一个SQLite数据库示例,并展示如何将其与一个强大的大语言模型(LLM)结合使用来回答数据库中的问题。

主要内容

1. 系统架构

问答系统的高层次步骤如下:

  1. 将用户问题转换为SQL查询:模型将用户输入转换为SQL查询。
  2. 执行SQL查询:执行生成的SQL查询。
  3. 回答问题:使用查询结果生成自然语言回答。

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数据库的问答系统,包括从基本实现到高级使用的步骤。希望这能帮助你更好地理解和实现类似的系统。

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---