提示工程——檢索增強生成(RAG)
隨著GPT-3等大語言模型的出現,自然語言處理(NLP)領域取得了重大突破。這些語言模型具有生成類人文本的能力,并且已經在各種場景中得到應用,例如:聊天機器人、翻譯。
然而,當涉及到專業化和定制化的應用場景時,通用的大語言模型可能在專業知識方面會有所不足。用專業的語料庫對這些模型進行微調往往昂貴且耗時。“檢索增強生成”(RAG)為專業化應用提供了一個新技術方案。
下面我們主要介紹RAG如何工作,并通過一個實際的例子,將產品手冊作為專業語料庫,使用GPT-3.5 Turbo來作為問答模型,驗證其有效性。
案例:開發一個聊天機器人,可以回答有關特定產品的知識。該企業的產品自己獨特的用戶手冊。
RAG介紹
RAG 提供了一個有效的方式來解決在特定領域的問答,主要將行業知識轉化為向量進行存儲和檢索,通過知識檢索的結果與用戶問題結合形成Prompt,最后利用大模型生成合適的回答。檢索機制與語言模型的相結合,增強了大模型的響應能力。
下面是創建聊天機器人程序的步驟:
- 讀取PDF(用戶手冊PDF文件)并使用chunk_size為1000個令牌進行令牌化。
- 創建向量(可以使用OpenAI EmbeddingsAPI來創建向量)。
- 在本地向量庫中存儲向量。我們將使用ChromaDB作為向量數據庫(向量數據庫也可以使用Pinecone或其他產品替代)。
- 用戶發出具有查詢/問題的提示。
- 根據用戶的問題從向量數據庫檢索出知識上下文數據。這個知識上下文數據將在后續步驟中與提示詞結合使用,來增強提示詞,通常被稱為上下文豐富。
- 提示詞包含用戶問題和增強的上下文知識一起被傳遞給LLM
- LLM 基于此上下文進行回答。
動手開發
(1)設置Python虛擬環境 設置一個虛擬環境來沙箱化我們的Python,以避免任何版本或依賴項沖突。執行以下命令以創建新的Python虛擬環境。
pip install virtualenv
python3 -m venv ./venv
source venv/bin/activate
(2)創建OpenAI密鑰
需要一個OpenAI密鑰來訪問GPT。
(3)安裝依賴庫
安裝程序需要的各種依賴項。包括以下幾個庫:
- lanchain:一個開發LLM應用程序的框架。
- chromaDB:這是用于持久化向量嵌入的VectorDB。
- unstructured:用于預處理Word/PDF文檔。
- tiktoken: Tokenizer framework
- pypdf:讀取和處理PDF文檔的框架。
- openai:訪問OpenAI的框架。
pip install langchain
pip install unstructured
pip install pypdf
pip install tiktoken
pip install chromadb
pip install openai
創建一個環境變量來存儲OpenAI密鑰。
export OPENAI_API_KEY=<OPENAI-KEY>
(4)將用戶手冊PDF文件轉化為向量并將其存儲在ChromaDB中
導入所有將要使用的依賴庫和函數。
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)
創建一個chroma集合,和一個存儲chroma數據的本地目錄。然后,創建一個向量(embeddings)并將其存儲在ChromaDB中。
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()
執行此代碼后,您應該看到一個已經創建好的文件夾,用于存儲向量。
將向量嵌入存儲在ChromaDB后,接著使用LangChain中的ConversationalRetrievalChain API來啟動一個聊天歷史組件。
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)
初始化了langchan之后,我們可以使用它來聊天/Q A。下面的代碼中,接受用戶輸入的問題,并在用戶輸入'done'之后,將問題傳遞給LLM,以獲得答復并打印出來。
chat_history = []
qry = ""
while qry != 'done':
qry = input('Question: ')
if qry != exit:
response = chatQA({"question": qry, "chat_history": chat_history})
print(response["answer"])
總之
RAG將GPT等語言模型的優勢與信息檢索的優勢結合在一起。通過使用特定的知識上下文的信息提高提示詞的豐富程度,使語言模型能夠生成更準確的和知識上下文相關的回答。RAG提供了一種比“微調”更高效且具有成本效益的解決方案,為行業應用或企業應用提供可定制化的交互方案。