凉城老泉
手机扫码
十.LangChian实验笔记,选择适当的向量检索器、逐步优化检索结果
凉城老泉  2025-05-28     阅读(57)   分享

我们用一个示例来记录多种向量检索方法的使用,在实际使用中我们根据具体情况来作出选择:

分别是:简单检索器、多轮查询检索器、上下文件压缩检索器、最大边界相似性检索器、相似度打分检索器

以下是具体实现代码:

一.引入需要的包

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)