构建RAG应用

news2024/6/29 8:43:55

构建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.coloradmin.cn/o/1866998.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构初阶】--- 归并排序

归并排序 递归递归的思路归并的步骤:代码示例 非递归快排为什么可以用栈模拟:归并可以用栈模拟吗?非递归的思路初版代码示例问题:越界 时间复杂度针对递归的优化小区间优化 递归 递归的思路 归并的前提是需要两个有序的区间&…

LLM大模型算法学习资源持续整理

文章目录 waytoagiLLM101llm-coursellm-cookbook waytoagi 飞书文档写的AGI知识库。 https://www.waytoagi.com/ LLM101 karpathy更新中的大模型教程: https://github.com/karpathy/LLM101n llm-course Course to get into Large Language Models (LLMs) wi…

【前端】实现时钟网页

【前端】实现时钟网页 文章目录 【前端】实现时钟网页项目介绍代码效果图 项目介绍 时钟显示在网页中央,并且使网页能够切换白天和夜晚两种模式。搭建基本的html结构,动态得到实时的时,分,秒 通过Date()函数获得。将得到的数字根…

单片机学习记录

一,单片机及开发板介绍 1,基本介绍 单片机,英文Micro Controller Unit,简称MCU内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能单片机的任务是信息采集(依靠传感器)、处理(依靠CPU)和硬件设备(…

SpringBoot整合拦截器和日期转换器

一、SpringBoot整合拦截器 1.添加拦截器 package com.by.interceptor;import com.by.pojo.User; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest; import java…

程序员如何用ChatGPT解决常见编程问题:实例解析

引言 在现代编程的世界中,技术进步日新月异,程序员们面临着各种各样的挑战和问题。解决这些问题的过程中,找到合适的工具至关重要。ChatGPT作为一种先进的人工智能语言模型,能够帮助程序员迅速、高效地解决常见的编程问题。本文将…

【Liunx-后端开发软件安装】Liunx安装FDFS并整合nginx

【Liunx-后端开发软件安装】Liunx安装nacos 文章中涉及的相关fdfs相关软件安装包请点击下载: https://download.csdn.net/download/weixin_49051190/89471122 一、简介 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括…

揭秘循环购模式:消费即投资,边消费边赚钱!

大家好,我是你们的电商顾问吴军。今天,我将带大家走进一个引人瞩目的商业模式——循环购模式。你可能会好奇,为何有商家能如此慷慨,消费1000元就送2000元?每天还有额外的现金收入?这背后究竟隐藏着怎样的秘…

Cadence计算器函数leafValue

与getData结合使用 leafValue( getData(“/output” ?result “dc”) 转自eetop https://bbs.eetop.cn/thread-931912-1-1.html

20240627 每日AI必读资讯

🔍挑战英伟达!00 后哈佛辍学小哥研发史上最快 AI 芯片 - 3名大学辍学生创立、目前仅35 名员工、刚筹集1.2 亿美元的团队:Etched。 - 史上最快Transformer芯片诞生了! - 用Sohu跑Llama 70B,推理性能已超B200十倍&…

让AI保持怪异

让AI保持怪异 Anthropic的创意技术专家和员工设计师凯尔图尔曼(Kyle Turman)分享了一种深深引起共鸣的观点。他说(转述原话):“人工智能实际上真的很奇怪,我认为人们对这一点的认识还不够。”这引发了我向小组提出的问题:我们是否有消毒人工智能固有的陌生感的风险?…

办公软件汇总

1、OCR 1.1 pearOCR pearOCR 是一个免费的免费在线文字提取OCR工具网站。PearOCR界面简洁,所有过程均在网页端完成,无需下载任何软件,点开即用。官方地址:https://pearocr.com/ 参考:9款文字识别(OCR)工具…

魔众一物一码溯源防伪系统——守护品牌,守护信任!

在这个充满竞争的市场上,如何确保你的产品不被仿冒,如何赢得消费者的信任?魔众一物一码溯源防伪系统,为你提供一站式解决方案,守护你的品牌,守护消费者的信任! 🔍魔众一物一码溯源防…

玩机进阶教程----MTK芯片使用Maui META修复基带 改写参数详细教程步骤解析

目前mtk芯片与高通芯片在主流机型 上使用比较普遍。但有时候版本更新或者误檫除分区等等原因会导致手机基带和串码丢失的故障。mtk芯片区别与高通。在早期mtk芯片中可以使用工具SN_Writer_Tool读写参数。但一些新版本机型兼容性不太好。今天使用另外一款工具来演示mtk芯片改写参…

企业如何通过数据资产入表与融资加速数字化转型

数据作为五大生产要素之一,是数字经济发展的基础。如何对数据资产进行确权、核算和变现,已成为数字经济时代的难点和热点。随着“数据资产入表”的提出与实践,这一领域迎来了新的变化与机遇。 一、什么是数据资产入表 在我国,数据…

【第2章】MyBatis-Plus代码生成器

文章目录 前言一、安装二、生成方式1.DefaultQuery (元数据查询)2.存在问题 三、快速生成1. 生成代码2. 目录结构 四、交互式总结 前言 全新的 MyBatis-Plus 代码生成器,通过 builder 模式可以快速生成你想要的代码,快速且优雅,跟随下面的代…

JetBrains Rider 2024安装教程

一、下载Rider 1、进入官网,点击“下载” 2、下载完毕 二、安装Rider 1、双击下载的exe文件 2、点击“下一步” 3、可以点击“浏览”选择安装路径,之后点击“下一步” 4、选中图中四项,点击“下一步” 5、选中图中四项,点击“下…

mysql自动填写当前时间,添加索引

mysql自动填写当前时间 在navicat操作界面创建表时,如果需要自动填写时间,可以操作如下 CURRENT_TIMESTAMP为表添加索引 ALTER table tableName ADD INDEX indexName(columnName)追加外键 ALTER TABLE tb_commentPhoto ADD CONSTRAINT FK_comment_ph…

什么是Arkose Labs挑战及其解决方法

Arkose Labs挑战是一种复杂的机制,旨在验证用户是真正的人类,而不是自动化的机器人或脚本。这一挑战在维护在线服务的安全性和完整性方面发挥着关键作用,通过防止欺诈活动并确保只有真实用户才能访问某些功能。 目录 什么是Arkose Labs挑战&a…

机械拆装-基于Unity-准备零件

目录 前言 1. 装配体模型的准备(STEP格式保存为零件) 1.1 关于不停提示“默认模板无效” 1.2 关于无法保存单个零件的解决 2. 整理装配体与零件 2.1 零件命名规则 2.2 建立子装配体 3. 装配体和零件转换格式 3.1 3DMax单位设置 3.2 装配体转换 3.3…