使用SQL数据构建高效的问答系统

88 阅读3分钟

使用SQL数据构建高效的问答系统

引言

在构建基于结构化数据的问答系统时,我们面临的挑战与处理非结构化文本数据时有所不同。对于后者,我们通常会将文本生成用于搜索矢量数据库,而对于前者,通常是通过大型语言模型(LLM)生成和执行DSL(如SQL)的查询。在这篇文章中,我们将探讨如何使用链和代理来创建一个基于数据库的问答系统。我们将重点讨论如何利用这些系统对数据库中的数据提问并获得自然语言答案。主要的区别在于代理可以根据需要多次查询数据库以回答问题。

主要内容

架构

高层次上,这些系统的步骤如下:

  1. 将问题转换为DSL查询:模型将用户输入转换为SQL查询。
  2. 执行SQL查询:执行查询。
  3. 回答问题:模型使用查询结果回应用户输入。

环境设置

首先,确保安装所需的软件包并设置环境变量:

%pip install --upgrade --quiet langchain langchain-community langchain-openai faiss-cpu

确保你有以下API密钥:OPENAI_API_KEY。另外,为了提高访问稳定性,你可能需要考虑使用API代理服务。

创建一个简单的SQL查询链

使用langchain库,你可以创建一个简单的链:

from langchain_community.utilities import SQLDatabase
from langchain.chains import create_sql_query_chain
from langchain_openai import ChatOpenAI

# 设置数据库连接
db = SQLDatabase.from_uri("sqlite:///Chinook.db")

# 创建链
llm = ChatOpenAI(model="gpt-4o-mini")
chain = create_sql_query_chain(llm, db)

# 执行示例查询
response = chain.invoke({"question": "How many employees are there"})
print(db.run(response))  # [(8,)]

使用代理实现复杂的SQL查询

LangChain提供了一个SQL Agent,它允许更灵活地与SQL数据库交互。以下是如何初始化Agent:

from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain_core.messages import SystemMessage
from langgraph.prebuilt import create_react_agent

# 初始化工具包
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
tools = toolkit.get_tools()

# 设置系统消息
SQL_PREFIX = """You are an agent designed to interact with a SQL database...
"""
system_message = SystemMessage(content=SQL_PREFIX)

# 创建代理
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)

代码示例

这里是一个完整的代码示例,用于构建和执行SQL查询链:

from langchain_community.utilities import SQLDatabase
from langchain.chains import create_sql_query_chain
from langchain_openai import ChatOpenAI

# 初始化SQL数据库和LLM
db = SQLDatabase.from_uri("sqlite:///Chinook.db")
llm = ChatOpenAI(model="gpt-4o-mini")

# 创建SQL查询链
chain = create_sql_query_chain(llm, db)

# 提问并执行查询
response = chain.invoke({"question": "How many employees are there"})
print(db.run(response))  # 输出:[('8',)]

常见问题和解决方案

  1. 安全性问题:执行模型生成的SQL查询时,需要小心权限控制。建议仅授予最低必要权限,并考虑添加人工审批步骤。

  2. 复杂查询需求:对于需要多次查询才能回答的问题,可以使用代理来处理。这允许模型在需要时多次查询数据库。

  3. 网络限制:由于某些地区的网络限制,访问API可能会不稳定。建议使用API代理服务来提高访问的可靠性。

总结和进一步学习资源

通过本文,我们讨论了如何构建一个基于SQL数据库的问答系统,并探索了链和代理在不同场景下的适用性。为了更深入地理解这些技术,以下是一些推荐的学习资源:

参考资料

  1. LangChain 官方文档 LangChain Documentation
  2. 数据库安全最佳实践 Database Security Best Practices

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