如何通过 Prompt 优化大模子 Text2SQL 的效果

打印 上一主题 下一主题

主题 690|帖子 690|积分 2074

媒介
在上篇文章中「大模子LLM在Text2SQL上的应用实践」先容了基于SQLDatabaseChain的Text2SQL实践,但对于逻辑复杂的查询在稳定性、可靠性、安全性方面可能无法到达预期,比如输出幻觉、数据安全、用户输入错误等问题。
本文将从以下4个方面探讨通过Prompt Engineering来优化LLM的Text2SQL转换效果。
1. 问题及思路
2. Prompt概述
3. Text2SQL中的Prompt实践
4. 后续计划
1. 问题及思路
1.1 问题挑战

在天然语言处理处罚(NLP)和人工智能(AI)领域,大型语言模子(LLM)如GPT-3和BERT已经取得显著的进步。然而,在将文本转换为SQL查询(Text to SQL)的任务上,这些模子仍有优化的空间。一些常见的挑战包罗:
1. 输出幻觉(Hallucination):LLM在生成SQL语句时会生成一些看似合理,但实际与输入文本无关或错误的查询,这可能是由于模子尚未充分学习到SQL查询的语法和逻辑,导致在推理阶段产生误导性的输出。
2. 数据安全性:在处理处罚敏感数据时,模子可能会生成泄露或窜改敏感信息的SQL语句。
3. 用户输入错误:用户在输入查询时拼写错误或有不合规的操作,这可能导致模子生成错误或高风险的SQL语句。
1.2 办理思路

针对上述问题,我们可以从Prompt Engineering(提示工程)和Fine Tuning(模子微调)两个方面进行思量。
1. Prompt Engineering是一种通过设计特定的提示词或句子,引导模子生成更符合用户意图的输出的方法。例如,我们可以为模子添加一些关于SQL语法的提示信息,以帮助模子更好地明确SQL语句的结构和规则。通过这种方式,我们可以有效地低落输出幻觉的可能性,提高模子的准确性和稳定性。
2. Fine Tuning则是指在预训练模子的基础上,使用特定的数据集进行微调,以适应特定的任务需求。对于Text-to-SQL任务,我们可以使用包含大量SQL语句的数据集进行Fine Tuning,以提高模子对SQL语句的明确和生成能力。
1.3 思路对比

两者对比如下:

Fine Tuning
Prompt Engineering
方法
在与目标任务或领域相关的数据集上重新训练模子
输入提示的设计和调整,选择符合的关键词、短语或问题来引导模子生成所需的回答
复杂度
较高,涉及模子的重新训练和参数调整,需要对模子的内部结构和机制有肯定的了解
较低,涉及到对输入提示的设计和调整,对模子本身的结构和机制要求较低
成本与时长
高,重新训练模子需要大量的计算资源和时间
低,可以通过迭代的方式逐步优化
性能
较高,模子深度明确特定任务或领域知识
稍低,偏重于引导模子生成与提示相关的回答
以我们都履历过的到场考试的例子做个平凡的对比:
1. Fine Tuning:考试前根据自己的知识体系,参考考试的题型、汗青真题,做好有偏重点的准备;考试过程中根据给定的题目,按照自己的明确直接给出答案
2. Prompt Engineering:考试前不做额外的准备,带着自己的知识体系去到场考试;考试过程中除了给定的题目外,还会有雷同题目的解答思路,按照解答提示来给出答案
2. Prompt概述
2.1 Prompt概念

Prompt是一种通过设计特定的提示词或句子,引导模子生成更符合用户意图的输出的方法。例如,我们可以为模子添加一些关于SQL语法的提示信息,以帮助模子更好地明确SQL语句的结构和规则。

Prompt的组成包四个元素:


  • Instruction(指令,必须):告诉模子该怎么做,如何使用外部信息,如那边理处罚查询并构建Out。
  • Context(上下文信息,可选):充当模子的附加知识泉源。这些可以手动插入到提示中,通过矢量数据库(Vector Database)检索(检索加强)获得,或通过其他方式(API、计算等)引入。
  • Input Data(需要处理处罚的数据,可选):通常(但不总是)是由人类用户(即提示者)In 到体系中的查询。
  • Output Indicator(要输出的类型或格式,可选):标记要生成的文本的开头。

代码示例:
  1. prompt = """ Answer the question based on the context below. If the question cannot be answered using the information provided answer with "I don't know".
  2. Context: Large Language Models (LLMs) are the latest models used in NLP. Their superior performance over smaller models has made them incredibly useful for developers building NLP enabled applications. These models can be accessed via Hugging Face's `transformers` library, via OpenAI using the `openai` library, and via Cohere using the `cohere` library.
  3. Question: Which libraries and model providers offer LLMs?
  4. Answer: """
复制代码
2.2 Prompt编写原则

1. 关键要素


  • 明确目标:清晰界说任务,以便模子明确。
  • 详细引导:给予模子明确的引导和束缚。
  • 简介明了:使用简练、清晰的语言表达Prompt。
  • 得当引导:通过示例或问题边界引导模子。
  • 迭代优化:根据输出结果,连续调整和优化Prompt。
2. 有效做法


  • 夸大,可以得当的重复命令和操作。
  • 给模子一个出路,假如模子可能无法完成,告诉它说“不知道”,别让它乱“遐想”。
  • 尽量详细,它还是孩子,少留解读空间。
2.3 Prompt类型

2.3.1 Zero-Shot Prompting
直接向模子提出问题,不需要任何案例,模子就能回答你的问题,基于模子训练的时候提供的大量数据,能做初步的判断。
1. Zero-Shot Prompting 技能依赖于预训练的语言模子。
2. 为了获得最佳性能,它需要大量的样本数据进行微调。像ChatGPT 就是一个例子,它的样本数量是过千亿。
3. 由于Zero-Shot Prompting 技能的机动性和通用性,它的输出有时可能不够准确,或不符合预期。这可能需要对模子进行进一步的微调或添加更多的提示文原来纠正。
2.3.2 Few-Shot Prompting
向模子提出问题,同时给出少量案例,模子根据给定的案例调整输出的回答。
缺点:依赖于案例的质量,案例假如给的不恰当,模子也会学到不恰当的形貌和回答。
**2.3.3 Chain of Thought(CoT)**思维链
Jason Wei等人(2022)引入的思维链(CoT)提示,通过中间推理步骤实现复杂的推理能力。可以将其与少样本提示相结合,以获得更好的结果,以便在回答之前进行推理的更复杂的任务。

有两种方式增加GPT的推理能力,或者CoT能力:
1. 第一种:增加案例,如下所示,第一次回答错误,给一个计算过程的案例,GPT可以通过案例学会简单推理。

2. 第二种:增加关键句,Let’s think step by step,测试职员测了许多雷同的句子,最后发现这句话是效果最好的,这个时候不加案例,GPT也具备肯定的推理能力。

根据 Wei 等人的论文表明,它仅在大于即是 100B 参数的模子中使用才会有效。假如使用的是小样本模子,这个方法不会生效。
2.3.4 Self-Consistency 自洽
是对CoT的一个增补,让模子生成多个思维链,然后取最多数答案的作为最终结果。其实重复运算多次,取概率最高的那一个,需要借助脚本辅助完成这个功能。

1. 从语言模子中生成多个差别的“推理路径(reasoning paths)”,这些路径可能因模子的随机性或差别的参数设置(如temperature、top_p等)而有所差别。有助于模子更全面地思量问题,并可能导致更准确或更可靠的最终答案。
2. 对上一步生成的多个推理路径进行“边缘化(marginalize out)”以得到一个最终的、一致的答案。边缘化在这里意味着从多个可能的推理路径中找出最常见或最一致的答案。
2.3.5 Tree of Thoughts(ToT) 思维树
Tree of Thoughts(ToT)框架,用于改进语言模子(LMs)的推理能力。该框架是对盛行的“Chain of Thought”方法的一种泛化,允许模子在办理问题的过程中进行更多的探索和策略性前瞻。
ToT允许模子自我评估差别的选择,以决定下一步的行动,并在必要时进行前瞻或回溯,以做出全局性的选择。

   在24点游戏中,使用链式思索提示的GPT-4仅办理了4%的任务,而使用ToT方法的乐成率到达了74%。
  2.3.6 ReAct框架
Yao等人(2022)引入了一个框架,其中LLMs以交错的方式生成推理轨迹和任务特定操作,并且允许LLMs与外部工具交互来获取额外信息,从而给出更可靠和实际的回应。ReAct的灵感来自于“举动”和“推理”之间的协同作用,正是这种协同作用使得人类可以或许学习新任务并做出决策或推理。
下图展示ReAct的一个示例,举例执行问题回答所涉及的差别步骤。

实现流程如下:
(1)用Prompt实现一个样例,比如上面的模板:Thought:xxx ==> Action: Search[xxx];
(2)LLMs会根据模板相同的逻辑,结合CoT思维链方式一步一步思索,并获取外部知识;
(3)最后Action: Finish获取最终结果后结束。
ReAct框架在后续先容Text2SQL的Agent实现的文章中还会详细先容,步骤如下:

3. Text2SQL中的Prompt实践
3.1 现有问题
以上篇文中「大模子LLM在Text2SQL上的应用实践」的数据库Chinook为例,需求为统计“连续两个月都下订单的客户有哪些?”,示例代码可参考上文。
结果如下:

可以看出生成的SQL不准确,只统计了近来两个月中都下订单的客户,和统计需求不相符。那如何办理这个问题?
3.2 办理方案
1. 加强LLM模子能力
我们先从LLM模子的角度思量。测试案例中用到的是“GPT-3.5-Turbo”,参考Spider排行榜(https://yale-lily.github.io/spider)可以看出GPT-4的效果还是一骑绝尘。

我们将LLM模子切换为GPT-4测试下效果,结果如下:

效果:生成的SQL基本上满意我们的需求。
成本:GPT-4的费用通常为GPT-3.5的10倍左右。所以该方案不是我们的首选方案。但其生成的SQL可以作为后续的参考和输入。
2. Prompt Engineering
接纳Prompt的方式来实现。其中自界说Prompt信息包罗:Database中Table Schema信息,Table Row数据样本和Few-shot Examples
PromptTemplate示例代码如下:
  1. from langchain.prompts import PromptTemplate
  2. TEMPLATE = """Given an input question, first create a syntactically correct {dialect} query to run, then look at the results of the query and return the answer.
  3. Use the following format:
  4. Question: "Question here"
  5. SQLQuery: "SQL Query to run"
  6. SQLResult: "Result of the SQLQuery"
  7. Answer: "Final answer here"
  8. Only use the following tables:
  9. {table_info}.
  10. Some examples of SQL queries that correspond to questions are:
  11. {few_shot_examples}
  12. Question: {input}"""
复制代码
其中{table_info}包罗Table Schema信息和Table Row数据样本,可通过LangChain中的SQLDatabase来获得,其封装在db.table_info中,示例内容如下:
  1. CREATE TABLE "Track" (
  2. "TrackId" INTEGER NOT NULL,
  3. "Name" NVARCHAR(200) NOT NULL,
  4. "AlbumId" INTEGER,
  5. "MediaTypeId" INTEGER NOT NULL,
  6. "GenreId" INTEGER,
  7. "Composer" NVARCHAR(220),
  8. "Milliseconds" INTEGER NOT NULL,
  9. "Bytes" INTEGER,
  10. "UnitPrice" NUMERIC(10, 2) NOT NULL,
  11. PRIMARY KEY ("TrackId"),
  12. FOREIGN KEY("MediaTypeId") REFERENCES "MediaType" ("MediaTypeId"),
  13. FOREIGN KEY("GenreId") REFERENCES "Genre" ("GenreId"),
  14. FOREIGN KEY("AlbumId") REFERENCES "Album" ("AlbumId")
  15. )
  16. SELECT * FROM 'Track' LIMIT 3;
  17. TrackId  Name  AlbumId  MediaTypeId  GenreId  Composer  Milliseconds  Bytes  UnitPrice
  18. 1  For Those About To Rock (We Salute You)  1  1  1  Angus Young, Malcolm Young, Brian Johnson  343719  11170334  0.99
  19. 2  Balls to the Wall  2  2  1  None  342562  5510424  0.99
  20. 3  Fast As a Shark  3  2  1  F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman  230619  3990994  0.99
复制代码
团体的测试代码如下:
  1. from langchain.utilities import SQLDatabase
  2. from langchain.chat_models import ChatOpenAI
  3. from langchain.schema.output_parser import StrOutputParser
  4. from langchain import hub
  5. # Initialize database
  6. db = SQLDatabase.from_uri("sqlite:///xxx/Chinook.db")
  7. # Pull down prompt
  8. prompt = hub.pull("rlm/text-to-sql")
  9. # Initialize model
  10. model = ChatOpenAI()
  11. # few shot examples
  12. few_shots = {
  13.     "List all artists.": "SELECT * FROM artists;",
  14.     "Find all albums for the artist 'AC/DC'.": "SELECT * FROM albums WHERE ArtistId = (SELECT ArtistId FROM artists WHERE Name = 'AC/DC');",
  15.     "连续两个月都下订单的客户有哪些?":"SELECT DISTINCT a.'CustomerId', a.'FirstName', a.'LastName' FROM 'Customer' a JOIN 'Invoice' b ON a.'CustomerId' = b.'CustomerId' JOIN 'Invoice' c ON a.'CustomerId' = c.'CustomerId' AND ((strftime('%Y-%m', b.'InvoiceDate') = strftime('%Y-%m', date(c.'InvoiceDate', '-1 month'))) OR (strftime('%Y-%m', b.'InvoiceDate') = strftime('%Y-%m', date(c.'InvoiceDate', '+1 month'))))"
  16. }
  17. # Create chain with LangChain Expression Language
  18. inputs = {
  19.     "table_info": lambda x: db.get_table_info(),
  20.     "input": lambda x: x["question"],
  21.     "few_shot_examples": lambda x: few_shots,
  22.     "dialect": lambda x: db.dialect,
  23. }
  24. sql_response = (
  25.     inputs
  26.     | prompt
  27.     | model.bind(stop=["\nSQLResult:"])
  28.     | StrOutputParser()
  29. )
  30. # Call with a given question
  31. sql_response.invoke({"question": "连续两个月都下订单的客户有哪些?"})
复制代码
结果如下:

效果:生成的SQL满意我们的需求。
成本:增加的Prompt上下文信息所占tokens的费用,与GPT-4相比基本在10%左右。

**根据Prompt信息,**测试相似拓展问题,结果情况如下:
案例1:统计“连续两个月都下订单的客户统共有多少个?”

结果:生成的SQL满意我们的需求。
案例2:统计“连续两个月都下订单的客户的订单统共有多少个?”

结果:生成的SQL满意我们的需求,固然不是最优解。
4. 后续计划
本文先容了通过Few-shot Prompting来优化Text2SQL生成结果的案例,总的来说,Prompt Engineering提供了一种有效的方法来优化LLM在Text2SQL应用上的效果。通过精心设计的提示,我们可以引导模子更好地明确和处理处罚用户的查询,从而提高查询的准确性和效率。除了使用Few-shot Prompting,还可以思量Agent、CoT等相关技能对Text2SQL效果的优化,后续共同探讨。同时也期待更多的研究和应用来探索和使用大型语言模子的潜力。
技能交流

技能要学会分享、交流,不建议闭门造车。一个人走的很快、一堆人可以走的更远。
建立了大模子技能交流群,大模子学习资料、数据代码、技能交流提升, 均可加知识星球交流群获取,群友已超过2000人,添加时切记的备注方式为:泉源+爱好方向,方便找到志同道合的朋友。
   方式①、添加微信号:mlc2060,备注:技能交流
方式②、微信搜索公众号:呆板学习社区,配景回复:技能交流
  

参考文献:
https://python.langchain.com/docs/use_cases/qa_structured/sql
https://blog.langchain.dev/query-construction/
https://blog.langchain.dev/llms-and-sql/
https://www.promptingguide.ai/zh/techniques/fewshot
https://zhuanlan.zhihu.com/p/663355618

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王國慶

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表