我们用一个示例来记录多种向量检索方法的使用,在实际使用中我们根据具体情况来作出选择:
分别是:简单检索器、多轮查询检索器、上下文件压缩检索器、最大边界相似性检索器、相似度打分检索器
以下是具体实现代码:
一.引入需要的包
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)