[构建一个基于SQL数据的问答系统:从SQL查询到自然语言回答]

83 阅读3分钟

构建一个基于SQL数据的问答系统:从SQL查询到自然语言回答

引言

在现代应用程序中,能够有效地从结构化数据中提取信息是非常有价值的。本文将介绍如何使用大语言模型(LLM)构建一个问答系统,能够对SQL数据库中的数据进行查询,并返回自然语言的回答。我们将探讨如何使用链和代理两种方法进行实现,并提供安全性建议以确保系统的可靠性。

主要内容

1. 架构概览

系统的基本步骤包括:

  • 将问题转换为SQL查询。
  • 执行SQL查询。
  • 利用查询结果回答用户问题。

2. 环境准备

首先,我们需要安装必要的依赖包并设置环境变量:

%%capture --no-stderr
%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()

# 使用LangSmith进行跟踪
if not os.environ.get("LANGCHAIN_API_KEY"):
    os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
    os.environ["LANGCHAIN_TRACING_V2"] = "true"

3. 数据库连接

我们将使用SQLite连接到Chinook数据库:

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查询。
  • 执行查询。
  • 根据结果回答问题。
4.1 问题到SQL

使用OpenAI的模型将用户问题转换为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"})
4.2 执行查询

通过QuerySQLDatabaseTool执行生成的查询:

from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool

execute_query = QuerySQLDataBaseTool(db=db)
write_query = create_sql_query_chain(llm, db)
chain = write_query | execute_query
chain.invoke({"question": "How many employees are there"})

5. 使用代理进行问答

代理提供了与SQL数据库交互的更灵活的方式,能够处理复杂的问题,如表描述和多查询。

5.1 初始化代理

使用SQLDatabaseToolkit创建工具,并初始化代理:

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

system_message = SystemMessage(content="You are an agent ...")  # 系统提示信息
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("----")

常见问题和解决方案

  • 安全性:执行SQL查询时,确保数据库权限最小化,并考虑在执行前加入人工审核步骤。
  • 高基数列处理:使用向量检索工具确保正确拼写。

总结和进一步学习资源

本文介绍了构建一个基于SQL数据的问答系统的流程,以及如何处理常见的开发挑战。对于更复杂的需求,可以查看以下资源:

参考资料

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

---END---