一、什么是RAG:
检索增强生成(Retrieval-Augmented Generation)是一种结合了信息检索与生成模型的技术。它通过将外部知识库或文档与生成模型结合,增强了生成模型的上下文信息,从而提高了生成内容的质量和准确性。
RAG的主要流程可以分为以下几个步骤:
1.检索(Retrieval)
- 输入查询或问题后,首先通过信息检索模块(通常是一个检索系统,如基于向量空间的搜索或传统的关键词匹配)从大量文档中检索出相关的文本片段或信息。
2.生成(Generation)
- 生成模型(例如 GPT 或 T5)使用检索到的相关信息作为上下文,再结合输入的查询,生成更为丰富、精准的回答或文本。
3.增强(Augmentation)
- 生成模型不仅仅依赖于输入的内容,还能利用外部信息库中的内容,使得生成的文本更加具有知识性和上下文的准确性,尤其是在面对复杂问题时,生成的答案能够包含更多的细节。
二、RAG应用流程
RAG应用流程如图所示
RAG应用实现主要包含两个阶段:
- 数据准备阶段:数据提取->文本分割->向量化(embedding)->数据入库
- 应用阶段:用户提问->数据检索->注入prompt->LLM生成回答
数据准备阶段
1.数据提取
- 数据加载:包含多种格式数据加载、不同数据源获取。
- 数据处理:将数据进行过滤、压缩、统一格式化等等。
- 元数据:提取数据中的关键信息,譬如文件名、标题、时间、关键字等信息。
2.文本分割
常见的文本分割方式:
- 句分割:以“句”的粒度进行切分,保证句子语义的完整性。常见的分割符,如句号、感叹号、问号、换行等等。
- 固定长度分割:依据embedding模型的token长度限制,将文本分割为固定长度(例如256/512个tokens),但是这种切分方式会导致语义信息的损失,通常在
在头尾增加⼀定冗余量来缓解
。
3.向量化
将文本数据转换为数字表示形式(即“嵌入”),使得计算机可以通过向量计算进行检索和生成。这是 RAG 系统的核心步骤之一,涉及将文本映射到一个高维的向量空间中。
4.数据入库
将文本数据及其对应的向量存储到数据库或检索系统中,方便后续检索。
应用阶段
1.用户提问
用户通过自然语言输入问题或查询,系统需要将用户的输入进行处理并准备后续的检索和生成任务。
2.数据检索
根据用户的提问,检索系统从预先存储的文档数据中找出与问题最相关的信息。检索的结果是与用户提问高度相关的文本片段或文档。
3.注入 Prompt
将检索到的相关信息(文本片段或文档)与用户提问一起构成模型的输入。这个过程通常涉及将检索结果和问题通过合适的格式化方式组合成一个输入 prompt,并注入到生成模型中。
4.LLM 生成回答
通过大规模语言模型(如 GPT、BERT、T5 等)生成回答。生成模型使用注入的 prompt,根据检索到的相关信息生成最终的回答或文本。
应用案例-私域知识问答
接上次:https://blog.youkuaiyun.com/RX0117/article/details/144971980
1.首先创建data和index两个文件夹,其次创建app_chat_basic_rag.py和embeddings.py文件
2.我们先安装两个模块
pip install llama-index-embeddings-huggingface
pip install llama-index-embeddings-ollama
3.embeddings.py代码
主要作用:
- embed_model_local_bge_small()构建本地模型,减少模型的加载时间,提高调用模型的效率
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
# 本地模型
def embed_model_local_bge_small(**kwargs):
"""
指定模型名称和缓存⽂件夹路径来初始化⼀个HuggingFaceEmbedding对象。
使⽤本地缓存可以减少模型的加载时间,并在多次调⽤时提⾼效率。
:param kwargs:
:return:
"""
# 初始化嵌入模型,使用指定的模型名称和缓存文件夹路径
embed_model = HuggingFaceEmbedding(
model_name="BAAI/bge-small-zh-v1",
cache_folder=r"../embed_cache",
**kwargs
)
# 返回嵌入后的模型
return embed_model
4.app_chat_basic_rag.py代码
主要作用:
- index_data()加载本地文件夹中的数据,为本地数据构建索引并对数据进行向量化后保存到磁盘持久化。
- create_chat_engine_rag采用上下文模式,根据本地持久化数据加载数据索引,创建聊天引擎。
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex, Settings, StorageContext, load_index_from_storage
from llama_index.core.chat_engine.types import ChatMode
from llama_index.core.memory import ChatMemoryBuffer
from llms import deepseek_llm
from embeddings import embed_model_local_bge_small
# 配置全局LLM和嵌入模型
# 设置LLM为deepseek_llm
Settings.llm = deepseek_llm()
Settings.embed_model = embed_model_local_bge_small
def index_data():
"""
索引数据
:return:
"""
# 加载数据(连接本地数据)
# 使⽤SimpleDirectoryReader从指定⽬录读取数据,这⾥的数据指的是⽂本或⽂档⽂件
# input_dir参数指定输⼊⽬录为"data",这是存放⽂档数据的⽬录
data = SimpleDirectoryReader(input_dir="data").load_data()
# 构建索引
# VectorStoreIndex.from_documents⽅法⽤于从加载的⽂档数据中构建⼀个向量存储索引
# data参数是之前步骤中加载的⽂档数据
# show_progress参数设置为True,表示在处理时显示进度条
index = VectorStoreIndex.from_documents(data, show_progress=True)
# 对向量数据库做持久化
# storage_context.persist⽅法⽤于将构建的索引持久化到磁盘
# persist_dir参数指定持久化的⽬录为"index",这会将索引数据保存到该⽬录下
index.storage_context.persist(persist_dir="index")
async def create_chat_engine_rag():
"""
异步创建检索增强生成(RAG)引擎
:return:
"""
# 初始化存储上下文,默认持久化目录为./index
storage_context = StorageContext.from_defaults(persist_dir="./index")
# 加载索引
index = load_index_from_storage(storage_context=storage_context)
# 构建内存,存储聊天历史,限制token数量为1024
memory = ChatMemoryBuffer.from_defaults(token_limit=1024)
# 创建聊天引擎,设置聊天模式为上下⽂模式,并指定记忆和系统提示
# chat_mode: 设置聊天模式为上下⽂模式,这意味着AI的回答将基于⽤户提供的上下⽂内容
# memory: ⽤于存储聊天历史记录,以便AI在回答时能考虑到之前的对话内容
# system_prompt: 系统提示,定义了AI的⾏为准则,即AI助⼿应基于⽤户提供的上下⽂内容来回答问题,不允许随意编造回答
chat_engine = index.as_chat_engine(
chat_mode=ChatMode.CONTEXT,
memory=memory,
system_prompt=(
"你是⼀个AI助⼿,可以基于⽤户提供的上下⽂内容,回答⽤户的问题。不能肆意编造回答。"
),
)
# 返回创建的聊天引擎
return chat_engine
if __name__ == '__main__':
index_data()
关于app_chat_basic_rag.py中导入的模块作用介绍
- VectorStoreIndex:向量存储索引类,⽤于创建和管理向量数据库。
- SimpleDirectoryReader:简单⽬录读取器类,⽤于从指定⽬录读取⽂档。
- Settings:设置类,⽤于配置全局设置。
- StorageContext:存储上下⽂类,⽤于管理存储配置。
- load_index_from_storage:从存储加载索引的函数。
5.切换到app.py文件中替换聊天引擎
@cl.on_chat_start
async def start():
# 初始化大型语言模型(LLM)设置
Settings.llm = deepseek_llm()
# 异步创建带有RAG(检索增强⽣成)的聊天引擎。
chat_engine = await create_chat_engine_rag()
# 将聊天引擎对象存储到用户会话中
cl.user_session.set('chat_engine', chat_engine)
# 发送一条欢迎消息
await cl.Message(
author="Assistant", content="你好!我是 AI 助⼿。有什么可以帮助你的吗?"
).send()
6.在data文件夹中存储本地数据文件
7.先启动app_chat_basic_rag.py构建向量索引数据库
再到终端使用命令chainlit run app.py -w启动项目