构建RAG应用

1.加载向量数据库

如何将数据保存为本地向量库参考上一篇: 基于LangChain框架搭建知识库

    def load_vector_db(self):
        """加载向量数据库"""
        from langchain.vectorstores.chroma import Chroma
        from langchain_openai import OpenAIEmbeddings

        embedding = OpenAIEmbeddings(model="text-embedding-3-small",
                                     openai_api_key=self.api_key,
                                     http_client=self.http_client)
        # 加载数据库
        vectordb = Chroma(
            persist_directory=self.persist_directory,  # 允许我们将persist_directory目录保存到磁盘上
            embedding_function=embedding
        )
        print(f"向量库中存储的数量:{vectordb._collection.count()}")
        return vectordb

2.测试向量库检索答案

    def search_txt(self):
        """测试向量库检索问答"""
        vectordb = self.load_vector_db()
        question = "什么是机器学习"
        docs = vectordb.similarity_search(question, k=2)
        print(f"检索到的内容数:{len(docs)}")

        for i, doc in enumerate(docs):
            print(f"检索到的第{i}个内容: \n {doc.page_content}",
                  end="\n-----------------------------------------------------\n")

3.langchain中的gpt做为llm

    def langchain_gpt(self):
        from langchain_openai import ChatOpenAI
        llm = ChatOpenAI(model_name="gpt-4o", temperature=0)
        # data = llm.invoke("请你自我介绍一下自己!")
        # print(data)
        return llm

4.检索问答框架【向量库+llm】

    def llm_response(self):
        """根据向量知识库+llm 检索问答"""
        from langchain.prompts import PromptTemplate
        llm = self.langchain_gpt()
        vectordb = self.load_vector_db()

        template = """使用以下上下文来回答最后的问题。如果你不知道答案,就说你不知道,不要试图编造答
        案。最多使用三句话。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问!”。
        {context}
        问题: {question}
        """

        QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context", "question"], template=template)

        # 基于模版的检索链
        from langchain.chains import RetrievalQA
        qa_chain = RetrievalQA.from_chain_type(llm,
                                               retriever=vectordb.as_retriever(),
                                               return_source_documents=True,
                                               chain_type_kwargs={"prompt": QA_CHAIN_PROMPT})
        question_1 = "什么是南瓜书?"
        question_2 = "王阳明是谁?"

        result = qa_chain({"query": question_1})
        print("大模型+知识库后回答 question_1 的结果:")
        print(result["result"])
        # 南瓜书是一本由Datawhale编委会编写的书籍,主要内容尚未明确,但可以通过在线阅读地址和PDF获取地址进行阅读。它采用知识共享署名-非商业性使用-相同方式共享4.0 国际许可协议进行许可。谢谢你的提问!

        result = qa_chain({"query": question_2})
        print("大模型+知识库后回答 question_2 的结果:")
        print(result["result"])
        # 我不知道王阳明是谁。谢谢你的提问!

        prompt_template = """请回答下列问题:
                                    {}""".format(question_1)

        ### 基于大模型的问答
        res = llm.predict(prompt_template)
        print(f'llm回答question1:{res}')

        prompt_template = """请回答下列问题:
                                    {}""".format(question_2)

        ### 基于大模型的问答
        res = llm.predict(prompt_template)
        print(f'llm回答question2:{res}')

5.保留回话历史

    def memory_chain(self):
        """保留会话记忆"""
        from langchain.memory import ConversationBufferMemory

        memory = ConversationBufferMemory(
            memory_key="chat_history",  # 与 prompt 的输入变量保持一致。
            return_messages=True  # 将以消息列表的形式返回聊天记录,而不是单个字符串
        )
        return memory

6.根据会话记忆进行回复

    def history_chain(self):
        """根据会话记忆进行问答"""
        from langchain.chains import ConversationalRetrievalChain
        vectordb = self.load_vector_db()
        llm = self.langchain_gpt()
        memory = self.memory_chain()

        retriever = vectordb.as_retriever()

        qa = ConversationalRetrievalChain.from_llm(
            llm,
            retriever=retriever,
            memory=memory
        )
        # 第一次提问后注释掉
        # question = "什么是南瓜书?"
        # result = qa({"question": question})
        # print(result['answer'])

        # 第二次提问,根据上次提问内容进行继续回答
        question = "我应该怎么学习南瓜书"
        result = qa({"question": question})
        print(result['answer'])

7.汇总

import os
from dotenv import load_dotenv, find_dotenv
from openai import OpenAI
import httpx


class RAG:
    def __init__(self):
        _ = load_dotenv(find_dotenv())
        # 获取openai key
        self.api_key = os.environ.get("OPENAI_API_KEY")
        #  本地向量数据库持久化路径
        self.persist_directory = './vector_db/chroma'
        # 设置代理地址
        self.proxy = 'http://127.0.0.1:7890'
        os.environ["HTTPS_PROXY"] = self.proxy
        os.environ["HTTP_PROXY"] = self.proxy

    def load_vector_db(self):
        """加载向量数据库"""
        from langchain.vectorstores.chroma import Chroma
        from langchain_openai import OpenAIEmbeddings

        embedding = OpenAIEmbeddings(model="text-embedding-3-small",
                                     openai_api_key=self.api_key,
                                     http_client=self.http_client)
        # 加载数据库
        vectordb = Chroma(
            persist_directory=self.persist_directory,  # 允许我们将persist_directory目录保存到磁盘上
            embedding_function=embedding
        )
        print(f"向量库中存储的数量:{vectordb._collection.count()}")
        return vectordb

    def search_txt(self):
        """测试向量库检索问答"""
        vectordb = self.load_vector_db()
        question = "什么是机器学习"
        docs = vectordb.similarity_search(question, k=2)
        print(f"检索到的内容数:{len(docs)}")

        for i, doc in enumerate(docs):
            print(f"检索到的第{i}个内容: \n {doc.page_content}",
                  end="\n-----------------------------------------------------\n")

    def langchain_gpt(self):
        from langchain_openai import ChatOpenAI
        llm = ChatOpenAI(model_name="gpt-4o", temperature=0)
        # data = llm.invoke("请你自我介绍一下自己!")
        # print(data)
        return llm

    def llm_response(self):
        """根据向量知识库+llm 检索问答"""
        from langchain.prompts import PromptTemplate
        llm = self.langchain_gpt()
        vectordb = self.load_vector_db()

        template = """使用以下上下文来回答最后的问题。如果你不知道答案,就说你不知道,不要试图编造答
        案。最多使用三句话。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问!”。
        {context}
        问题: {question}
        """

        QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context", "question"], template=template)

        # 基于模版的检索链
        from langchain.chains import RetrievalQA
        qa_chain = RetrievalQA.from_chain_type(llm,
                                               retriever=vectordb.as_retriever(),
                                               return_source_documents=True,
                                               chain_type_kwargs={"prompt": QA_CHAIN_PROMPT})
        question_1 = "什么是南瓜书?"
        question_2 = "王阳明是谁?"

        result = qa_chain({"query": question_1})
        print("大模型+知识库后回答 question_1 的结果:")
        print(result["result"])
        # 南瓜书是一本由Datawhale编委会编写的书籍,主要内容尚未明确,但可以通过在线阅读地址和PDF获取地址进行阅读。它采用知识共享署名-非商业性使用-相同方式共享4.0 国际许可协议进行许可。谢谢你的提问!

        result = qa_chain({"query": question_2})
        print("大模型+知识库后回答 question_2 的结果:")
        print(result["result"])
        # 我不知道王阳明是谁。谢谢你的提问!

        prompt_template = """请回答下列问题:
                                    {}""".format(question_1)

        ### 基于大模型的问答
        res = llm.predict(prompt_template)
        print(f'llm回答question1:{res}')

        prompt_template = """请回答下列问题:
                                    {}""".format(question_2)

        ### 基于大模型的问答
        res = llm.predict(prompt_template)
        print(f'llm回答question2:{res}')

    def memory_chain(self):
        """保留会话记忆"""
        from langchain.memory import ConversationBufferMemory

        memory = ConversationBufferMemory(
            memory_key="chat_history",  # 与 prompt 的输入变量保持一致。
            return_messages=True  # 将以消息列表的形式返回聊天记录,而不是单个字符串
        )
        return memory

    def history_chain(self):
        """根据会话记忆进行问答"""
        from langchain.chains import ConversationalRetrievalChain
        vectordb = self.load_vector_db()
        llm = self.langchain_gpt()
        memory = self.memory_chain()

        retriever = vectordb.as_retriever()

        qa = ConversationalRetrievalChain.from_llm(
            llm,
            retriever=retriever,
            memory=memory
        )
        # 第一次提问后注释掉
        # question = "什么是南瓜书?"
        # result = qa({"question": question})
        # print(result['answer'])

        # 第二次提问,根据上次提问内容进行继续回答
        question = "我应该怎么学习南瓜书"
        result = qa({"question": question})
        print(result['answer'])


if __name__ == '__main__':
    rag = RAG()
    # 基于向量库+llm进行检索问答
    # rag.llm_response()
    # 基于llm+历史会话记忆进行问答
    rag.history_chain()

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值