對于給定的文檔, 比如從PDF、網頁、公司主頁中提取構建的內部文檔集合,我們可以使用大語言模型來回答關于這些文檔內容的問題,以幫助用戶更有效地獲取和使用他們所需要的信息。這種方式非常有效且靈活地適用于實際應用場景,因為它不僅僅利用大語言模型已有的訓練集數據信息,它還能使用外部信息。
這個過程會涉及LongChain中的其他組件,比如:表征模型(Embedding Models)和向量儲存(Vector Stores)
一、設置API Key
import os
from zhipuai import ZhipuAI
from dotenv import load_dotenv, find_dotenv# 讀取本地/項目的環境變量。# find_dotenv()尋找并定位.env文件的路徑
# load_dotenv()讀取該.env文件,并將其中的環境變量加載到當前的運行環境中
# 如果你設置的是全局的環境變量,這行代碼則沒有任何作用。
_ = load_dotenv(find_dotenv())# 獲取環境變量 OPENAI_API_KEY
key = "f5cd91f2528fed334b9dfd75015791c3.GuLdvM9tXWrGQnAg"
client = ZhipuAI(api_key = key)
二、 結合表征模型和向量存儲
解決長文檔問答的方法:利用向量表征(Embeddings)和向量存儲(Vector Store)技術處理長文檔,使語言模型能夠回答涉及全部內容的問題。
文本表征將文本轉換為語義向量,相似內容的向量在空間中也相近。這種特性便于在向量空間中進行文本相似性比較。
將文檔分割為較小的文本塊(chunks),獲取每個塊的文本表征并存入向量數據庫。這種處理方式稱為創建索引(index),目的是解決語言模型單次處理文本長度的限制。
為查詢生成向量表征后,與向量數據庫中的向量進行相似性比對,選出最相關的n個文本塊。將這些文本塊構建為提示輸入語言模型,最終生成答案。
2.1 導入數據
from langchain.chains.retrieval_qa.base import RetrievalQA #檢索QA鏈,在文檔上進行檢索
from langchain_community.chat_models.zhipuai import ChatZhipuAI #openai模型
from langchain.document_loaders import CSVLoader #文檔加載器,采用csv格式存儲
from langchain.vectorstores import DocArrayInMemorySearch #向量存儲
from IPython.display import display, Markdown #在jupyter顯示信息的工具
#創建一個文檔加載器,通過csv格式加載
file = 'data/OutdoorClothingCatalog_1000.csv'
loader = CSVLoader(file_path=file,encoding="utf-8")
docs = loader.load()
docs = docs[:20]
2.2 文本向量表征模型
#使用OpenAIEmbedding類
from langchain_community.embeddings.zhipuai import ZhipuAIEmbeddings# 使用智譜 AI 嵌入模型
embeddings = ZhipuAIEmbeddings(model="embedding-2", # 智譜 AI 的嵌入模型名稱api_key=key # 替換為你的智譜 AI API Key
)
#因為文檔比較短了,所以這里不需要進行任何分塊,可以直接進行向量表征
#使用初始化OpenAIEmbedding實例上的查詢方法embed_query為文本創建向量表征
embed = embeddings.embed_query("Hi my name is Harrison")#查看得到向量表征的長度
print(len(embed))
2.3 基于向量表征創建向量存儲
# 將剛才創建文本向量表征(embeddings)存儲在向量存儲(vector store)中
# 使用DocArrayInMemorySearch類的from_documents方法來實現
# 該方法接受文檔列表以及向量表征模型作為輸入
#docs過長會報調用參數有誤,現取前20條
db = DocArrayInMemorySearch.from_documents(docs, embeddings)
import langchain
langchain.__version__
2.4 查詢創建的向量存儲
query = "Please suggest a shirt with sunblocking"#使用上面的向量存儲來查找與傳入查詢類似的文本,得到一個相似文檔列表
docs = db.similarity_search(query)
2.5 使用向量儲存回答文檔的相關問題
#基于向量儲存,創建檢索器
retriever = db.as_retriever()
#導入大語言模型, 這里使用默認模型gpt-3.5-turbo會出現504服務器超時,因此使用gpt-3.5-turbo-0301
llm = ChatZhipuAI(model_name="glm-3-turbo",temperature = 0.0, zhipuai_api_key=key)
#合并獲得的相似文檔內容
qdocs = "".join([docs[i].page_content for i in range(len(docs))])
#將合并的相似文檔內容后加上問題(question)輸入到 `llm.call_as_llm`中
#這里問題是:以Markdown表格的方式列出所有具有防曬功能的襯衫并總結
response = llm.call_as_llm(f"{qdocs} Question: Please list all your \
shirts with sun protection in a table in markdown and summarize each one.")
display(Markdown(response))
'''
通過LangChain鏈封裝起來
創建一個檢索QA鏈,對檢索到的文檔進行問題回答,要創建這樣的鏈,我們將傳入幾個不同的東西
1、語言模型,在最后進行文本生成
2、傳入鏈類型,這里使用stuff,將所有文檔塞入上下文并對語言模型進行一次調用
3、傳入一個檢索器
'''qa_stuff = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=retriever, verbose=True
)
query = "Please list all your shirts with sun protection in a table \
in markdown and summarize each one."#創建一個查詢并在此查詢上運行鏈
response = qa_stuff.run(query)
display(Markdown(response))#使用 display 和 markdown 顯示它