一、前言
目前,大模型的一個(gè)熱門應(yīng)用方向Text2SQL,它可以幫助用戶快速生成想要查詢的SQL語句,再結(jié)合可視化技術(shù)可以降低使用數(shù)據(jù)的門檻,更便捷的支持決策。本文將從以下四個(gè)方面介紹LLM在Text2SQL應(yīng)用上的基礎(chǔ)實(shí)踐。
· Text2SQL概述
· LangChain基礎(chǔ)知識(shí)
· 基于SQLDatabaseChain的Text2SQL實(shí)踐
· 后續(xù)計(jì)劃
二、Text2SQL概述
Text-to-SQL(或者Text2SQL),顧名思義就是把文本轉(zhuǎn)化為SQL語言,更學(xué)術(shù)一點(diǎn)的定義是:把數(shù)據(jù)庫領(lǐng)域下的自然語言(Natural Language,NL)問題,轉(zhuǎn)化為在關(guān)系型數(shù)據(jù)庫中可以執(zhí)行的結(jié)構(gòu)化查詢語言(Structured Query Language,SQL),因此Text-to-SQL也可以被簡(jiǎn)寫為NL2SQL。
· 輸入:自然語言問題,比如“查詢表t_user的相關(guān)信息,結(jié)果按id降序排序,只保留前10個(gè)數(shù)據(jù) ”
· 輸出:SQL,比如 “SELECT * FROM t_user ORDER BY id DESC LIMIT 10”
Text2SQL應(yīng)用主要是幫助用戶減少開發(fā)時(shí)間,降低開發(fā)成本?!按蚱迫伺c結(jié)構(gòu)化數(shù)據(jù)之間的壁壘”,即普通用戶可以通過自然語言描述完成復(fù)雜數(shù)據(jù)庫的查詢工作,得到想要的結(jié)果。
基于LLM的應(yīng)用開發(fā)基本架構(gòu)如上圖,本文介紹以LangChain + OpenAI + RDB的方式來實(shí)現(xiàn)Text2SQL的實(shí)踐方案。
三、LangChain基礎(chǔ)知識(shí)
LangChain是一個(gè)面向大語言模型的應(yīng)用開發(fā)框架,如果將大語言模型比作人的大腦,那么可以將LangChain可以比作人的五官和四肢,它可以將外部數(shù)據(jù)源、工具和大語言模型連接在一起,既可以補(bǔ)充大語言模型的輸入,也可以承接大語言模型的輸出。
LangChain提供各種不同的組件幫助使用LLM,如下圖所示,核心組件有Models、Indexes、Chains、Memory、Prompt以及Agent。
3.1 Models
LangChain本身不提供LLM,提供通用的接口訪問LLM,可以很方便的更換底層的LLM以及自定義自己的LLM。主要有2大類的Models:
1)LLM:將文本字符串作為輸入并返回文本字符串的模型,類似OpenAI的text-davinci-003
2)Chat Models:由語言模型支持將聊天消息列表作為輸入并返回聊天消息的模型。一般使用的ChatGPT以及Claude為Chat Models。
與模型交互可以通過給予Prompt的方式,LangChain通過PromptTemplate的方式方便我們構(gòu)建以及復(fù)用Prompt。
代碼示例如下:
from langchain import PromptTemplate
# 定義提示模板
prompt = PromptTemplate(input_variables=["question"], template="""
簡(jiǎn)潔和專業(yè)的來回答用戶的問題。
如果無法從中得到答案,請(qǐng)說 “根據(jù)已知信息無法回答該問題” 或 “沒有提供足夠的相關(guān)信息”,不允許在答案中添加編造成分,答案請(qǐng)使用中文。
問題是:{question}""",)
print(prompt.format_prompt(question="如何進(jìn)行數(shù)據(jù)治理"))
3.2 Indexes
索引和外部數(shù)據(jù)進(jìn)行集成,用于從外部數(shù)據(jù)獲取答案。如下圖所示,主要的步驟:
· 通過Document Loaders加載各種不同類型的數(shù)據(jù)源
· 通過Text Splitters進(jìn)行文本語義分割
· 通過Vectorstore進(jìn)行非結(jié)構(gòu)化數(shù)據(jù)的向量存儲(chǔ)
· 通過Retriever進(jìn)行文檔數(shù)據(jù)檢索
3.3 Chains
LangChain通過chain將各個(gè)組件進(jìn)行鏈接,以及chain之間進(jìn)行鏈接,用于簡(jiǎn)化復(fù)雜應(yīng)用程序的實(shí)現(xiàn)。其中主要有LLMChain、SQLDatabase Chain以及Sequential Chain。
3.3.1 LLMChain
最基本的鏈為L(zhǎng)LMChain,由PromptTemplate、LLM和OutputParser組成。LLM的輸出一般為文本,OutputParser用于讓LLM結(jié)構(gòu)化輸出并進(jìn)行結(jié)果解析,方便后續(xù)的調(diào)用。
其實(shí)現(xiàn)原理如圖所示,包含三步:
· 輸入問題
· 拼接提示,根據(jù)提示模板將問題轉(zhuǎn)化為提示
· 模型推理,輸出答案
代碼如下所示:
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain import OpenAI
import os
os.environ["OPENAI_API_KEY"] = "Your openai key"
# 定義模型
llm = OpenAI(temperature=0)
# 定義提示模板
prompt = PromptTemplate(input_variables=["question"], template="""
簡(jiǎn)潔和專業(yè)的來回答用戶的問題。
如果無法從中得到答案,請(qǐng)說 “根據(jù)已知信息無法回答該問題” 或 “沒有提供足夠的相關(guān)信息”,不允許在答案中添加編造成分,答案請(qǐng)使用中文。
問題是:{question}""",)
# 定義chain
chain = LLMChain(llm=llm, prompt=prompt, verbose=True)
# 執(zhí)行chain
print(chain.run("如何開展數(shù)據(jù)治理"))
3.3.2 SQLDatabaseChain
SQLDatabaseChain能夠通過模型自動(dòng)生成SQL并執(zhí)行,其實(shí)現(xiàn)原理如圖所示,包含如下過程:
· 輸入問題;
· 獲取數(shù)據(jù)庫Schema,Schema包含數(shù)據(jù)庫所有表的建表語句和數(shù)據(jù)示例,LangChain支持多種關(guān)系型數(shù)據(jù)庫,包括MariaDB、MySQL、SQLite、ClickHouse、PrestoDB等;
· 拼接提示,根據(jù)提示模板將問題、數(shù)據(jù)庫Schema轉(zhuǎn)化為提示,并且提示中包含指示,要求模型在理解問題和數(shù)據(jù)庫Schema的基礎(chǔ)上,能夠按一定的格式輸出查詢SQL、查詢結(jié)果和問題答案等;
· 模型推理,這一步預(yù)期模型根據(jù)問題、數(shù)據(jù)庫Schema推理、輸出的答案中包含查詢SQL,并從中提取出查詢SQL;
· 執(zhí)行查詢SQL,從數(shù)據(jù)庫中獲取查詢結(jié)果;
· 拼接提示,和上一次拼接的提示基本一致,只是其中的提示中包含了前兩步已獲取的查詢SQL、查詢結(jié)果;
· 模型推理,這一步預(yù)期模型根據(jù)問題、數(shù)據(jù)庫Schema、查詢SQL和查詢結(jié)果推理出最終的問題答案。
3.3.3 SequentialChain
SequentialChains是按預(yù)定義順序執(zhí)行的鏈。SimpleSequentialChain為順序鏈的最簡(jiǎn)單形式,其中每個(gè)步驟都有一個(gè)單一的輸入/輸出,一個(gè)步驟的輸出是下一個(gè)步驟的輸入。SequentialChain為順序鏈更通用的形式,允許多個(gè)輸入/輸出。
3.4 Memory
正常情況下Chain無狀態(tài)的,每次交互都是獨(dú)立的,無法知道之前歷史交互的信息。LangChain使用Memory組件保存和管理歷史消息,這樣可以跨多輪進(jìn)行對(duì)話,在當(dāng)前會(huì)話中保留歷史會(huì)話的上下文。Memory組件支持多種存儲(chǔ)介質(zhì),可以與Mongo、Redis、SQLite等進(jìn)行集成,以及簡(jiǎn)單直接形式就是Buffer Memory。
3.5 Agent
Agent字面含義就是代理,如果說LLM是大腦,Agent就是代理大腦使用工具Tools。目前的大模型一般都存在知識(shí)過時(shí)、邏輯計(jì)算能力低等問題,通過Agent訪問工具,可以去解決這些問題。目前這個(gè)領(lǐng)域特別活躍,誕生了類似AutoGPT、BabyAGI、AgentGPT等一堆優(yōu)秀的項(xiàng)目。傳統(tǒng)使用LLM,需要給定Prompt一步一步地達(dá)成目標(biāo),通過Agent是給定目標(biāo),其會(huì)自動(dòng)規(guī)劃并達(dá)到目標(biāo)。
四、基于SQLDatabaseChain的Text2SQL實(shí)踐
4.1 簡(jiǎn)介
LangChain提供基于LLM的SQLDatabaseChain,可以利用LLM的能力將自然語言的query轉(zhuǎn)化為SQL,連接DB進(jìn)行查詢,并利用LLM來組裝潤(rùn)色結(jié)果,返回最終answer。
在后臺(tái),LangChain 使用SQLAlchemy
連接到 SQL 數(shù)據(jù)庫。因此,SQLDatabaseChain
可以與 SQLAlchemy 支持的任何 SQL 方言一起使用,例如 MS SQL、MySQL、MariaDB、PostgreSQL、Oracle和 SQLite。
4**.**2 數(shù)據(jù)準(zhǔn)備
本案例使用SQLite 和示例Chinook 數(shù)據(jù)庫,用戶可按照https://database.guide/2-sample-databases-sqlite/ 上的說明進(jìn)行設(shè)置。Chinook表示一個(gè)數(shù)字多媒體商店,包含了顧客(Customer)、雇員(Employee)、歌曲(Track)、訂單(Invoice)及其相關(guān)的表和數(shù)據(jù),數(shù)據(jù)模型如下圖所示。
4.3實(shí)踐過程
需求: 測(cè)試中文提問“總共有多少員工?”,即英文提問“How many employees are there?”
期望: 模型先給出查詢Employee表記錄數(shù)的SQL,再根據(jù)查詢結(jié)果給出最終的答案。
(1)測(cè)試中文提問,代碼如下所示:
from langchain.llms import OpenAI
from langchain.utilities import SQLDatabase
from langchain_experimental.sql import SQLDatabaseChain
import os
os.environ["OPENAI_API_KEY"] = "Your openai key"
db = SQLDatabase.from_uri("sqlite:///..../Chinook.db")
llm = OpenAI(temperature=0, verbose=True)
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)
db_chain.run("總共有多少員工?")
輸出結(jié)果如下:
這里我們使用商業(yè)化的OpenAI,并將其temperature設(shè)為0,因?yàn)椴樵僁B不太需要?jiǎng)?chuàng)造性和多樣性。從返回的過程來看,自然語言被翻譯成了SQL,得到查詢結(jié)果后,解析包裝結(jié)果,最終返回我們可以理解的答案。這里L(fēng)LM成功將“總共”轉(zhuǎn)成select count(*),并準(zhǔn)確地識(shí)別出表名,且最終組裝出正確的結(jié)果。
注意: 對(duì)于數(shù)據(jù)敏感項(xiàng)目,可以在 SQLDatabaseChain 初始化中指定 return_direct=True,以直接返回 SQL 查詢的輸出,而無需任何其他格式設(shè)置。這樣可以防止 LLM 看到數(shù)據(jù)庫中的任何內(nèi)容。但請(qǐng)注意,默認(rèn)情況下,LLM 仍然可以訪問數(shù)據(jù)庫方案(即所用方言、表名和列名)。
(2)測(cè)試英文提問,也可以得到我們想要的結(jié)果:
通過上例,我們可以借助LangChain提供的SQLDatabaseChain,輕松地連接LLM與Database,自然語言的方式輸入,自然語言的方式輸出,借助LLM的強(qiáng)大能力來理解問題、生成SQL查詢數(shù)據(jù)并輸出結(jié)果。
五、后續(xù)計(jì)劃
隨著大模型的發(fā)展,LangChain是目前最火的LLM開發(fā)框架之一,能和外部數(shù)據(jù)源交互、能集成各種常用的組件等等,大大降低了LLM應(yīng)用開發(fā)的門檻?;赟QLDatabaseChain實(shí)現(xiàn)的Text2SQL只是最基礎(chǔ)的實(shí)踐方式,但對(duì)于邏輯復(fù)雜的查詢?cè)诜€(wěn)定性、可靠性、安全性方面可能無法達(dá)到預(yù)期,比如輸出幻覺問題、數(shù)據(jù)安全問題。如何解決或減少該類問題的出現(xiàn),可改進(jìn)的措施和方案在后續(xù)專題中繼續(xù)討論,大家一起群策群力??傊瑢?shí)現(xiàn)高穩(wěn)定、高可靠的基于LLM的應(yīng)用,是一個(gè)持續(xù)改進(jìn)的過程,是一個(gè)多種技術(shù)相結(jié)合的過程。
參考文獻(xiàn):
https://docs.langchain.com/docs/
https://platform.openai.com/
https://database.guide/2-sample-databases-sqlite/
https://www.langchain.asia/modules/chains/examples/sqlite
https://mp.weixin.qq.com/s/pgRC71IkSXrOjZg3W9V72g文章來源:http://www.zghlxwxcb.cn/news/detail-792561.html
https://zhuanlan.zhihu.com/p/640580808文章來源地址http://www.zghlxwxcb.cn/news/detail-792561.html
到了這里,關(guān)于大模型LLM在 Text2SQL 上的應(yīng)用實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!