原力注入

学习总结 - RAG 快速开发实战 - 《02|从0到1快速搭建RAG应用》

课程推荐 - RAG 快速开发实战

Image

地址:https://time.geekbang.org/column/intro/100804101

RAG 流程说明

参考:https://time.geekbang.org/column/article/803829

RAG 技术框架:LangChain

LangChain 是专为开发基于大型语言模型(LLM)应用而设计的全面框架,其核心目标是简化开发者的构建流程,使其能够高效创建 LLM 驱动的应用。

索引流程 - 文档解析模块:pypdf

pypdf 是一个开源的 Python 库,专门用于处理 PDF 文档。pypdf 支持 PDF 文档的创建、读取、编辑和转换操作,能够有效提取和处理文本、图像及页面内容。

索引流程 - 文档分块模块:RecursiveCharacterTextSplitter

采用 LangChain 默认的文本分割器 - RecursiveCharacterTextSplitter。该分割器通过层次化的分隔符(从双换行符到单字符)拆分文本,旨在保持文本的结构和连贯性,优先考虑自然边界如段落和句子。

索引 / 检索流程 - 向量化模型:bge-small-zh-v1.5

bge-small-zh-v1.5 是由北京人工智能研究院(BAAI,智源)开发的开源向量模型。虽然模型体积较小,但仍然能够提供高精度和高效的中文向量检索。该模型的向量维度为 512,最大输入长度同样为 512。

索引 / 检索流程 - 向量库:Faiss

Faiss 全称 Facebook AI Similarity Search,由 Facebook AI Research 团队开源的向量库,因其稳定性和高效性在向量检索领域广受欢迎。

生成流程 - 大语言模型:通义千问 Qwen

通义千问 Qwen 是阿里云推出的一款超大规模语言模型,支持多轮对话、文案创作、逻辑推理、多模态理解以及多语言处理,在模型性能和工程应用中表现出色。采用云端 API 服务,注册有 1,000,000 token 的免费额度。

上述选型在 RAG 流程图中的应用如下所示:

Image
  • LangChain:提供用于构建 LLM RAG 的应用程序框架。
  • 索引流程:使用 pypdf 对文档进行解析并提取信息;随后,采用 RecursiveCharacterTextSplitter 对文档内容进行分块(chunks);最后,利用 bge-small-zh-v1.5 将分块内容进行向量化处理,并将生成的向量存储在 Faiss 向量库中。
  • 检索流程:使用 bge-small-zh-v1.5 对用户的查询(Query)进行向量化处理;然后,通过 Faiss 向量库对查询向量和文本块向量进行相似度匹配,从而检索出与用户查询最相似的前 top-k 个文本块(chunk)。
  • 生成流程:通过设定提示模板(Prompt),将用户的查询与检索到的参考文本块组合输入到 Qwen 大模型中,生成最终的 RAG 回答。

完整代码:https://github.com/yangchangcy/GeekbangCourse-Rapid_Development_of_RAG/blob/main/rag_app_lesson2.py

笔者基于上述代码将其改造成 python notebook,方便在线运行!

准备工作

pip install langchain langchain_community pypdf sentence-transformers faiss-cpu dashscope -i https://pypi.tuna.tsinghua.edu.cn/simple 
git clone git@github.com:yangchangcy/GeekbangCourse-Rapid_Development_of_RAG.git

Python notebook(show me the code)

我们要在 GeekbangCourse-Rapid_Development_of_RAG 里面创建一个新的 notebook,例如 lession2.ipynb,然后我们需要依次将下面 Cell 代码 copy 到 notebook 中。

注意:代码中用到的 API Key 需要从https://bailian.console.aliyun.com/?apiKey=1#/api-key进行申请。

Cell #1

from langchain_community.document_loaders import PyPDFLoader # PDF文档提取from langchain_text_splitters import RecursiveCharacterTextSplitter # 文档拆分chunkfrom sentence_transformers import SentenceTransformer # 加载和使用Embedding模型import faiss # Faiss向量库import numpy as np # 处理嵌入向量数据,用于Faiss向量检索import dashscope #调用Qwen大模型from http import HTTPStatus #检查与Qwen模型HTTP请求状态
import os # 引入操作系统库,后续配置环境变量与获得当前文件路径使用os.environ["TOKENIZERS_PARALLELISM"] = "false" # 不使用分词并行化操作, 避免多线程或多进程环境中运行多个模型引发冲突或死锁
# 设置Qwen系列具体模型及对应的调用API密钥,从阿里云百炼大模型服务平台获得qwen_model = "qwen-turbo"qwen_api_key = "..."
def load_embedding_model():    """    加载bge-small-zh-v1.5模型    :return: 返回加载的bge-small-zh-v1.5模型    """    print(f"加载Embedding模型中")    # SentenceTransformer读取绝对路径下的bge-small-zh-v1.5模型,非下载    embedding_model = SentenceTransformer(os.path.abspath('bge-small-zh-v1.5'))    print(f"bge-small-zh-v1.5模型最大输入长度: {embedding_model.max_seq_length}")     return embedding_model

def indexing_process(pdf_file, embedding_model):    """    索引流程:加载PDF文件,并将其内容分割成小块,计算这些小块的嵌入向量并将其存储在FAISS向量数据库中。    :param pdf_file: PDF文件路径    :param embedding_model: 预加载的嵌入模型    :return: 返回FAISS嵌入向量索引和分割后的文本块原始内容列表    """    # PyPDFLoader加载PDF文件,忽略图片提取    pdf_loader = PyPDFLoader(pdf_file, extract_images=False)    # 配置RecursiveCharacterTextSplitter分割文本块库参数,每个文本块的大小为768字符(非token),相邻文本块之间的重叠256字符(非token)    text_splitter = RecursiveCharacterTextSplitter(        chunk_size=512, chunk_overlap=128    )    # 加载PDF文档,提取所有页的文本内容    pdf_content_list = pdf_loader.load()    # 将每页的文本内容用换行符连接,合并为PDF文档的完整文本    pdf_text = "\n".join([page.page_content for page in pdf_content_list])    print(f"PDF文档的总字符数: {len(pdf_text)}") 
    # 将PDF文档文本分割成文本块Chunk    chunks = text_splitter.split_text(pdf_text)    print(f"分割的文本Chunk数量: {len(chunks)}") 
    # 文本块转化为嵌入向量列表,normalize_embeddings表示对嵌入向量进行归一化,用于准确计算相似度    embeddings = []    for chunk in chunks:        embedding = embedding_model.encode(chunk, normalize_embeddings=True)        embeddings.append(embedding)
    print("文本块Chunk转化为嵌入向量完成")
    # 将嵌入向量列表转化为numpy数组,FAISS索引操作需要numpy数组输入    embeddings_np = np.array(embeddings)
    # 获取嵌入向量的维度(每个向量的长度)    dimension = embeddings_np.shape[1]
    # 使用余弦相似度创建FAISS索引    index = faiss.IndexFlatIP(dimension)    # 将所有的嵌入向量添加到FAISS索引中,后续可以用来进行相似性检索    index.add(embeddings_np)
    print("索引过程完成.")
    return index, chunks
def retrieval_process(query, index, chunks, embedding_model, top_k=3):    """    检索流程:将用户查询Query转化为嵌入向量,并在Faiss索引中检索最相似的前k个文本块。    :param query: 用户查询语句    :param index: 已建立的Faiss向量索引    :param chunks: 原始文本块内容列表    :param embedding_model: 预加载的嵌入模型    :param top_k: 返回最相似的前K个结果    :return: 返回最相似的文本块及其相似度得分    """    # 将查询转化为嵌入向量,normalize_embeddings表示对嵌入向量进行归一化    query_embedding = embedding_model.encode(query, normalize_embeddings=True)    # 将嵌入向量转化为numpy数组,Faiss索引操作需要numpy数组输入    query_embedding = np.array([query_embedding])
    # 在 Faiss 索引中使用 query_embedding 进行搜索,检索出最相似的前 top_k 个结果。    # 返回查询向量与每个返回结果之间的相似度得分(在使用余弦相似度时,值越大越相似)排名列表distances,最相似的 top_k 个文本块在原始 chunks 列表中的索引indices。    distances, indices = index.search(query_embedding, top_k)
    print(f"查询语句: {query}")    print(f"最相似的前{top_k}个文本块:")
    # 输出查询出的top_k个文本块及其相似度得分    results = []    for i in range(top_k):        # 获取相似文本块的原始内容        result_chunk = chunks[indices[0][i]]        print(f"文本块 {i}:\n{result_chunk}") 
        # 获取相似文本块的相似度得分        result_distance = distances[0][i]        print(f"相似度得分: {result_distance}\n")
        # 将相似文本块存储在结果列表中        results.append(result_chunk)
    print("检索过程完成.")    return results
def generate_process(query, chunks):    """    生成流程:调用Qwen大模型云端API,根据查询和文本块生成最终回复。    :param query: 用户查询语句    :param chunks: 从检索过程中获得的相关文本块上下文chunks    :return: 返回生成的响应内容    """    # 设置Qwen系列具体模型及对应的调用API密钥,从阿里云大模型服务平台百炼获得    llm_model = qwen_model    dashscope.api_key = qwen_api_key
    # 构建参考文档内容,格式为“参考文档1: \n 参考文档2: \n ...”等    context = ""    for i, chunk in enumerate(chunks):        context += f"参考文档{i+1}: \n{chunk}\n\n"
    # 构建生成模型所需的Prompt,包含用户查询和检索到的上下文    prompt = f"根据参考文档回答问题:{query}\n\n{context}"    print(f"生成模型的Prompt: {prompt}")
    # 准备请求消息,将prompt作为输入    messages = [{'role': 'user', 'content': prompt}]
    # 调用大模型API云服务生成响应    try:        responses = dashscope.Generation.call(            model = llm_model,            messages=messages,            result_format='message',  # 设置返回格式为"message"            stream=True,              # 启用流式输出            incremental_output=True   # 获取流式增量输出        )        # 初始化变量以存储生成的响应内容        generated_response = ""        print("生成过程开始:")        # 逐步获取和处理模型的增量输出        for response in responses:            if response.status_code == HTTPStatus.OK:                content = response.output.choices[0]['message']['content']                generated_response += content                print(content, end='')  # 实时输出模型生成的内容            else:                print(f"请求失败: {response.status_code} - {response.message}")                return None  # 请求失败时返回 None        print("\n生成过程完成.")        return generated_response    except Exception as e:        print(f"大模型生成过程中发生错误: {e}")        return None

Cell #2

print("-------------RAG过程开始-------------")
# promptquery="下面报告中涉及了哪几个行业的案例以及总结各自面临的挑战?"

输出:

-------------RAG过程开始-------------

Cell #3

embedding_model = load_embedding_model()

输出:

加载Embedding模型中bge-small-zh-v1.5模型最大输入长度: 512

Cell #4

# 索引流程:加载PDF文件,分割文本块,计算嵌入向量,存储在FAISS索引中(内存)index, chunks = indexing_process('test_lesson2.pdf', embedding_model)

输出:

PDF文档的总字符数: 9163分割的文本Chunk数量: 24文本块Chunk转化为嵌入向量完成索引过程完成.

Cell #5

# 检索流程:将用户查询转化为嵌入向量,检索最相似的文本块retrieval_chunks = retrieval_process(query, index, chunks, embedding_model)

输出:

查询语句: 下面报告中涉及了哪几个行业的案例以及总结各自面临的挑战?最相似的前3个文本块:文本块 0:面的数字化转型。2.3.2 面临的挑战在数字化转型之前,金融业案例中银行面临以下主要挑战:客户服务模式过时,主要依赖实体网点,导致服务效率低、客户体验差;金融科技企业带来巨大竞争压力,凭借创新技术和便捷服务吸引大量客户,尤其是年轻一代;数据孤岛和风险管理滞后,各业务部门缺乏数据共享机制,导致信息无法整合,风险管理效率低。2.3.3 数字化转型解决方案为应对金融业案例挑战,银行实施了多方面的数字化转型措施:首先,构建数字化银行平台,推出移动银行应用、在线服务、虚拟客服和智能理财顾问,显著提升了服务便捷性和客户满意度;其次,引入人工智能和大数据分析技术,通过个性化金融产品推荐和实时风险监控,提升客户服务质量和风险管理能力。相似度得分: 0.5915015935897827
文本块 1:导致效率低且易出错;供应链复杂,涉及多个国家和地区,信息传递不及时,造成库存管理困难,甚至存在供应链断裂的风险;客户需求变化快,传统大规模生产方式无法满足市场对个性化定制产品的需求。2.1.3 数字化转型解决方案为了应对制造业上述挑战,公司通过以下步骤进行数字化转型:首先,引入工业 4.0 技术,包括物联网(IoT)、人工智能(AI)、大数据分析和机器人自动化,以优化生产线;其次,构建基于云计算的智能供应链管理系统,实现供应链的端到端可视化管理。2.2 案例二:零售业的数字化转型2.2.1 公司背景零售业案例讲述了一家全球知名的快时尚服装零售企业,面对电子商务的崛起和消费者购物行为的快速变化,传统零售模式受到巨大挑战。为保持市场竞争力并满足消费者日益增长的数字化需求,公司决定实施全面的数字化转型战略。2.2.2 面临的挑战在数字化转型之前,零售业案例的公司面临以下挑战:线上线下渠道割裂,导致库存管理不统一、客户体验不一致,难以提供无缝购物体验;数据利用率低,尽管拥有大量消费者和销售数据,但缺乏先进的数据分析工具,未能转化为可操作的商业洞察。2.2.3 数字化转型解决方案相似度得分: 0.572852373123169
文本块 2:统一、客户体验不一致,难以提供无缝购物体验;数据利用率低,尽管拥有大量消费者和销售数据,但缺乏先进的数据分析工具,未能转化为可操作的商业洞察。2.2.3 数字化转型解决方案为了解决零售业案例的线上线下渠道割裂、数据利用率低、供应链效率低下和客户体验滞后等问题,公司实施了一系列数字化转型措施:首先,构建全渠道零售平台,实现线上与线下购物渠道的无缝整合,提升顾客的便利性和满意度;其次,引入大数据和人工智能驱动的分析平台,精准预测需求、优化库存,并提供个性化产品推荐和营销活动。2.3 案例三:金融业的数字化转型2.3.1 公司背景金融业案例中的金融机构是一家全球知名的银行,成立已有百年历史。随着金融科技(FinTech)的迅速发展以及消费者对在线金融服务需求的增加,传统银行业务模式面临前所未有的挑战。为了保持市场竞争力并满足客户日益增长的数字化需求,该银行决定开展全面的数字化转型。2.3.2 面临的挑战在数字化转型之前,金融业案例中银行面临以下主要挑战:客户服务模式过时,主要依赖实体网点,导致服务效率低、客户体验差;金融科技企业带来巨大竞争压力,凭借创新技术和相似度得分: 0.5637901425361633
检索过程完成.

Cell #6

# 生成流程:调用Qwen大模型生成响应generate_process(query, retrieval_chunks)print("-------------RAG过程结束-------------")

输出:

生成模型的Prompt: 根据参考文档回答问题:下面报告中涉及了哪几个行业的案例以及总结各自面临的挑战?
参考文档1: 面的数字化转型。2.3.2 面临的挑战在数字化转型之前,金融业案例中银行面临以下主要挑战:客户服务模式过时,主要依赖实体网点,导致服务效率低、客户体验差;金融科技企业带来巨大竞争压力,凭借创新技术和便捷服务吸引大量客户,尤其是年轻一代;数据孤岛和风险管理滞后,各业务部门缺乏数据共享机制,导致信息无法整合,风险管理效率低。2.3.3 数字化转型解决方案为应对金融业案例挑战,银行实施了多方面的数字化转型措施:首先,构建数字化银行平台,推出移动银行应用、在线服务、虚拟客服和智能理财顾问,显著提升了服务便捷性和客户满意度;其次,引入人工智能和大数据分析技术,通过个性化金融产品推荐和实时风险监控,提升客户服务质量和风险管理能力。
参考文档2: 导致效率低且易出错;供应链复杂,涉及多个国家和地区,信息传递不及时,造成库存管理困难,甚至存在供应链断裂的风险;客户需求变化快,传统大规模生产方式无法满足市场对个性化定制产品的需求。2.1.3 数字化转型解决方案为了应对制造业上述挑战,公司通过以下步骤进行数字化转型:首先,引入工业 4.0 技术,包括物联网(IoT)、人工智能(AI)、大数据分析和机器人自动化,以优化生产线;其次,构建基于云计算的智能供应链管理系统,实现供应链的端到端可视化管理。2.2 案例二:零售业的数字化转型2.2.1 公司背景零售业案例讲述了一家全球知名的快时尚服装零售企业,面对电子商务的崛起和消费者购物行为的快速变化,传统零售模式受到巨大挑战。为保持市场竞争力并满足消费者日益增长的数字化需求,公司决定实施全面的数字化转型战略。2.2.2 面临的挑战在数字化转型之前,零售业案例的公司面临以下挑战:线上线下渠道割裂,导致库存管理不统一、客户体验不一致,难以提供无缝购物体验;数据利用率低,尽管拥有大量消费者和销售数据,但缺乏先进的数据分析工具,未能转化为可操作的商业洞察。2.2.3 数字化转型解决方案
参考文档3: 统一、客户体验不一致,难以提供无缝购物体验;数据利用率低,尽管拥有大量消费者和销售数据,但缺乏先进的数据分析工具,未能转化为可操作的商业洞察。2.2.3 数字化转型解决方案为了解决零售业案例的线上线下渠道割裂、数据利用率低、供应链效率低下和客户体验滞后等问题,公司实施了一系列数字化转型措施:首先,构建全渠道零售平台,实现线上与线下购物渠道的无缝整合,提升顾客的便利性和满意度;其次,引入大数据和人工智能驱动的分析平台,精准预测需求、优化库存,并提供个性化产品推荐和营销活动。2.3 案例三:金融业的数字化转型2.3.1 公司背景金融业案例中的金融机构是一家全球知名的银行,成立已有百年历史。随着金融科技(FinTech)的迅速发展以及消费者对在线金融服务需求的增加,传统银行业务模式面临前所未有的挑战。为了保持市场竞争力并满足客户日益增长的数字化需求,该银行决定开展全面的数字化转型。2.3.2 面临的挑战在数字化转型之前,金融业案例中银行面临以下主要挑战:客户服务模式过时,主要依赖实体网点,导致服务效率低、客户体验差;金融科技企业带来巨大竞争压力,凭借创新技术和

生成过程开始:根据提供的参考文档,报告中涉及了以下三个行业的案例及其面临的挑战:
### 1. 金融业**案例背景**:- 一家全球知名的银行,有百年历史。
**:临的挑战、客户体验差。式过时,主要依赖实体网点,导致服务效率低技术和便捷服务吸引大量客户。压力,凭借创新共享机制,信息无法整合,风险管理效率低。乏数据
---
### 2. 制造业**案例背景**:家公司,但描述了其面临的普遍性问题。
**面临的挑战**:- 生产流程效率低且易出错。涉及多个国家和地区,信息传递不及时,导致库存管理困难和供应链断裂风险。产品的需求。变化快,传统大规模生产方式无法满足市场对个性化定制
---
### 3. 零售业背景**:企业。家全球知名的快时尚服装零售
**面临的挑战**:体验不一致,难以提供无缝购物体验。不统一、客户销售数据,但缺乏先进的数据分析工具,未能转化为可操作的商业洞察。
---
### 总结零售业** 三个行业的案例。各行业面临的挑战分别为:服务效率低、客户体验差、金融科技竞争压力大、数据孤岛和风险管理滞后。2. **制造业**:生产效率低、供应链复杂、客户需求变化快。、数据利用率低、库存管理困难、客户体验滞后。生成过程完成.-----------RAG过程结束.---------------