譯者 | 朱先忠
審校 | 重樓
摘要:在本博客中,我們將了解一種名為檢索增強生成(retrieval augmented generation)的提示工程技術(shù),并將基于Langchain、ChromaDB和GPT 3.5的組合來實現(xiàn)這種技術(shù)。
動機
隨著GPT-3等基于轉(zhuǎn)換器的大數(shù)據(jù)模型的出現(xiàn),自然語言處理(NLP)領(lǐng)域取得了重大突破。這些語言模型能夠生成類似人類的文本,并已有各種各樣的應(yīng)用程序,如聊天機器人、內(nèi)容生成和翻譯等。然而,當涉及到專業(yè)化和特定于客戶的信息的企業(yè)應(yīng)用場景時,傳統(tǒng)的語言模型可能滿足不了要求。另一方面,使用新的語料庫對這些模型進行微調(diào)可能既昂貴又耗時。為了應(yīng)對這一挑戰(zhàn),我們可以使用一種名為“檢索增強生成”(RAG:Retrieval Augmented Generation)的技術(shù)。
在本博客中,我們將探討這種檢索增強生成(RAG)技術(shù)是如何工作的,并通過一個實戰(zhàn)示例來證明這一技術(shù)的有效性。需要說明的是,此實例將使用GPT-3.5 Turbo作為附加語料庫對產(chǎn)品手冊進行響應(yīng)。
想象一下,你的任務(wù)是開發(fā)一個聊天機器人,該機器人可以響應(yīng)有關(guān)特定產(chǎn)品的查詢。該產(chǎn)品有自己獨特的用戶手冊,專門針對企業(yè)的產(chǎn)品。傳統(tǒng)的語言模型,如GPT-3,通常是根據(jù)一般數(shù)據(jù)進行訓練的,可能不了解這種特定的產(chǎn)品。另一方面,使用新的語料庫對模型進行微調(diào)似乎是一種解決方案;然而,此辦法會帶來相當大的成本和資源需求。
檢索增強生成(RAG)簡介
檢索增強生成(RAG)提供了一種更高效的方法來解決在特定領(lǐng)域生成上下文適當?shù)捻憫?yīng)的問題。RAG沒有使用新的語料庫對整個語言模型進行微調(diào),而是利用檢索的能力按需訪問相關(guān)信息。通過將檢索機制與語言模型相結(jié)合,RAG通過結(jié)合外部上下文來增強響應(yīng)。這個外部上下文可以作為向量嵌入來提供。
下面給出了創(chuàng)建本文中應(yīng)用程序時需要遵循的步驟流程。
- 閱讀Clarett用戶手冊(PDF格式)并使用1000個令牌的chunk_size進行令牌化。
- 創(chuàng)建這些標記的向量嵌入。我們將使用OpenAIEmbeddings庫來創(chuàng)建向量嵌入。
- 將向量嵌入存儲在本地。我們將使用簡單的ChromaDB作為我們的VectorDB。我們可以使用Pinecone或任何其他更高可用性的生產(chǎn)級的向量數(shù)據(jù)庫VectorDB。
- 用戶發(fā)出帶有查詢/問題的提示。
- 這將從VectorDB中進行搜索和檢索,以便從VectorDB中獲取更多上下文數(shù)據(jù)。
- 此上下文數(shù)據(jù)現(xiàn)在將與提示內(nèi)容一起使用。
- 上下文增強了提示,這通常被稱為上下文豐富。
- 提示信息,連同查詢/問題和這個增強的上下文,現(xiàn)在被傳遞給大型語言模型LLM。
- 至此,LLM基于此上下文進行響應(yīng)。
需要說明的是,在本示例中,我們將使用Focusrite Clarett用戶手冊作為附加語料庫。Focusrite Clarett是一個簡單的USB音頻接口,用于錄制和播放音頻。您可以從鏈接https://fael-downloads-prod.focusrite.com/customer/prod/downloads/Clarett%208Pre%20USB%20User%20Guide%20V2%20English%20-%20EN.pdf處下載使用手冊。
實戰(zhàn)演練
設(shè)置虛擬環(huán)境
讓我們設(shè)置一個虛擬環(huán)境來把我們的實現(xiàn)案例封裝起來,以避免系統(tǒng)中可能出現(xiàn)的任何版本/庫/依賴性沖突。現(xiàn)在,我們執(zhí)行以下命令來創(chuàng)建一個新的Python虛擬環(huán)境:
pip install virtualenv
python3 -m venv ./venv
source venv/bin/activate
創(chuàng)建OpenAI密鑰
接下來,我們將需要一個OpenAI密鑰來訪問GPT。讓我們創(chuàng)建一個OpenAI密鑰。您可以通過在鏈接https://platform.openai.com/apps處注冊O(shè)penAI來免費創(chuàng)建OpenAIKey。
注冊后,登錄并選擇API選項,如屏幕截圖所示(時間原因所致,當您打開該屏幕設(shè)計時可能會與我當前拍攝屏幕截圖有所變化)。
然后,轉(zhuǎn)到您的帳戶設(shè)置并選擇“查看API密鑰(View API Keys)”:
然后,選擇“創(chuàng)建新密鑰(Create new secret key)”,你會看到一個彈出窗口,如下圖所示。你需要提供一個名稱,這將會生成一個密鑰。
該操作將生成一個唯一的密鑰,您應(yīng)該將其復(fù)制到剪貼板并存儲在安全的地方。
接下來,讓我們編寫Python代碼來實現(xiàn)上面流程圖中顯示的所有步驟。
安裝依賴庫
首先,讓我們安裝我們需要的各種依賴項。我們將使用以下庫:
- Lanchain:一個開發(fā)LLM應(yīng)用程序的框架。
- ChromaDB:這是用于持久化向量嵌入的VectorDB。
- unstructured:用于預(yù)處理Word/PDF文檔。
- Tiktoken:Tokenizer框架
- pypdf:閱讀和處理PDF文檔的框架
- openai:訪問openai的框架
pip install langchain
pip install unstructured
pip install pypdf
pip install tiktoken
pip install chromadb
pip install openai
一旦成功安裝了這些依賴項,請創(chuàng)建一個環(huán)境變量來存儲在最后一步中創(chuàng)建的OpenAI密鑰。
export OPENAI_API_KEY=<OPENAI-KEY>
接下來,讓我們開始編程。
從用戶手冊PDF創(chuàng)建向量嵌入并將其存儲在ChromaDB中
在下面的代碼中,我們將導入所有將要使用的依賴庫和函數(shù)。
import os
import openai
import tiktoken
import chromadb
from langchain.document_loaders import OnlinePDFLoader, UnstructuredPDFLoader, PyPDFLoader
from langchain.text_splitter import TokenTextSplitter
from langchain.memory import ConversationBufferMemory
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.llms import OpenAI
from langchain.chains import ConversationalRetrievalChain
在下面的代碼中,閱讀PDF,將文檔標記化并拆分為標記。
loader = PyPDFLoader("Clarett.pdf")
pdfData = loader.load()
text_splitter = TokenTextSplitter(chunk_size=1000, chunk_overlap=0)
splitData = text_splitter.split_documents(pdfData)
在下面的代碼中,我們將創(chuàng)建一個色度集合,一個用于存儲色度數(shù)據(jù)庫的本地目錄。然后,我們創(chuàng)建一個向量嵌入并將其存儲在ChromaDB數(shù)據(jù)庫中。
collection_name = "clarett_collection"
local_directory = "clarett_vect_embedding"
persist_directory = os.path.join(os.getcwd(), local_directory)
openai_key=os.environ.get('OPENAI_API_KEY')
embeddings = OpenAIEmbeddings(openai_api_key=openai_key)
vectDB = Chroma.from_documents(splitData,
embeddings,
collection_name=collection_name,
persist_directory=persist_directory
)
vectDB.persist()
執(zhí)行此代碼后,您應(yīng)該會看到創(chuàng)建了一個存儲向量嵌入的文件夾。
現(xiàn)在,我們將向量嵌入存儲在ChromaDB中。下面,讓我們使用LangChain中的ConversationalRetrievalChain API來啟動聊天歷史記錄組件。我們將傳遞由GPT 3.5 Turbo啟動的OpenAI對象和我們創(chuàng)建的VectorDB。我們將傳遞ConversationBufferMemory,它用于存儲消息。
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
chatQA = ConversationalRetrievalChain.from_llm(
OpenAI(openai_api_key=openai_key,
temperature=0, model_name="gpt-3.5-turbo"),
vectDB.as_retriever(),
memory=memory)
既然我們已經(jīng)初始化了會話檢索鏈,那么接下來我們就可以使用它進行聊天/問答了。在下面的代碼中,我們接受用戶輸入(問題),直到用戶鍵入“done”。然后,我們將問題傳遞給LLM以獲得回復(fù)并打印出來。
chat_history = []
qry = ""
while qry != 'done':
qry = input('Question: ')
if qry != exit:
response = chatQA({"question": qry, "chat_history": chat_history})
print(response["answer"])
這是輸出的屏幕截圖。
小結(jié)
正如你從本文中所看到的,檢索增強生成是一項偉大的技術(shù),它將GPT-3等語言模型的優(yōu)勢與信息檢索的能力相結(jié)合。通過使用特定于上下文的信息豐富輸入,檢索增強生成使語言模型能夠生成更準確和與上下文相關(guān)的響應(yīng)。在微調(diào)可能不實用的企業(yè)應(yīng)用場景中,檢索增強生成提供了一種高效、經(jīng)濟高效的解決方案,可以與用戶進行量身定制、知情的交互。
譯者介紹
朱先忠,51CTO社區(qū)編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。
原文標題:Prompt Engineering: Retrieval Augmented Generation(RAG),作者:A B Vijay Kumar