2、LangChain —— RAG基本架构

news2024/11/15 12:41:12

文章目录

  • 一、概述
  • 二、什么是 RAG
  • 三、概念
    • 1、Indexing
    • 2、Retrieval and generation
  • 四、设置
    • 1、下载安装 langchain
    • 2、LangSmith
  • 五、一个简单的RAG后端
    • 1、Load
    • 2、Split
    • 3、Embedding and Store
    • 4、Retrieval
    • 5、Generate


一、概述

 LLM 支持的最强大的应用程序之一是 复杂的问答 (Q&A) 聊天机器人。这些应用程序可以回答有关特定源信息的问题。这些应用程序使用一种称为 检索增强生成 (RAG) 的技术。

 这里将展示如何 基于文本数据源 构建一个简单的问答应用程序。在此过程中,我们将介绍典型的问答架构,并重点介绍更多高级问答技术的资源。

 我们还将了解 LangSmith 如何帮助我们跟踪和理解我们的应用程序。随着我们的应用程序变得越来越复杂,LangSmith 将变得越来越有用。


二、什么是 RAG

 RAG 是一种利用附加数据增强 LLM 知识的技术。
 LLM 可以推理广泛的主题,但他们的知识 仅限于 他们接受训练的 特定时间点公共数据。如果想构建能够推理 私有数据模型截止日期后引入的数据 的 AI 应用程序,则需要使用模型所需的特定信息来增强模型的知识。将适当的信息引入模型提示的过程称为 检索增强生成 (RAG)
 LangChain 有许多组件,旨在帮助构建问答应用程序以及更广泛的 RAG 应用程序。

 注意:这里重点介绍非结构化数据的问答。如果您对结构化数据的 RAG 感兴趣,请查看 关于通过 SQL 数据进行问答的教程。


三、概念

 一个典型的 RAG 应用包含两个主要的部分:

  • Indexing (索引):从源中提取数据并对其进行索引的管道。这通常是离线进行的。
  • Retrieval 和 generation (检索和生成):实际的 RAG 链,它在运行时接受用户查询并从索引中检索相关数据,然后将其传递给模型。

从原始数据到答案的最常见完整序列如下所示:
在这里插入图片描述
在这里插入图片描述

1、Indexing

  1. Load (加载):首先我们需要加载数据。这可以通过 DocumentLoaders 完成。
  2. Split (拆分)Text splitters 文本拆分器 将大型文档拆分成较小的块。这对于索引数据和将其传递给模型都很有用,因为大块数据更难搜索,并且不适合模型的有限上下文窗口。
  3. Store (存储):我们需要一个地方来存储和索引我们的拆分,以便以后可以搜索它们。这通常使用 VectorStoreEmbeddings 模型来完成。

2、Retrieval and generation

  1. Retrieval (检索):给定用户输入,使用检索器从存储中检索相关分割。
  2. Generation (生成)ChatModel/LLM 使用 包含问题和检索到的数据的 提示 生成 答案

四、设置

1、下载安装 langchain

 要安装 LangChain,请运行:

pip install langchain # 在python 中

2、LangSmith

 点击跳转至 LangSmith 的使用教程


五、一个简单的RAG后端

1、Load

 我们首先用 LangChain 中的 document_loaders 来加载各种格式的文本文件。这些文件 (也就是我们的私有知识库) 我放在了 documents 这个目录中,如果你创建自己的文件夹,就要调整一下代码中的目录。
 在这一步中,我们从 pdf、word 和 txt 文件中加载文本,然后将这些文本存储在一个列表中。(注意:可能需要安装 PyPDF、Docx2txt 等库)

import os
os.environ["OPENAI_API_KEY"] = '你的Open AI API Key'

# 1.Load 导入Document Loaders
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import Docx2txtLoader
from langchain.document_loaders import TextLoader

# 加载Documents
base_dir = '.\documents' # 文档的存放目录
documents = []
for file in os.listdir(base_dir): 
    # 构建完整的文件路径
    file_path = os.path.join(base_dir, file)
    if file.endswith('.pdf'):
        loader = PyPDFLoader(file_path)
        documents.extend(loader.load())
    elif file.endswith('.docx'): 
        loader = Docx2txtLoader(file_path)
        documents.extend(loader.load())
    elif file.endswith('.txt'):
        loader = TextLoader(file_path)
        documents.extend(loader.load())

2、Split

 接下来需要将加载的文本分割成更小的块,以便进行嵌入和向量存储。这个步骤中,我们使用 LangChain 中的 RecursiveCharacterTextSplitter 来分割文本。

# 2.Split 将Documents切分成块以便后续进行嵌入和向量存储
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10)

chunked_documents = text_splitter.split_documents(documents)

3、Embedding and Store

 紧接着,我们将这些分割后的文本转换成嵌入的形式,并将其存储在一个向量数据库中。在这个例子中,我们使用了 OpenAIEmbeddings 来生成嵌入,然后使用 Qdrant 这个向量数据库来存储嵌入 (这里需要 pip install qdrant-client)。
 向量数据库有很多种,比如 Pinecone、Chroma 和 Qdrant,有些是收费的,有些则是开源的。如果要使用其他的 向量数据库,最好去其官网看看文档中关于参数的说明

# 3.Store 将分割嵌入并存储在矢量数据库Qdrant中
from langchain.vectorstores import Qdrant
from langchain.embeddings import OpenAIEmbeddings

vectorstore = Qdrant.from_documents(
    documents=chunked_documents, # 以分块的文档
    embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入
    location=":memory:",  # in-memory 存储
    collection_name="my_documents",  # 指定collection_name
)

4、Retrieval

 当内部文档存储到向量数据库之后,我们需要根据问题和任务来提取最相关的信息。此时,信息提取的基本方式就是 把问题也转换为向量,然后去和向量数据库中的各个向量进行比较,提取最接近的信息
 向量之间的比较通常基于向量的距离或者相似度。在高维空间中,常用的向量距离或相似度计算方法有 欧氏距离余弦相似度

  • 欧氏距离,这是最直接的距离度量方式,就像在二维平面上测量两点之间的直线距离那样。在高维空间中,两个向量的欧氏距离就是 各个对应维度差的平方和的平方根
  • 余弦相似度,在很多情况下,我们更关心向量的方向而不是它的大小。例如在文本处理中,一个词的向量可能会因为文本长度的不同,而在大小上有很大的差距,但方向更能反映其语义。余弦相似度就是度量 向量之间方向的相似性,它的值范围在 -1 到 1 之间,值越接近 1,表示两个向量的方向越相似

 这两种方法都被广泛应用于各种机器学习和人工智能任务中,选择哪一种方法取决于具体的应用场景。

 在这一步的代码部分,我们会创建一个聊天模型。然后需要创建一个 RetrievalQA 链,它是一个检索式问答模型,用于生成问题的答案。在 RetrievalQA 链中有下面两大重要组成部分:

  • LLM 是大语言模型,负责回答问题。
  • retriever (vectorstore.as_retriever()), 负责根据问题检索相关的文档,找到具体的“嵌入片”。这些“嵌入片”对应的“文档块”就会作为知识信息,和问题一起传递进入大模型。本地文档中检索而得的知识很重要,因为从互联网信息中训练而来的大模型不可能知道某个组织的私有知识库。
# 4. Retrieval 准备模型和Retrieval链
import logging # 导入Logging工具
from langchain.chat_models import ChatOpenAI # ChatOpenAI模型
from langchain.retrievers.multi_query import MultiQueryRetriever # MultiQueryRetriever工具
from langchain.chains import RetrievalQA # RetrievalQA链

# 设置Logging
logging.basicConfig()
logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO)

# 实例化一个大模型工具 - OpenAI的GPT-3.5
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)

# 实例化一个MultiQueryRetriever
retriever_from_llm = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(), llm=llm)

# 实例化一个RetrievalQA链
qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever_from_llm)

 上面代码中,MultiQueryRetriever 是一个高级检索器,它使用多查询策略来增强信息检索的效果。一般的 retriever 是不需要 llm 的,但是可以看到 MultiQueryRetriever 的实例化过程中不但用到了 retriever 还用到了 llm。
 实际上,MultiQueryRetriever 使用语言模型生成多种查询,以提高信息检索的覆盖范围和准确性。

5、Generate

 这一步是问答系统应用的主要 UI 交互部分,这里会创建一个 Flask 应用来接收用户的问题,并生成相应的答案,最后通过 index.html 对答案进行渲染和呈现。
 在这个步骤中,我们使用了之前创建的 RetrievalQA 链来获取相关的文档和生成答案。然后,将这些信息返回给用户,显示在网页上。

# 5. Output 问答系统的UI实现
from flask import Flask, request, render_template
app = Flask(__name__) # Flask APP

@app.route('/', methods=['GET', 'POST'])
def home():
    if request.method == 'POST':

        # 接收用户输入作为问题
        question = request.form.get('question')        
        
        # RetrievalQA链 - 读入问题,生成答案
        result = qa_chain({"query": question})
        
        # 把大模型的回答结果返回网页进行渲染
        return render_template('index.html', result=result)
    
    return render_template('index.html')

if __name__ == "__main__":
    app.run(host='0.0.0.0',debug=True,port=5000)
<body>
    <div class="container">
        <div class="header">
            <h1>一个简单的 RAG</h1>
            <img src="{{ url_for('static', filename='flower.png') }}" alt="flower logo" width="200"> 
        </div>
        <form method="POST">
            <label for="question">Enter your question:</label><br>
            <input type="text" id="question" name="question"><br>
            <input type="submit" value="Submit">
        </form>
        {% if result is defined %}
            <h2>Answer</h2>
            <p>{{ result.result }}</p>
        {% endif %}
    </div>
</body>

 最后跑起一个网页 http://127.0.0.1:5000/ 即可。最后的最后,给出一下项目的目录结构:
在这里插入图片描述

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

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

相关文章

MySQL中实现动态表单中JSON元素精准匹配的方法

目录 前言 一、动态表单技术 1、包含的主要信息 2、元素属性设置 3、表单内容 二、表单数据存储和查询 1、数据存储 2、数据的查询 3、在5.7版本中进行JSON检索 4、8.0后的优化查询 三、总结 前言 在很多有工作流设置的地方、比如需要在不同的流程中&#xff0c;需要…

【八股系列】JavaScript如何判断一个对象是否属于某个类?

&#x1f389; 博客主页&#xff1a;【剑九 六千里-CSDN博客】 &#x1f3a8; 上一篇文章&#xff1a;【探索扫描二维码登录的奥秘&#xff1a;从前端到后端的无缝连接】 &#x1f3a0; 系列专栏&#xff1a;【面试题-八股系列】 &#x1f496; 感谢大家点赞&#x1f44d;收藏⭐…

基于单片机控制的家电产品硬件故障诊断

摘要&#xff1a; 在现阶段家用电子产品生产制造的过程中&#xff0c;需要应用到非常多的单片机以及单片机控制技术&#xff0c;单片机凭借着自身体积小、反应快、功耗低的优势迅速抢占了家电产品的市场。并且在单片机实际的应用过程中&#xff0c;通过对单片机控制技术的掌握可…

HarmonyOS 本地真机运行

目录 官网地址 1.开发工具设置签名 2.手机开启开发者模式 3.使用USB连接方式 4.使用无线调试连接方式 5.常见的问题 官网地址 使用真机运行应用 使用本地真机运行应用/服务 1.开发工具设置签名 官网应用/服务签名 1.左上角文件--项目结构-勾选自动生成签名-Sign in登录 2…

【Vue3】watch 监视 reactive 定义的数据

【Vue3】watch 监视 reactive 定义的数据 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经…

Binius-based zkVM:为Polygon AggLayer开发、FPGA加速的zkVM

1. 引言 近日&#xff0c;ZK硬件加速巨头Irreducible和Polygon团队宣布联合开发生产级的Binius-based zkVM&#xff0c;用于助力Polygon AggLayer&#xff0c;实现具有低开销、硬件加速的binary proofs。 Irreducible&#xff08;曾用名为Ulvetanna&#xff09;团队 Benjamin …

如何在 Spring Boot 中开发一个操作日志系统

文章目录 前言添加依赖配置日志存储创建实体类创建仓库接口创建AOP切面配置日志级别测试日志系统 前言 在开发企业级应用时&#xff0c;记录用户操作日志是非常重要的。这不仅能帮助开发者监控系统的行为&#xff0c;还能在出现问题时进行追踪。在这篇文章中&#xff0c;我们将…

线性代数|机器学习-P25线性规划和两人零和博弈

文章目录 0. 概述1. 线性规划问题1.1 定义1.2 举例 2. 线性规划中的对偶问题3. 最大流 - 最小割问题4. 两人零和博弈 MIT教授教学视频&#xff0c;讲得比较泛&#xff0c;需要另外学习很多知识补充 0. 概述 线性规划[LP]问题 线性规划是问题为线性求最值&#xff0c;约束也是求…

前端调试合集(包含移动端/内嵌h5)

代码内使用方法 alert/console alert和console.log作为JS最基本的调试能力&#xff0c;提供了简易版的断点 (只能断一下) 和输出 (只能输出字符串) 能力&#xff0c;可以在代码运行到预期的位置输出预期的log&#xff0c;通过对不同流程下写入alert&#xff0c;输出变量的值来…

普元EOS学习笔记-EOS的ide开发工具的介绍

前言 普元EOS开发包括低开和高开。 EOS低开&#xff0c;直接在浏览器操作即可&#xff0c;不需要编码。 EOS高开&#xff0c;需要使用EOS的ide工具&#xff0c;进行编码开发。 EOS的ide工具是普元在Eclipse基础上进行的扩展&#xff0c;添加了若干插件&#xff0c;专门用于…

Redis 7.x 系列【29】集群原理之自动故障转移

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 案例演示3. 工作原理3.1 故障检测3.2 排名3.3 延迟等待3.4 投票3.5 上位 1.…

LeetCode:对称的二叉树(C语言)

1、问题概述&#xff1a;给一个二叉树&#xff0c;看是否按轴对称 2、示例 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 3、分析 &#xff08;1&a…

MATLAB和Python零模型社会生物生成式结构化图

&#x1f3af;要点&#x1f3af;要点&#x1f3af;启发式方法无标度和前馈拓扑的网络编码&#x1f3af;随机遗传模型使用布线规则&#x1f3af;随机遗传算法测试连接组模型&#x1f3af;确定性地生成分支树和分层网络&#xff0c;同质偏好规则的联系&#x1f3af;生成随机网络节…

无涯·问知财报解读,辅助更加明智的决策

财报解读就像是给公司做一次全面的体检&#xff0c;是理解公司内部运作机制和市场表现的一把钥匙&#xff0c;能够有效帮助投资者、分析师、管理层以及所有市场参与者判断一家公司的健康程度和发展潜力。 星环科技无涯问知的财经库内置了企业年报及财经类信息&#xff0c;并对…

GateWay网关微服务定位和理论知识

微服务架构的网关在哪里&#xff1f; 概念 SPring Cloud Gateway组件的核心是一系列的过滤器&#xff0c;通过这些过滤器可以将客户端发送的请求转发&#xff08;路由&#xff09;到对应的微服务。Spring Cloud Gateway是加在整个微服务最前沿的防火墙和代理器&#xff0c;隐藏…

linux离线安装mysql8(单机版)

文章目录 一、检查服务器是否有残留mysql资源&#xff0c;有的话就全删除1.1、查询mysql已安装的相关依赖&#xff1a;1.2、查找含有MySQL的目录 二、安装2.1、上传mysql安装包到文件夹下并解压2.2、移动及重命名2.3、mysql用户2.4、配置mysql所需的my.cnf文件2.5、给my.cnf配置…

基于单片机控制的红外热释电家庭防盗报警器硬件系统设计

【摘要】 随着社会的发展和人们安全意识的提高&#xff0c;传统的家庭防盗系统不能适应现代生活中多变的环境。本文设计开发的红外热释电家庭防盗报警器能改善传统防盗系统结构复杂&#xff0c;计算繁琐、价格昂贵、监控盲区等缺陷&#xff0c;主要由单片机模块、复位电路模块、…

pycharm+pytorch2.3.1安装

成功运行 Anaconda简介 Anaconda 就是可以便捷获取包且对包能够进行管理&#xff0c;同时对环境可以统一管理的发行版本。Anaconda包含了conda、Python在内的超过180个科学包及其依赖项。 Anaconda安装 去官网地址下载 Download Anaconda Distribution | Anaconda​www.ana…

<数据集>棉花叶片病害识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;5837张 标注数量(xml文件个数)&#xff1a;5837 标注数量(txt文件个数)&#xff1a;5837 标注类别数&#xff1a;4 标注类别名称&#xff1a;[Bacterial Blight, Curl virus, Fussarium wilt, Healthy] 序号类别名…

springboot3-web-questions-分析

系列文章目录 文章目录 目录 系列文章目录 文章目录 前言 一、问题案例 1、maven项目compile时候出现告警warn 2、java文件打包然后在命令行中运行java会找不到主类 3、程序找不到数据库驱动和配置实例 4、springboot和mybatis-plus版本不兼容导致 5、springboot项目启动的解释…