摘要
????????Advanced RAG 的后檢索優化,是指在檢索環節完成后、最終響應生成前,通過一系列策略與技術對檢索結果進行深度處理,旨在顯著提升生成內容的相關性與質量。在這些優化手段中,上文壓縮與過濾技術是提升檢索結果質量的重要手段。它能巧妙篩除冗余、無關信息,萃取關鍵內容,為后續處理奠定優質基礎。本文將聚焦上文壓縮與過濾技術展開深入探究,并依托功能強大的 LangChain 框架,具體闡釋相關策略的實現路徑,助力深入理解與應用這一關鍵技術。
上下文壓縮原理說明
-
多元檢索:利用各類基礎檢索器,如基于關鍵詞匹配的傳統檢索器、向量檢索器等。這些檢索器從不同數據源(如文檔庫、知識庫等)獲取與問題相關的信息。比如在一個企業知識問答場景中,向量檢索器可從企業內部文檔向量數據庫中找出語義相關的文檔片段,關鍵詞檢索器則可定位包含特定業務術語的資料。
-
信息匯聚:將從不同檢索器獲取到的信息整合到文檔壓縮器中。此時,收集到的信息可能包含大量冗余、不相關或重復的內容。例如,多個檢索器可能返回關于同一主題但表述略有差異的段落。
-
精準過濾提取:文檔壓縮器運用多種技術對輸入信息進行處理。一方面,通過文本分類、關鍵詞提取等方法判斷信息與問題的相關性,剔除明顯無關的內容;另一方面,利用摘要算法,如抽取式摘要或生成式摘要技術,提煉出關鍵信息。比如對于一個關于 “如何優化電商網站用戶體驗” 的問題,壓縮器會過濾掉電商運營中物流配送等無關信息,提取頁面布局優化、交互設計等相關內容。
????????通過這一系列步驟,RAG 系統能夠為后續的生成模型提供精煉、有效的上下文信息,助力生成更準確、有用的回答。
LLMChainExtractor 文檔壓縮
? ? ? ? LLMChainExtractor 借助大語言模型(LLM)的理解和生成能力,對檢索到的文本進行分析。它能識別文本中的關鍵信息片段,依據語言邏輯和語義關聯,將重要內容提取出來。它能深入理解文本語義,提取出具有較高價值的信息,適用于各種復雜文本結構的處理。
代碼示例
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains.llm import LLMChain
from langchain.retrievers.document_compressors import LLMChainExtractor
from langchain.retrievers import ContextualCompressionRetriever# 加載文檔
loader = TextLoader('example.txt', encoding='utf-8')
docs = loader.load()# 分割文檔
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
chunks = text_splitter.split_documents(docs)# 創建向量存儲
embeddings = HuggingFaceEmbeddings()
vectorstore = Chroma.from_documents(documents=chunks, embedding=embeddings)# 初始化 LLM
llm = ChatOpenAI(temperature=0)# 創建 LLMChain
llm_chain = LLMChain(llm=llm)# 創建 LLMChainExtractor
compressor = LLMChainExtractor(llm_chain=llm_chain)# 創建基礎檢索器
base_retriever = vectorstore.as_retriever()# 創建 ContextualCompressionRetriever
compression_retriever = ContextualCompressionRetriever(base_compressor=compressor,base_retriever=base_retriever
)# 定義查詢
query = "文檔中提到的關鍵要點有哪些?"# 執行檢索
results = compression_retriever.get_relevant_documents(query)# 打印結果
for doc in results:print(doc.page_content)
-
LLMChainExtractor:使用?
LLMChainExtractor
?作為文檔壓縮器,它將使用 LLMChain 從檢索到的文檔中提取相關信息。我們的代碼中并未定義prompt,所以LLMChainExtractor 將使用默認的prompt 結構,在langchain.retrievers.document_compressors.chain_extract_prompt中定義。我們也可將默認提示詞作為參考,自定義文本壓縮提示詞,默認prompt 如下所示:
# flake8: noqa prompt_template = """Given the following question and context, extract any part of the context *AS IS* that is relevant to answer the question. If none of the context is relevant return {no_output_str}. Remember, *DO NOT* edit the extracted parts of the context.> Question: {{question}} > Context: >>> {{context}} >>> Extracted relevant parts:"""
-
ContextualCompressionRetriever:是 LangChain 框架中用于文檔檢索的工具,主要功能是在檢索文檔時對結果進行上下文相關的壓縮,以提高檢索效率和質量。通過ContextualCompressionRetriever我們可以配置不同的檢索器與壓縮器,最終在檢索時實現文檔壓縮提取的效果。
LLMChainFilter 文檔過濾
? ?LLMChainFilter
是 LangChain 中用于過濾文檔的工具,它基于 LLMChain 的結果對文檔進行篩選,只有符合特定條件的文檔才會被保留。
-
LLMChainFilter
利用LLMChain
來處理文檔。LLMChain
由一個語言模型(LLM)和一個提示模板(PromptTemplate)組成。用戶提供一個提示模板,其中包含文檔內容和一些特定的問題或條件。LLMChain
將文檔內容填充到提示模板中,并調用語言模型生成回答。 -
生成的回答會被用于判斷文檔是否通過過濾。可以根據回答的內容、結構或其他特征來定義過濾條件。例如,可以設置條件為當語言模型生成的回答中包含特定關鍵詞時,文檔通過過濾;或者當回答滿足某種語義理解,如對某個問題的回答為肯定時,文檔通過過濾。
代碼示例
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains.llm import LLMChain
from langchain.retrievers.document_compressors import LLMChainExtractor
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainFilter# 加載文檔
loader = TextLoader('example.txt', encoding='utf-8')
docs = loader.load()# 分割文檔
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
chunks = text_splitter.split_documents(docs)# 創建向量存儲
embeddings = HuggingFaceEmbeddings()
vectorstore = Chroma.from_documents(documents=chunks, embedding=embeddings)# 初始化 LLM
llm = ChatOpenAI(temperature=0)# 創建用于過濾的 LLMChain
filter_llm_chain = LLMChain(llm=llm)# 創建 LLMChainFilter
filter = LLMChainFilter(llm_chain=filter_llm_chain)# 定義查詢
query = "文檔中提到的關鍵技術有哪些?"# 執行檢索
docs = retriever.get_relevant_documents(query)# 執行過濾
filtered_docs = filter.compress_documents(docs, query=query)# 打印結果
for doc in filtered_docs:print(doc.page_content)
-
LLMChainFilter:我們使用LLMChainFilter 結合LLM進行文本過濾,用戶可以自定義過濾提示詞,也可使用LangChain 框架在langchain.retrievers.document_compressors.chain_filter_prompt 中提供的默認提示詞,或作為參考:
# flake8: noqa prompt_template = """Given the following question and context, return YES if the context is relevant to the question and NO if it isn't.> Question: {question} > Context: >>> {context} >>> > Relevant (YES / NO):"""
EmbeddingsFilter 向量相似度過濾
? ?EmbeddingsFilter
使用預訓練的詞嵌入模型或句子嵌入模型,將文本轉換為低維向量空間中的向量表示。通過計算這些向量之間的相似度,來判斷文本之間的相關性或相似性,進而根據設定的閾值對文本進行過濾。
-
優勢
-
高效性:基于向量空間的計算,能夠快速計算文本之間的相似度,相比基于文本內容的直接比較,大大提高了過濾的效率,尤其適用于處理大規模文本數據。
-
語義理解能力:預訓練的嵌入模型能夠捕捉文本的語義信息,因此
EmbeddingsFilter
可以從語義層面判斷文本的相關性,而不僅僅是基于表面的詞匯匹配,從而提高過濾的準確性。
-
-
局限
-
依賴預訓練模型:其性能高度依賴于所使用的預訓練嵌入模型的質量和適用性。如果模型不能很好地捕捉文本的語義和句法信息,或者與具體應用場景不匹配,可能會導致過濾效果不佳。
-
缺乏領域適應性:對于一些特定領域的文本,可能需要針對該領域進行專門的模型訓練或調整,否則可能無法準確理解領域特定的術語和概念,影響過濾的準確性。
-
難以處理復雜語義關系:雖然能夠捕捉一定的語義信息,但對于一些復雜的語義關系和上下文依賴的文本理解,可能存在局限性,無法像人類一樣全面、準確地理解文本的含義。
-
代碼示例
from langchain.retrievers.document_compressors import EmbeddingsFilter'''對檢索到的文檔塊與查詢進行相似度計算,如果相似度大于0.66,則保留該文檔塊,否則過濾掉'''
embeddings_filter = EmbeddingsFilter(embeddings=embeddings_model, similarity_threshold=0.66)compression_retriever = ContextualCompressionRetriever(base_compressor=embeddings_filter, base_retriever=retriever
)compressed_docs = compression_retriever.invoke("deepseek的發展歷程"
)
print("-------------------EmbeddingsFilter壓縮后--------------------------")
pretty_print_docs(compressed_docs)
EmbeddingsRedundantFilter 冗余文檔過濾
? EmbeddingsRedundantFilter
是一種基于嵌入向量的過濾器,用于識別和過濾文本數據中的冗余信息。EmbeddingsRedundantFilter
通過計算文本向量之間的相似度來判斷文本是否冗余。常用的相似度計算方法包括余弦相似度、歐式距離等。如果兩個文本的向量相似度超過了設定的閾值,就認為它們是冗余的,其中一個文本可能會被過濾掉。
-
優勢
-
語義層面的過濾:與基于簡單字符串匹配或詞頻統計的過濾方法不同,
EmbeddingsRedundantFilter
基于文本的嵌入向量進行計算,能夠從語義層面理解文本的相似性,更準確地識別真正的冗余信息,即使文本的表述方式有所不同。 -
高效性:借助現代的向量計算庫和優化算法,計算文本向量相似度的過程可以高效地進行,能夠處理大規模的文本數據,滿足實時性要求較高的應用場景。
-
-
局限
-
閾值設定的主觀性:確定文本是否冗余的相似度閾值通常需要人工設定,這在一定程度上具有主觀性。不同的應用場景和數據特點可能需要不同的閾值,不合適的閾值可能導致過濾效果不佳,要么過濾掉過多有用信息,要么保留了過多冗余信息。
-
對嵌入模型的依賴:其性能高度依賴于所使用的嵌入模型的質量和適用性。如果嵌入模型不能很好地捕捉文本的語義和句法信息,或者與具體應用領域的文本特點不匹配,可能會導致對文本相似性的判斷不準確,進而影響冗余過濾的效果。
-
無法處理復雜語義關系:盡管嵌入模型能夠捕捉一定的語義信息,但對于一些復雜的語義關系和上下文依賴的文本理解,仍然存在局限性。例如,對于具有隱喻、反諷等修辭手法的文本,或者在特定領域中具有特殊含義的術語,可能無法準確判斷其與其他文本的冗余關系。
-
代碼示例
from langchain.retrievers.document_compressors import DocumentCompressorPipeline
from langchain_community.document_transformers import EmbeddingsRedundantFilter# 默認文檔間相似度超過0.95則為冗余文檔
redundant_filter = EmbeddingsRedundantFilter(embeddings=embeddings_model, similarity_threshold=0.95)# 根據問題與文檔的相似度過濾
relevant_filter = EmbeddingsFilter(embeddings=embeddings_model, similarity_threshold=0.66)# Transformers轉換器 與 compressor壓縮器結合
'''
1、通過EmbeddingsRedundantFilter過濾冗余文檔
2、通過EmbeddingsFilter過濾與問題相似度低于0.66的文檔
'''
pipeline_compressor = DocumentCompressorPipeline(transformers=[redundant_filter, relevant_filter]
)compression_retriever = ContextualCompressionRetriever(base_compressor=pipeline_compressor, base_retriever=retriever
)compressed_docs = compression_retriever.invoke("deepseek的發展歷程"
)print("-------------------DocumentCompressorPipeline壓縮后--------------------------")
pretty_print_docs(compressed_docs)
-
EmbeddingsRedundantFilter:創建冗余文檔過濾器。它使用?
embeddings_model
?將文檔轉換為向量表示,并通過計算向量間的相似度來判斷文檔是否冗余。similarity_threshold=0.95
?表示當兩個文檔向量的相似度超過 0.95 時,就認為這兩個文檔是冗余的,其中一個文檔會被過濾掉。 -
EmbeddingsFilter:向量過濾器。
同樣使用?embeddings_model
?將文檔和查詢問題轉換為向量表示。similarity_threshold=0.66
?表示只有當文檔向量與查詢問題向量的相似度超過 0.66 時,該文檔才會被保留,否則會被過濾掉。 -
DocumentCompressorPipeline
?:文檔壓縮管道。將?redundant_filter
?和?relevant_filter
?組合成一個處理管道。在處理文檔時,會先使用?redundant_filter
?過濾掉冗余文檔,再使用?relevant_filter
?過濾掉與查詢問題相似度低于 0.66 的文檔。
總結
壓縮器 | 說明 |
---|---|
LLMChainExtractor | 通過 LLM 根據用戶查詢提取檢索的文檔內容。 |
LLMChainFilter | 通過 LLM 根據用戶查詢過濾檢索的文檔 |
EmbeddingsFilter | 通過向量模型根據用戶查詢計算文檔與問題相似度,過濾低于指定閾值的文檔 |
EmbeddingsRedundantFilter | 通過向量模型根據用戶查詢計算檢索文檔之間的相似度,過濾高于閾值的文檔 |