当前位置: 首页 > news >正文

【RAG 项目实战 07】替换 ConversationalRetrievalChain(单轮问答)

【RAG 项目实战 07】替换 ConversationalRetrievalChain(单轮问答)


NLP Github 项目:

  • NLP 项目实践:fasterai/nlp-project-practice

    介绍:该仓库围绕着 NLP 任务模型的设计、训练、优化、部署和应用,分享大模型算法工程师的日常工作和实战经验

  • AI 藏经阁:https://gitee.com/fasterai/ai-e-book

    介绍:该仓库主要分享了数百本 AI 领域电子书

  • AI 算法面经:fasterai/nlp-interview-handbook#面经

    介绍:该仓库一网打尽互联网大厂NLP算法面经,算法求职必备神器

  • NLP 剑指Offer:https://gitee.com/fasterai/nlp-interview-handbook

    介绍:该仓库汇总了 NLP 算法工程师高频面题


一、RAG 整体流程

检索式问答的系统流程图:

二、RAG 核心模块

2.1 环境配置

# @Author:青松  
# 公众号:FasterAI  
# Python, version 3.10.14  
# Pytorch, version 2.3.0  
# Chainlit, version 1.1.301

2.2 分割文本块并对每一个块建索引

# 配置文件分割器,每个块1000个token,重复100个
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)# 将文件分割成文本块
texts = text_splitter.split_text(text)# 为每个文本块添加元数据
metadatas = [{"source": f"{i}-pl"} for i in range(len(texts))]# 使用异步方式创建 Chroma 向量数据库
vectorstore = await cl.make_async(Chroma.from_texts)(texts, embeddings_model, metadatas=metadatas
)# 将 Chroma 向量数据库转化为检索器
retriever = vectorstore.as_retriever()

2.3 构建 RAG 链

# RAG_Prompt:根据参考内容回答用户问题
rag_template = "你是一个专门处理问答任务的智能助理。请使用给定的参考内容来回答用户的问题,如果你不知道答案,就说你不知道,不要试图编造答案。" \"\n\n用户问题: {question} \n参考内容: {context} \n答案:"rag_prompt = PromptTemplate.from_template(rag_template)# RAG链:根据问题和参考内容生成答案
rag_chain = ({"context": retriever | format_docs, "question": RunnablePassthrough()}| rag_prompt| llm| StrOutputParser()
)

2.4 检索生成

rag_chain = cl.user_session.get("rag_chain")# 使用RAG链处理用户问题
response = rag_chain.invoke(message.content,config=RunnableConfig(callbacks=[cl.LangchainCallbackHandler()]),
)# 大模型的回答
await cl.Message(content=response).send()

三、RAG 效果展示

启动程序:

chainlit run rag_app.py -w

系统截图:

在这里插入图片描述

  • 问题一:对第一个问题大模型可以根据文档内容生成答案。
  • 问题二:对第一个问题大模型未能结合聊天历史进行RAG。

四、RAG 完整代码

# @Author:青松
# 公众号:FasterAI
# Python, version 3.10.14
# Pytorch, version 2.3.0
# Chainlit, version 1.1.301import chainlit as cl
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceBgeEmbeddings
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnableConfig, RunnablePassthroughimport llm_util
from common import Constants# 获取大模型实例
llm = llm_util.get_llm(Constants.MODEL_NAME['QianFan'])# 获取文本嵌入模型
model_name = "BAAI/bge-small-zh"
# 对模型生成的嵌入进行归一化处理,将它们缩放到具有单位范数(长度为1)的尺度
encode_kwargs = {"normalize_embeddings": True}
embeddings_model = HuggingFaceBgeEmbeddings(model_name=model_name, encode_kwargs=encode_kwargs
)@cl.on_chat_start
async def on_chat_start():""" 监听会话开始事件 """await send_welcome_msg()files = None# 等待用户上传文件while files is None:files = await cl.AskFileMessage(content="Please upload a text file to begin!",accept=["text/plain"],max_size_mb=20,timeout=180,).send()file = files[0]# 发送处理文件的消息msg = cl.Message(content=f"Processing `{file.name}`...", disable_feedback=True)await msg.send()with open(file.path, "r", encoding="utf-8") as f:text = f.read()# 配置文件分割器,每个块1000个token,重复100个text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)# 将文件分割成文本块texts = text_splitter.split_text(text)# 为每个文本块添加元数据metadatas = [{"source": f"{i}-pl"} for i in range(len(texts))]# 使用异步方式创建 Chroma 向量数据库vectorstore = await cl.make_async(Chroma.from_texts)(texts, embeddings_model, metadatas=metadatas)# 将 Chroma 向量数据库转化为检索器retriever = vectorstore.as_retriever()cl.user_session.set("retriever", retriever)# RAG_Prompt:根据参考内容回答用户问题rag_template = "你是一个专门处理问答任务的智能助理。请使用给定的参考内容来回答用户的问题,如果你不知道答案,就说你不知道,不要试图编造答案。" \"\n\n用户问题: {question} \n参考内容: {context} \n答案:"rag_prompt = PromptTemplate.from_template(rag_template)# RAG链:根据问题和参考内容生成答案rag_chain = ({"context": retriever | format_docs, "question": RunnablePassthrough()}| rag_prompt| llm| StrOutputParser())cl.user_session.set("rag_chain", rag_chain)# 通知用户文件已处理完成,更新当前窗口的内容msg.content = f"Processing `{file.name}` done. You can now ask questions!"await msg.update()@cl.on_message
async def on_message(message: cl.Message):""" 监听用户消息事件 """rag_chain = cl.user_session.get("rag_chain")# 使用RAG链处理用户问题response = rag_chain.invoke(message.content,config=RunnableConfig(callbacks=[cl.LangchainCallbackHandler()]),)# 大模型的回答await cl.Message(content=response).send()async def send_welcome_msg():image = cl.Image(url="https://qingsong-1257401904.cos.ap-nanjing.myqcloud.com/wecaht.png")# 发送一个图片await cl.Message(content="**青松** 邀你关注 **FasterAI**, 让每个人的 AI 学习之路走的更容易些!立刻扫码开启 AI 学习、面试快车道 **(^_^)** ",elements=[image],).send()def format_docs(docs):""" 拼接检索到的文本块 """return "\n\n".join(doc.page_content for doc in docs)

【动手学 RAG】系列文章:

  • 【RAG 项目实战 01】在 LangChain 中集成 Chainlit
  • 【RAG 项目实战 02】Chainlit 持久化对话历史
  • 【RAG 项目实战 03】优雅的管理环境变量
  • 【RAG 项目实战 04】添加多轮对话能力
  • 【RAG 项目实战 05】重构:封装代码
  • 【RAG 项目实战 06】使用 LangChain 结合 Chainlit 实现文档问答
  • 【RAG 项目实战 07】替换 ConversationalRetrievalChain(单轮问答)
  • 【RAG 项目实战 08】为 RAG 添加历史对话能力
  • More…

【动手部署大模型】系列文章:

  • 【模型部署】vLLM 部署 Qwen2-VL 踩坑记 01 - 环境安装
  • 【模型部署】vLLM 部署 Qwen2-VL 踩坑记 02 - 推理加速
  • 【模型部署】vLLM 部署 Qwen2-VL 踩坑记 03 - 多图支持和输入格式问题
  • More…

相关文章:

【RAG 项目实战 07】替换 ConversationalRetrievalChain(单轮问答)

【RAG 项目实战 07】替换 ConversationalRetrievalChain(单轮问答) NLP Github 项目: NLP 项目实践:fasterai/nlp-project-practice 介绍:该仓库围绕着 NLP 任务模型的设计、训练、优化、部署和应用,分享大…...

godot游戏引擎_瓦片集和瓦片地图介绍

在 Godot 中,TileSet 和 TileMap 是用于处理瓦片地图的两个关键概念,它们的作用和用途有明显的区别。以下是两者的详细对比: 1. TileSet(瓦片集) TileSet 是资源,定义瓦片的内容和属性。 特点&#xff1a…...

7、深入剖析PyTorch nn.Module源码

文章目录 1. 重要类2. add_modules3. Apply(fn)4. register_buffer5. nn.Parametersister_parameters6. 后续测试 1. 重要类 nn.module --> 所有神经网络的父类,自定义神经网络需要继承此类,并且自定义__init__,forward函数即可: #!/usr…...

如何提升编程能力第二篇

如何提升编程能力2 1. 引言2. 掌握理论基础2.1 理解编程语言的核心2.2 数据结构与算法2.3 计算机基础与系统设计3.1 多写代码3.2 参与开源项目3.3 开发自己的项目 4. 提高代码质量4.1 代码风格与可读性4.2 测试驱动开发 1. 引言 编程是推动现代科技发展的核心技能,…...

问:SpringBoot核心配置文件都有啥,怎么配?

在SpringBoot的开发过程中,核心配置文件扮演着至关重要的角色。这些文件用于配置应用程序的各种属性和环境设置,使得开发者能够灵活地定制和管理应用程序的行为。本文将探讨SpringBoot的核心配置文件,包括它们的作用、区别,并通过…...

RHCSA作业

课后练习 将整个 /etc 目录下的文件全部打包并用 gzip 压缩成/back/etcback.tar.gz [rootlocalhost ~]# tar -czvf /back/etcback.tar.gz -C / etc 使当前用户永久生效的命令别名:写一个命令命为hello,实现的功能为每输入一次hello命令,就有hello&#…...

ESP32学习笔记_FreeRTOS(3)——SoftwareTimer

摘要(From AI): 这篇笔记全面介绍了 FreeRTOS 软件定时器的核心概念和使用方法,包括定时器的创建、管理、常用 API 和辅助函数,并通过示例代码演示了如何启动、重置和更改定时器的周期。它强调了软件定时器的灵活性、平台无关性以及与硬件定时器的对比 …...

文心一言与千帆大模型平台的区别:探索百度AI生态的双子星

随着人工智能技术的迅猛发展,越来越多的公司开始投入资源开发自己的AI解决方案。在中国,百度作为互联网巨头之一,不仅在搜索引擎领域占据重要位置,还在AI领域取得了显著成就。其中,“文心一言”和“千帆大模型平台”便…...

【c语言】文件操作详解 - 从打开到关闭

文章目录 1. 为什么使用文件?2. 什么是文件?3. 如何标识文件?4. 二进制文件和文本文件?5. 文件的打开和关闭5.1 流和标准流5.1.1 流5.1.2 标准流 5.2 文件指针5.3 文件的打开和关闭 6. 文件的读写顺序6.1 顺序读写函数6.2 对比一组…...

Flink Sink的使用

经过一系列Transformation转换操作后,最后一定要调用Sink操作,才会形成一个完整的DataFlow拓扑。只有调用了Sink操作,才会产生最终的计算结果,这些数据可以写入到的文件、输出到指定的网络端口、消息中间件、外部的文件系统或者是…...

pcl::PointCloud<PointType>::Ptr extractedCloud; 尖括号里的值表示什么含义?

在C中&#xff0c;pcl::PointCloud<PointType>::Ptr是一种智能指针&#xff0c;它是Point Cloud Library (PCL)中用于管理pcl::PointCloud对象的智能指针类型。这里的<pcl::PointCloud<PointType>::Ptr>尖括号里的值表示智能指针所指向的对象类型。 让我们分…...

《基于FPGA的便携式PWM方波信号发生器》论文分析(三)——数码管稳定显示与系统调试

一、论文概述 基于FPGA的便携式PWM方波信号发生器是一篇由任青颖、庹忠曜、黄洵桢、李智禺和张贤宇 等人发表的一篇期刊论文。该论文主要研究了一种新型的信号发生器&#xff0c;旨在解决传统PWM信号发生器在移动设备信号调控中存在的精准度低和便携性差的问题 。其基于现场可编…...

VsCode 插件推荐(个人常用)

VsCode 插件推荐&#xff08;个人常用&#xff09;...

路由策略与路由控制实验

AR1、AR2、AR3在互联接口、Loopback0接口上激活OSPF。AR3、AR4属于IS-IS Area 49.0001&#xff0c;这两者都是Level-1路由器&#xff0c;AR3、AR4的系统ID采用0000.0000.000x格式&#xff0c;其中x为设备编号 AR1上存在三个业务网段A、B、C&#xff08;分别用Loopback1、2、3接…...

训练的decoder模型文本长度不一致,一般设置为多大合适,需要覆盖最长的文本长度么

在训练解码器模型时,文本长度不一致是常见的情况,需要根据任务的特性和数据集的长度分布来设置合理的最大长度 (max_length)。以下是一些指导原则,帮助你设置合适的最大长度: 1. 是否需要覆盖最长文本长度 覆盖最长文本长度: 如果任务对完整性要求很高(例如生成数学公式、…...

过滤条件包含 OR 谓词,如何进行查询优化——OceanBase SQL 优化实践

这篇博客涉及两个点&#xff0c;一个是 “OR Expansion 改写”&#xff0c;另一个是 “基于代价的改写”。 背景 在写SQL查询时&#xff0c;难以避免在过滤条件中使用 OR 谓词&#xff0c;但其往往会导致索引利用效率下降的问题 。本文将分享如何通过查询改写的2种方式进行优化…...

通过异步使用消息队列优化秒杀

通过异步使用消息队列优化秒杀 同步秒杀流程异步优化秒杀异步秒杀流程基于lua脚本保证Redis操作原子性代码实现阻塞队列的缺点 同步秒杀流程 public Result seckillVoucher(Long voucherId) throws InterruptedException {SeckillVoucher seckillVoucher iSeckillVoucherServi…...

AI产业告别“独奏”时代,“天翼云息壤杯”高校AI大赛奏响产学研“交响乐”

文 | 智能相对论 作者 | 陈泊丞 人工智能产业正在从“独奏”时代进入“大合奏”时代。 在早期的AI发展阶段&#xff0c;AI应用主要集中在少数几个领域&#xff0c;如语音识别、图像处理等。这些领域的研究和开发工作往往由少数几家公司或研究机构即可独立完成&#xff0c;犹…...

Hot100 - 字母异位词分组

Hot100 - 字母异位词分组 最佳思路&#xff1a;排序 时间复杂度&#xff1a; O(nmlogm)&#xff0c;其中 n 为 strs 数组的长度&#xff0c;m 为每个字符串的长度。 代码&#xff1a; class Solution {public List<List<String>> groupAnagrams(String[] strs) …...

力扣hot100-->排序

排序 1. 56. 合并区间 中等 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题&#xff1a; pgsql数据库通过备份数据库文件进行还原时&#xff0c;如果表中有自增序列&#xff0c;还原后可能会出现重复的序列&#xff0c;此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”&#xff0c;…...

React核心概念:State是什么?如何用useState管理组件自己的数据?

系列回顾&#xff1a; 在上一篇《React入门第一步》中&#xff0c;我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目&#xff0c;并修改了App.jsx组件&#xff0c;让页面显示出我们想要的文字。但是&#xff0c;那个页面是“死”的&#xff0c;它只是静态…...

李沐--动手学深度学习--GRU

1.GRU从零开始实现 #9.1.2GRU从零开始实现 import torch from torch import nn from d2l import torch as d2l#首先读取 8.5节中使用的时间机器数据集 batch_size,num_steps 32,35 train_iter,vocab d2l.load_data_time_machine(batch_size,num_steps) #初始化模型参数 def …...