系列文章地址
【可能是全網最絲滑的LangChain教程】一肌括、LangChain介紹 - 簡書 (jianshu.com)
【可能是全網最絲滑的LangChain教程】二诅福、LangChain安裝 - 簡書 (jianshu.com)
【可能是全網最絲滑的LangChain教程】三、快速入門LLMChain - 簡書 (jianshu.com)
使用LangChain構建應用
LangChain支持構建應用程序需忿,將外部數據源和計算源連接到LLM诅炉。我們將從一個簡單的 LLM 鏈開始,它只依賴于提示模板中的信息來響應贴谎。 接下來汞扎,我們將構建一個檢索鏈,該鏈從單獨的數據庫獲取數據并將其傳遞到提示模板中擅这。 然后澈魄,我們將添加聊天記錄,以創(chuàng)建對話檢索鏈仲翎。這允許您以聊天方式與此 LLM 進行交互痹扇,因此它會記住以前的問題。 最后溯香,我們將構建一個代理鲫构,利用 LLM 來確定它是否需要獲取數據來回答問題。
Retrieval Chain
1 問一個LLM不知道的問題
"數據空間研究院是誰出資建立的玫坛?"
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(openai_api_key="...")
llm.invoke("數據空間研究院是誰出資建立的结笨?")
因為LLM沒有學習郭過相關的知識,所以輸出的結果不是我們想要的,如下
AIMessage(content='抱歉炕吸,我不確定數據空間研究院是誰出資建立的伐憾。 ')
2 怎么讓LLM正確回答它沒學習過的相關知識的問題?
為了正確回答最初的問題(“數據空間研究院是誰出資建立的赫模?”)树肃,我們需要為 LLM 提供額外的上下文。 我們可以通過檢索來做到這一點瀑罗。 當您有太多數據無法直接傳遞給 LLM 時胸嘴,檢索非常有用。 然后斩祭,您可以使用檢索器僅獲取最相關的部分并將其傳遞劣像。
在此過程中,我們將從 Retriever 中查找相關文檔停忿,然后將它們傳遞到提示符中驾讲。 Retriever 可以由任何東西支持——SQL 表、互聯網席赂、文檔等——但在這種情況下,我們將填充一個向量存儲并將其用作檢索器时迫。
2.1 創(chuàng)建用于將文檔列表傳遞給模型的鏈
首先颅停,讓我們設置一個鏈,該鏈接受一個問題和檢索到的文檔并生成一個答案掠拳。
from langchain.chains.combine_documents import create_stuff_documents_chain
prompt = ChatPromptTemplate.from_template("""僅根據提供的上下文回答以下問題:
<上下文>
{context}
</上下文>
問題: {input}""")
document_chain = create_stuff_documents_chain(llm, prompt)
2.2 傳入文檔信息
這里傳入文檔信息可以選擇手動傳入癞揉,也可以選擇從指定文檔(網頁、PDF溺欧、文檔等等)加載喊熟。
2.2.1 手動傳入文檔信息
from langchain_core.documents import Document
document_chain.invoke({
"input": "數據空間研究院是誰出資建立的?",
"context": [Document(page_content="合肥綜合性國家科學中心數據空間研究院是由安徽省人民政府發(fā)起成立的事業(yè)單位姐刁,是新一代信息技術數據空間領域的大型新型研發(fā)機構芥牌,致力于引領網絡空間安全和數據要素創(chuàng)新技術前沿和創(chuàng)新方向,凝聚一批海內外領軍科學家團隊聂使,匯聚相關行業(yè)大數據壁拉,開展數據空間基礎理論、體系架構柏靶、關鍵技術研究以及相關能力建設弃理,打造大數據發(fā)展新高地,推進“數字江淮”建設屎蜓,為數字中國建設貢獻“安徽智慧”“合肥智慧”痘昌。")]
})
輸出:
安徽省人民政府
2.2.2 從網頁加載
首先,我們需要加載要索引的數據。因為我需要從網頁(百度百科)獲取數據辆苔,為此笔诵,我們將使用 WebBaseLoader。這需要安裝 BeautifulSoup:
pip install beautifulsoup4
之后姑子,我們可以導入和使用 WebBaseLoader乎婿。
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://baike.baidu.com/item/%E5%90%88%E8%82%A5%E7%BB%BC%E5%90%88%E6%80%A7%E5%9B%BD%E5%AE%B6%E7%A7%91%E5%AD%A6%E4%B8%AD%E5%BF%83%E6%95%B0%E6%8D%AE%E7%A9%BA%E9%97%B4%E7%A0%94%E7%A9%B6%E9%99%A2/62996254?fr=ge_ala")
docs = loader.load()
接下來,我們需要將其索引到向量存儲中街佑。這需要一些組件谢翎,即嵌入模型和向量存儲。
對于嵌入模型沐旨,這里使用目前比較熱門的m3e-base森逮。m3e-base使用時需要指定加載路徑,可以是本地或者在線(在線的本質也是先下載后加載)磁携,這里我已經提前下載好了褒侧。
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
import torch
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})
現在,我們可以使用此嵌入模型將文檔攝取到矢量存儲中谊迄。 為了簡單起見闷供,我們將使用一個簡單的本地向量存儲 FAISS。
首先统诺,我們需要為此安裝所需的軟件包歪脏。如果機器有顯卡,選擇下載完整的faiss粮呢,我這里用faiss-cpu婿失,因為我電腦沒顯卡。
pip install faiss-cpu
然后我們可以建立我們的索引:
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter()
documents = text_splitter.split_documents(docs)
vector = FAISS.from_documents(documents, embeddings)
現在啄寡,我們已經在向量存儲中索引了這些數據豪硅,我們將創(chuàng)建一個檢索鏈。 該鏈將接受一個傳入的問題挺物,查找相關文檔懒浮,然后將這些文檔與原始問題一起傳遞到 LLM 中,并要求它回答原始問題姻乓。
使用從網頁獲取的數據信息:
from langchain.chains import create_retrieval_chain
retriever = vector.as_retriever()
retrieval_chain = create_retrieval_chain(retriever, document_chain)
response = retrieval_chain.invoke({"input": "數據空間研究院是誰出資創(chuàng)建的嵌溢?"})
print(response["answer"])
這里輸出的結果是:
合肥綜合性國家科學中心數據空間研究院是由安徽省人民政府發(fā)起成立的。
總結
我們現在已經成功地建立了一個基本的檢索鏈蹋岩。我們只觸及了檢索的基礎知識赖草,Retrieval Chain還有更多的用法,包括嵌入模型的選擇(不同模型的效果有差異剪个,進而影響最終輸出結果的準確性)秧骑、文檔加載器的選擇(你的文檔是什么格式?來自本地還是網頁?視頻還是文本乎折?)绒疗、文檔怎么檢索(MapReduce、MapRerank骂澄、Reduce吓蘑、Refine、Stuff)等等等等坟冲。具體怎么使用磨镶,請關注后續(xù)文章更新。
Peace Guys~