【可能是全網(wǎng)最絲滑的LangChain教程】五账锹、快速入門Conversation Retrieval Chain

系列文章地址

【可能是全網(wǎng)最絲滑的LangChain教程】一、LangChain介紹 - 簡(jiǎn)書 (jianshu.com)
【可能是全網(wǎng)最絲滑的LangChain教程】二酗洒、LangChain安裝 - 簡(jiǎn)書 (jianshu.com)
【可能是全網(wǎng)最絲滑的LangChain教程】三窗骑、快速入門LLMChain - 簡(jiǎn)書 (jianshu.com)
【可能是全網(wǎng)最絲滑的LangChain教程】四、快速入門Retrieval Chain - 簡(jiǎn)書 (jianshu.com)

使用LangChain構(gòu)建應(yīng)用

LangChain支持構(gòu)建應(yīng)用程序耳鸯,將外部數(shù)據(jù)源和計(jì)算源連接到LLM湿蛔。我們將從一個(gè)簡(jiǎn)單的 LLM 鏈開(kāi)始,它只依賴于提示模板中的信息來(lái)響應(yīng)县爬。 接下來(lái)阳啥,我們將構(gòu)建一個(gè)檢索鏈,該鏈從單獨(dú)的數(shù)據(jù)庫(kù)獲取數(shù)據(jù)并將其傳遞到提示模板中财喳。 然后察迟,我們將添加聊天記錄,以創(chuàng)建對(duì)話檢索鏈耳高。這允許您以聊天方式與此 LLM 進(jìn)行交互扎瓶,因此它會(huì)記住以前的問(wèn)題。 最后泌枪,我們將構(gòu)建一個(gè)代理概荷,利用 LLM 來(lái)確定它是否需要獲取數(shù)據(jù)來(lái)回答問(wèn)題。

Conversation Retrieval Chain

到目前為止碌燕,我們創(chuàng)建的鏈只能回答單個(gè)問(wèn)題误证。人們正在構(gòu)建的LLM應(yīng)用程序的主要類型之一是聊天機(jī)器人继薛。那么,我們?nèi)绾螌⑦@條鏈轉(zhuǎn)化為一條可以回答后續(xù)問(wèn)題的鏈呢愈捅?

我們?nèi)匀豢梢允褂胏reate_retrieval_chain函數(shù)遏考,但我們需要更改兩件事:

  • 檢索方法現(xiàn)在不應(yīng)該只針對(duì)最近的輸入,而是應(yīng)該考慮整個(gè)歷史蓝谨。
  • 最后的LLM鏈同樣應(yīng)考慮整個(gè)歷史诈皿。

背景

基于百度百科的《讓子彈飛》介紹,設(shè)計(jì)一個(gè)帶歷史對(duì)話的聊天機(jī)器人像棘。

準(zhǔn)備工作

主要是網(wǎng)頁(yè)數(shù)據(jù)的加載稽亏、嵌入模型的初始化、向量數(shù)據(jù)庫(kù)的初始化等缕题,具體代碼如下截歉。

from langchain_community.document_loaders import WebBaseLoader
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
import torch
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter 

# 詞嵌入模型
EMBEDDING_DEVICE = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu"
embeddings = HuggingFaceEmbeddings(model_name='D:\models\m3e-base', model_kwargs={'device': EMBEDDING_DEVICE})
# 加載外部文檔
loader = WebBaseLoader("https://baike.baidu.com/item/%E8%AE%A9%E5%AD%90%E5%BC%B9%E9%A3%9E/5358?fr=ge_ala")
docs = loader.load()
# 文檔向量化到FAISS
text_splitter = RecursiveCharacterTextSplitter()
documents = text_splitter.split_documents(docs)
vector = FAISS.from_documents(documents, embeddings)
# 得到一個(gè)檢索器
retriever = vector.as_retriever()

Updating Retrieval

為了更新檢索,我們將創(chuàng)建一個(gè)新的鏈烟零。該鏈將接收最近的輸入(input)和會(huì)話歷史(chat_history)瘪松,并使用LLM生成搜索查詢。

from langchain.chains import create_history_aware_retriever
from langchain_core.prompts import MessagesPlaceholder  

prompt = ChatPromptTemplate.from_messages([    
  MessagesPlaceholder(variable_name="chat_history"), 
  ("user", "{input}"),    
  ("user", "Given the above conversation, generate a search query to look up in order to get information relevant to the conversation")
])
retriever_chain = create_history_aware_retriever(llm, retriever, prompt)

現(xiàn)在我們有了這個(gè)新的檢索器锨阿,我們可以創(chuàng)建一個(gè)新的鏈來(lái)繼續(xù)對(duì)話宵睦,并牢記這些檢索到的文檔。

prompt = ChatPromptTemplate.from_messages([    
  ("system", "Answer the user's questions based on the below context:\n\n{context}"),    
  MessagesPlaceholder(variable_name="chat_history"),    
  ("user", "{input}"),
])
document_chain = create_stuff_documents_chain(llm, prompt) 
retrieval_chain = create_retrieval_chain(retriever_chain, document_chain)

測(cè)試一下效果

chat_history = [
  HumanMessage(content="《讓子彈飛》什么時(shí)候在大陸上映的墅诡?"), 
  AIMessage(content="《讓子彈飛》的大陸上映時(shí)間是2010年12月16日壳嚎。")
]
retrieval_chain.invoke({    
  "chat_history": chat_history,    
  "input": "那韓國(guó)上映時(shí)間呢?"
})

最終輸出

《讓子彈飛》在2011年10月8日在韓國(guó)上映末早。

以上就是一個(gè)簡(jiǎn)單的烟馅,帶歷史記錄的聊天機(jī)器人。整個(gè)的流程大概是:檢索文檔找到關(guān)聯(lián)的文檔(一條或者多條)然磷,基于文檔和歷史對(duì)話進(jìn)行問(wèn)答郑趁,得到問(wèn)題的答案。如果如果還要繼續(xù)進(jìn)行問(wèn)答姿搜,往chat_history中添加新的問(wèn)答對(duì)即可寡润。

Peace Guys~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市舅柜,隨后出現(xiàn)的幾起案子梭纹,更是在濱河造成了極大的恐慌,老刑警劉巖业踢,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栗柒,死亡現(xiàn)場(chǎng)離奇詭異礁扮,居然都是意外死亡知举,警方通過(guò)查閱死者的電腦和手機(jī)瞬沦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)雇锡,“玉大人逛钻,你說(shuō)我怎么就攤上這事∶烫幔” “怎么了曙痘?”我有些...
    開(kāi)封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)立肘。 經(jīng)常有香客問(wèn)我边坤,道長(zhǎng),這世上最難降的妖魔是什么谅年? 我笑而不...
    開(kāi)封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任茧痒,我火速辦了婚禮,結(jié)果婚禮上融蹂,老公的妹妹穿的比我還像新娘旺订。我一直安慰自己,他們只是感情好超燃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布区拳。 她就那樣靜靜地躺著,像睡著了一般意乓。 火紅的嫁衣襯著肌膚如雪樱调。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天届良,我揣著相機(jī)與錄音本涕,去河邊找鬼。 笑死伙窃,一個(gè)胖子當(dāng)著我的面吹牛菩颖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播为障,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼晦闰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了鳍怨?” 一聲冷哼從身側(cè)響起呻右,我...
    開(kāi)封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鞋喇,沒(méi)想到半個(gè)月后声滥,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年落塑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纽疟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡憾赁,死狀恐怖污朽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情龙考,我是刑警寧澤蟆肆,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站晦款,受9級(jí)特大地震影響炎功,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缓溅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一亡问、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肛宋,春花似錦州藕、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至沉帮,卻和暖如春锈死,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背穆壕。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工待牵, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人喇勋。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓缨该,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親川背。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贰拿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容