基于Llama 3和LangChain,使用自然語(yǔ)言進(jìn)行SQL查詢 精華
在數(shù)據(jù)泛濫的今天,如何高效地從海量信息中提取有價(jià)值的洞察,已成為開(kāi)發(fā)者面臨的共同挑戰(zhàn)。本文介紹一個(gè)創(chuàng)新項(xiàng)目——基于Streamlit的應(yīng)用程序,它能夠理解自然語(yǔ)言并直接與SQL數(shù)據(jù)庫(kù)進(jìn)行交互,從而簡(jiǎn)化數(shù)據(jù)分析流程。
1 環(huán)境設(shè)置
在本項(xiàng)目中,我們選擇PostgreSQL作為后端數(shù)據(jù)庫(kù)。用戶需自行安裝并配置PostgreSQL,同時(shí)需要搭建Ollama環(huán)境以及OpenWebUI界面。具體的安裝和配置步驟,建議參考相應(yīng)的官方文檔或社區(qū)指南進(jìn)行操作。
2 創(chuàng)建用于生成SQL的自定義模型
接著是創(chuàng)建自定義LLM,根據(jù)用戶輸入生成SQL查詢。這里會(huì)使用OpenWebUI完成這項(xiàng)任務(wù)。以下是設(shè)置方法:
創(chuàng)建新模型文件:
- 命名并描述您的自定義模型。
- 定義模型內(nèi)容,基于Llama 3,溫度設(shè)置為零。
- 在系統(tǒng)消息中,指示模型為PostgreSQL生成SQL,整合數(shù)據(jù)庫(kù)架構(gòu)和關(guān)系。
模型內(nèi)容定義:
- 提供數(shù)據(jù)庫(kù)架構(gòu)。
- 包括有關(guān)查詢結(jié)構(gòu)和表連接的指南。
- 專注于SQL查詢生成,忽略響應(yīng)中的格式。
保存模型:
- 添加提示建議和相關(guān)類別。
- 保存模型文件,使其在Ollama生態(tài)系統(tǒng)中可用。
3 構(gòu)建LangChain集成
LangChain是開(kāi)源的框架,用于構(gòu)建基于大型語(yǔ)言模型的應(yīng)用程序。它通過(guò)將語(yǔ)言模型與內(nèi)部數(shù)據(jù)源相結(jié)合,自動(dòng)化地串聯(lián)起一系列操作,生成智能響應(yīng)。
利用LangChain,我們能夠?qū)崿F(xiàn)數(shù)據(jù)庫(kù)與自然語(yǔ)言之間的無(wú)縫交互。這一解決方案的實(shí)現(xiàn),是通過(guò)在Python的??app.py?
?文件中編寫(xiě)代碼來(lái)完成的。
首先,確保環(huán)境已安裝以下包:
- langchain
- langchain-community
- streamlit
4 建立數(shù)據(jù)庫(kù)連接
將數(shù)據(jù)庫(kù)憑據(jù)保存在本地變量中,并創(chuàng)建一個(gè)使用LangChain的SQLDatabase包裝器建立連接的函數(shù)。
pwd = os.environ['PGPASS']
uid = os.environ['PGUID']
server = "localhost"
db = "adventureworks"
port = 5432
def init_database() -> SQLDatabase:
db_uri = f"postgresql://{uid}:{pwd}@{server}:{port}/{db}"
return SQLDatabase.from_uri(db_uri, schema="sales")
5 使用自定義LLM生成SQL查詢
創(chuàng)建自定義函數(shù),根據(jù)用戶輸入生成SQL。這個(gè)函數(shù)使用Ollama訪問(wèn)自定義模型。
def llm_query(question):
# 第一個(gè)sql llm
llm = ChatOllama(model="llama-sql")
prompt = ChatPromptTemplate.from_template(" {topic}")
# 鏈
chain = prompt | llm | StrOutputParser()
# 鏈調(diào)用
sql = chain.invoke({"topic": f"{question}"})
sql = re.sub(r'(?:(?<=_) | (?=_))','',sql)
# 返回sql查詢
return sql
6 創(chuàng)建完整鏈
開(kāi)發(fā)一個(gè)功能強(qiáng)大的函數(shù),它能夠?qū)崿F(xiàn)與數(shù)據(jù)庫(kù)的自然語(yǔ)言交互。該函數(shù)能夠接收用戶的查詢、數(shù)據(jù)庫(kù)的連接信息以及之前的聊天記錄,從而為用戶提供一個(gè)連貫且上下文相關(guān)的交互體驗(yàn)。
def get_response(user_query: str, db: SQLDatabase, chat_history: list):
sql_query = llm_query(user_query)
template = """
您是公司中經(jīng)驗(yàn)豐富的數(shù)據(jù)分析師。您正在與詢問(wèn)公司數(shù)據(jù)庫(kù)問(wèn)題的用戶進(jìn)行交互。
根據(jù)表架構(gòu)、問(wèn)題、SQL查詢和SQL響應(yīng),用自然語(yǔ)言編寫(xiě)回答。
對(duì)話歷史:{chat_history}
用戶問(wèn)題:{question}
SQL響應(yīng):{response}
"""
prompt = ChatPromptTemplate.from_template(template)
# llm
llm = ChatOllama(model="llama3", temperature=0)
chain = (
RunnablePassthrough.assign(
response=lambda vars: db.run(sql_query),
)
| prompt
| llm
| StrOutputParser()
)
return chain.invoke({
"question": user_query,
"chat_history": chat_history,
})
7 構(gòu)建Streamlit應(yīng)用程序
創(chuàng)建Streamlit組件以存儲(chǔ)聊天歷史和管理用戶交互。
初始化數(shù)據(jù)庫(kù):
# 初始化數(shù)據(jù)庫(kù)
db = init_database()
st.session_state.db = db
st.success("已連接到數(shù)據(jù)庫(kù)!")
處理用戶輸入:
user_query = st.chat_input("輸入一個(gè)問(wèn)題...")
if user_query is not None and user_query.strip() != "":
st.session_state.chat_history.append(HumanMessage(content=user_query))
with st.chat_message("用戶"):
st.markdown(user_query)
with st.chat_message("AI"):
response = get_response(user_query, st.session_state.db, st.session_state.chat_history)
st.markdown(response)
8 測(cè)試應(yīng)用程序
用幾個(gè)查詢來(lái)測(cè)試應(yīng)用程序,以確保其能正常運(yùn)行。
1)總銷售額:
- Query: “What is the total sales?”
2)銷售額Top 10
- Query: “What are the top ten products by sales?”
3)按國(guó)家/地區(qū)銷售情況:
- Query: “Show me the sales by country.”
LangChain和LLM的這種集成為數(shù)據(jù)分析打開(kāi)了無(wú)數(shù)可能性,特別是對(duì)于特定的架構(gòu)。用戶現(xiàn)在可以使用自然語(yǔ)言獲取答案,從而增強(qiáng)和補(bǔ)充現(xiàn)有的商業(yè)智能解決方案。
本文轉(zhuǎn)載自 ??AI科技論談??,作者: AI科技論談
