我们用一个示例来记录多种向量检索方法的使用,在实际使用中我们根据具体情况来作出选择:
分别是:简单检索器、多轮查询检索器、上下文件压缩检索器、最大边界相似性检索器、相似度打分检索器
以下是具体实现代码:
一.引入需要的包
from langchain.document_loaders import Docx2txtLoader from langchain.text_splitter import RecursiveCharacterTextSplitter,CharacterTextSplitter from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Chroma from langchain.retrievers import MultiQueryRetriever,ContextualCompressionRetriever from langchain.retrievers.document_compressors import LLMChainExtractor from lc_deepseek_ai import CreateChartDeepSeek二.定义一个类吧,这个类主要实现对一篇画展文档内容进行查询
class AnyDoc():三.构造器、和文档加载方法
'''加载一篇文档、文档是关于举办画展活动的培训手册,我们用不同的检索器来查询文档内容'''
class AnyDoc():
def __init__(self):
self.data=None
self.split_texts=[]
def get_doc(self,file_path):
loader = Docx2txtLoader(file_path)
self.data = loader.load()
return self.data
四.分割文档并将数据向量化,这里用到开源向量嵌入模型,下载到本地后对文档进行分词,向量库使用Chroma DB
def split_doc(self):
if self.data:
text_splitter = CharacterTextSplitter(
chunk_size=200,
chunk_overlap=40
)
texts = text_splitter.split_documents(self.data)
self.split_texts = texts
else:
print("请先加载文档")
def get_embeddings(self):
embeddings = HuggingFaceEmbeddings(model_name='../models/BAAI_bge-small-zh-v1.5')
vector_db = Chroma.from_documents(documents=self.split_texts, embedding=embeddings)
return vector_db
五.下面是不同检索器的使用方法
'''最简单的检索器'''
def ask(self,query):
vector_db = self.get_embeddings()
return vector_db.as_retriever().get_relevant_documents(query)
'''多轮查询检索器'''
def ask_MultiQuery(self,query):
vector_db = self.get_embeddings()
llm=CreateChartDeepSeek()
retriever_from_llm = MultiQueryRetriever.from_llm(
retriever=vector_db.as_retriever(),
llm=llm
)
return retriever_from_llm.get_relevant_documents(query)
'''上下文压缩检索器'''
def ask_ContextualCompressionRetriever(self,query):
vector_db = self.get_embeddings()
llm=CreateChartDeepSeek()
compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=vector_db.as_retriever()
)
return compression_retriever.get_relevant_documents(query)
'''最大边界相似性检索器'''
def ask_mmr(self,query):
vector_db = self.get_embeddings()
ret=vector_db.as_retriever(searth_type="mmr")
#ret=vector_db.max_marginal_relevance_search(query,k=4)
res=ret.get_relevant_documents(query)
return res
'''相似度打分检索器'''
def ask_similarity_search(self,query,k=4):
vector_db = self.get_embeddings()
#ret=vector_db.as_retriever(searth_type="similarity_score_threshold",search_kwargs={"k":1,"score_threshold":0.5})
ret=vector_db.similarity_search_with_score(query,k=2)
return ret.get_relevant_documents(query)
六. 最后我们来测试一下,对比哪一种更优
if __name__ == "__main__":
file_path = "d:\\datas\\4.2活动志愿者培训.docx"
doc = AnyDoc()
data = doc.get_doc(file_path)
doc.split_doc()
res=doc.ask_MultiQuery("作者是谁?")
print(res)
res1=doc.ask_ContextualCompressionRetriever("作者是谁?")
print(res1)
res2=doc.ask_mmr("作者是谁?")
print(res2)
res3=doc.ask_similarity_search("作者是谁?")
print(res3)