构建RAG应用

构建RAG应用

  • 1.加载向量数据库
  • 2.测试向量库检索答案
  • 3.langchain中的gpt做为llm
  • 4.检索问答框架【向量库+llm】
  • 5.保留回话历史
  • 6.根据会话记忆进行回复
  • 7.汇总

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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/746256.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu20.04安装python2和python3及版本配置

Ubuntu20.04安装python2和python3及版本配置_ubuntu 20.04 python3-CSDN博客https://blog.csdn.net/pangc2014/article/details/117407413 >>>ubuntu 安装源码python2_mob649e8161c39d的技术博客_51CTO博客https://blog.51cto.com/u_16175489/7327966

【Academy】测试WebSockets安全漏洞Testing for WebSockets security vulnerabilities

测试WebSockets安全漏洞Testing for WebSockets security vulnerabilities 概述WebSockets是什么?HTTP和WebSockets有什么区别?如何建立WebSocket连接?WebSocket消息看起来像什么? 操纵WebSocket流量拦截和修改WebSocket消息重放和生成新的W…

ONLYOFFICE 8.1:引领桌面办公新潮流,功能升级全面提升

目录 一、ONLYOFFICE是什么? 二、功能完善的PDF编辑器 三、幻灯片版式升级 四、改进从右至左显示 五、新的本地化选项 六、多媒体功能增强 七、应用价值探讨 一、ONLYOFFICE是什么? ONLYOFFICE 是一款功能强大的办公套件,旨在提供全面…

什么是云服务器镜像,如何选择?

云服务器镜像是一种用于业务连续性、灾难恢复和备份的技术手段,其本质是云端创建的服务器数据副本。 这些镜像内容可以涵盖系统、光盘、软件、网站甚至整个服务器,主要用于创建容错和冗余服务器计算基础架构,为用户提供了一个方便且可靠的解…

YOLOv8改进 | 注意力机制 | 轻量级的空间组增强模块SGE【全网独家】

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录:《YOLOv8改进有效涨…

python项目运营时,出现,redis用户密码未设置问题,排查解决

一、问题描述: 在本地化开发过程中,pythonDjango运行项目,redis为本地windows版本,在设置过密码后,仍然会出现pythonDjango运行项目,终端日志显示如下: INFO info信息 ERROR redis数据库异常[&…

内网安全【4】SSH隧道技术

1.四大隧道协议 (1)SMB协议 判断:445端口是否开放 (2)ICMP协议 判断:ping命令能通说明使用icmp协议 (3)DNS协议 判断:nslookup www.baidu.com 属于UDP iodine工作原理是 ,通过TAP虚拟网卡,在服…

大厂面试经验分享,小白如何在面试中脱颖而出

前言 毕业季,对于每一位即将步入社会的学子来说,都是一个充满挑战和机遇的时刻。作为我的一位好朋友也是好学长,他刚刚在一家顶尖科技公司斩获了他梦寐以求的职位。他深知求职路上的艰辛,因此打算把自己的经验分享给大家&#xf…

一键掌握多渠道推广效果!Xinstall超级渠道功能,让你的App推广更高效

在App运营的大潮中,如何高效、精准地推广App,成为每一位运营者关注的焦点。传统的推广方式,如地推、代理、分销、广告等,虽然能够带来一定的用户增长,但如何衡量推广效果、如何与合作伙伴结算、如何管理下属渠道等问题…

Java程序递归及mybatis递归查询

之前项目组有个需求,定时同步机构的信息。已知三方接口由于返回数据量很大,所以最后需要三方提供一个可根据机构编号获取当前机构及子机构信息的接口。而不是一次性返回全部机构信息! 由于这次需求也用到了递归,所以记录下&#…

2024.6.26 刷题总结

2024.6.26 **每日一题** 526.优美的排列,该题考察的是状压dp的知识,用一个n位的二进制数表示排列中的数被选取的情况,若为1,则表示该位被选取,若为0,则表示该位没有被选取,用一个数组来存储当前…

【Vue】集成富文本编辑器

这文章使用的是wangeditor插件&#xff0c;官网地址&#xff1a;wangEditor&#xff0c;这个比较简单 安装 npm i wangeditor --save 使用 <div id"editor"></div>import E from "wangeditor"const editor new E("#editor") e…

兰州市红古区市场监管管理局调研食家巷品牌,关注细节,推动进步

近日&#xff0c;兰州市红古区市场监管管理局临平凉西北绿源电子商务有限公司进行了深入视察&#xff0c;为企业发展带来了关怀与指导。 食家巷品牌作为平凉地区特色美食的代表之一&#xff0c;一直以来凭借其纯手工工艺和独特的风味&#xff0c;在市场上占据了一席之地。领导…

charls抓包工具 mumu模拟器抓包apk

1.先安装mumu 官网添加链接描述 2.配置 设置&#xff0c;点进互联网&#xff0c;点编辑&#xff0c;选择手动代理 主机名写自己电脑的ip地址&#xff0c;端口随便&#xff0c;只要不被占用&#xff0c;一般参考其他人都是8888 3.下载charls 参考这个添加链接描述 先官网…

一文详解:什么是企业邮箱?最全百科

什么是企业邮箱&#xff1f;企业邮箱即绑定企业自有域名作为邮箱后缀的邮箱&#xff0c;是企业用于内部成员沟通和客户沟通的邮箱系统。 一、企业邮箱概念拆解 1.什么是企业邮箱&#xff1f; 企业邮箱即使用企业域名作为后缀的邮箱系统。它不仅提供专业的电子邮件收发功能&a…

How to persist LangChain conversation memory (save and load)

题意&#xff1a;如何持久化 LangChain 对话记忆&#xff08;保存和加载&#xff09; 问题背景&#xff1a; Im creating a conversation like so: 我正在创建一个对话&#xff0c;如下所示&#xff1a; llm ChatOpenAI(temperature0, openai_api_keyOPENAI_API_KEY,…

大学生毕业季,寄物流快递避雷指南

随着毕业季的来临&#xff0c;大学生们纷纷开始整理自己的行李&#xff0c;准备离开校园&#xff0c;踏入社会。 在这个过程中&#xff0c;寄送快递成为了一个不可或缺的环节。然而&#xff0c;在寄送快递的过程中&#xff0c;如果不注意一些细节&#xff0c;很容易遭遇各种“…

【别再用Excel了!】这款免费可视化工具能帮你轻松提升效率

现代数据分析和展示的需求已经远远超出了传统工具的能力&#xff0c;尤其是在需要快速、直观和高效地处理复杂数据的情况下。山海鲸可视化通过其强大的功能和易用性&#xff0c;成为了设计师以及各类新手用户的理想选择。下面我就以一个可视化设计师的角度&#xff0c;和大家简…

金升阳电源被制裁,广州顶源电源模块可以完美替换

广州顶源电子科技股份有限公司,座落于国家高新技术开发区---广州科学城&#xff0c;是一家集研发、生产、销售及服务于一体的DC-DC&#xff0c;AC-DC电源的生产厂家。 公司通过了IATF16949汽车认证及ISO9001:2015质量管理体系认证。拥有专家级研发团队&#xff0c;产品研发经过…

Python中20个鲜为人知的字符串函数

目录 1. capitalize() 2. casefold() 3. join() 和 split() 4. strip(), lstrip(), rstrip() 5. replace() 6. format() 7. enumerate() 8. isalpha(), isdigit(), isalnum() 9. startswith(), endswith() 10. center() 11. count() 12. find(), index() 13. make…