**How to Better Prompt When Doing SQL Question-Answering**

在这篇文章中,我们将探讨如何通过改进提示策略来提升使用 create_sql_query_chain 生成SQL查询的能力。我们将重点关注获取数据库特定信息的方法,以便在提示中使用。

我们将涵盖以下内容:

  • LangChain SQL 数据库的方言如何影响链的提示;
  • 如何使用 SQLDatabase.get_context 格式化模式信息到提示中;
  • 如何构建和选择少数示例来辅助模型。

技术背景介绍

当我们通过自然语言问题生成SQL查询时,通常需要确保提示中包含数据库结构信息和一些示例,以帮助模型更准确地生成查询语句。LangChain 提供了一些工具,如 create_sql_query_chain,可以帮助我们实现这一目标。

核心原理解析

  1. SQL 方言的影响

    不同的SQL数据库有不同的方言,例如SQLite、PostgreSQL、MySQL等。LangChain能够自动为这些方言生成特定的提示。这是通过 SQL_PROMPTS 实现的,如下所示:

    from langchain.chains.sql_database.prompt import SQL_PROMPTS
    
    list(SQL_PROMPTS)
    
  2. 格式化模式信息

    我们需要在提示中包含数据库的表结构和示例行信息。SQLDatabase 提供了 get_context 方法,可以方便地获取相关信息:

    from langchain_community.utilities import SQLDatabase
    
    db = SQLDatabase.from_uri("sqlite:///Chinook.db", sample_rows_in_table_info=3)
    context = db.get_context()
    print(context["table_info"])
    
  3. 少数示例的构建和选择

    包含一些自然语言问题和相应的SQL查询示例,有助于提高模型的性能。构建示例如下:

    examples = [
        {"input": "List all artists.", "query": "SELECT * FROM Artist;"},
        {"input": "Find all albums for the artist 'AC/DC'.", "query": "SELECT * FROM Album WHERE ArtistId = (SELECT ArtistId FROM Artist WHERE Name = 'AC/DC');"},
        # 更多示例...
    ]
    

    我们还可以使用 SemanticSimilarityExampleSelector 根据输入动态选择相关示例:

    from langchain_community.vectorstores import FAISS
    from langchain_core.example_selectors import SemanticSimilarityExampleSelector
    from langchain_openai import OpenAIEmbeddings
    
    example_selector = SemanticSimilarityExampleSelector.from_examples(
        examples,
        OpenAIEmbeddings(),
        FAISS,
        k=5,
        input_keys=["input"],
    )
    

代码实现演示(重点)

下面是一个完整的代码示例,展示了如何设置环境变量、获取数据库上下文信息以及创建一个SQL查询链:

import openai
import getpass
import os
from langchain_community.utilities import SQLDatabase
from langchain.chains import create_sql_query_chain
from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from langchain_community.vectorstores import FAISS
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings

# 设置API密钥(假设使用https://yunwu.ai作为endpoint)
os.environ["OPENAI_API_KEY"] = getpass.getpass()

# 创建SQLite数据库连接
db = SQLDatabase.from_uri("sqlite:///Chinook.db", sample_rows_in_table_info=3)
context = db.get_context()

# 少数示例构建
examples = [
    {"input": "List all artists.", "query": "SELECT * FROM Artist;"},
    {"input": "Find all albums for the artist 'AC/DC'.", "query": "SELECT * FROM Album WHERE ArtistId = (SELECT ArtistId FROM Artist WHERE Name = 'AC/DC');"},
    # 更多示例...
]

# 动态示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples,
    OpenAIEmbeddings(),
    FAISS,
    k=5,
    input_keys=["input"],
)

# 创建 SQL 查询链
prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=PromptTemplate.from_template("User input: {input}\nSQL query: {query}"),
    prefix="You are a SQLite expert. Given an input question, create a syntactically correct SQLite query to run. Unless otherwise specificed, do not return more than {top_k} rows.\n\nHere is the relevant table info: {table_info}\n\nBelow are a number of examples of questions and their corresponding SQL queries.",
    suffix="User input: {input}\nSQL query: ",
    input_variables=["input", "top_k", "table_info"],
)

llm = openai.OpenAI(
    base_url='https://yunwu.ai/v1',  # 国内稳定访问
    api_key=os.environ["OPENAI_API_KEY"]
)

chain = create_sql_query_chain(llm, db, prompt)

# 测试查询
result = chain.invoke({"question": "how many artists are there?"})
print(result)

应用场景分析

这种SQL问答系统在许多场景下都有广泛应用,例如:

  • 数据分析师可以通过自然语言查询数据库,无需编写复杂的SQL语句;
  • 开发者可以快速验证数据库中的数据;
  • 商业智能应用中,用户可以通过自然语言获取所需的数据报告。

实践建议

  1. 确保数据库模式信息的准确性:在提示中包含准确的表结构和示例数据,可以显著提升查询的准确性。
  2. 利用少数示例:在提示中包含相关的自然语言问题和SQL查询示例,可以帮助模型更好地理解和生成查询语句。
  3. 动态选择示例:对于复杂的查询问题,动态选择最相关的示例可以进一步提升模型的性能。

如果遇到问题欢迎在评论区交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值