4月7日(RAG基础)

张开发
2026/4/7 17:53:53 15 分钟阅读

分享文章

4月7日(RAG基础)
第1节认识RAGRAG定义RAG是一种将外部知识检索与大语言模型生成能力结合的技术通过动态注入权威数据解决模型幻觉问题和时效性问题核心价值不予大语言模型实时访问更新知识的能力突破训练数据的时间限制基本技术原理架构用户提问 - 检索模块查询向量化数据库匹配 -增强模块,构建提示词 -生成模块:大语言生成答案RAG三步走数据预处理构建向量索引库知识库构建收集整理网页文档、数据库等多元数据信息构建外部知识库文档切块将文档切分为适合大小的片段以便后续检索。分段策略需要在语义完整性与检索效率之间取得平衡向量化处理使用嵌入模型将文本转换为向量并存储在向量数据库中检索当用户提出问题时系统从外部知识库中检索与相关的文本片段向量检索将问题和文档转换为向量通过相似度计算匹配语义相关内容关键词检索基于关键词匹配快速定位内容如BM25算法混合检索结合向量和关键词检索提高召回率和准确性生成将检索到的文本与用户提问合并为提示词输入大语言模型生成自然语言答案。模型基于外部知识库而非仅依赖训练数据生成内容回答显著降低虚构信息的风险RAG架构演进Native RAG基础RAG核心流程索引构建-检索召回-直接对话用途适用于简单的问答缺陷检索噪音干扰语义相似但主题无关的内容信息碎片化固定分块割裂长上下文多跳推理失效无法关联跨文档信息典型应用场景企业产品手册查询基础聊天机器人Advanced RAG高级RAG优化策略检索前查询改写Query Rewriting子查询分解HyDE源数据过滤检索中混合查询向量加关键字图数据库增强检索后重排序上下文压缩用途提升高精度场景的答案质量如法律合同、医疗诊断支持优势解决基础的噪声问题支持复杂语义对齐Modular RAG模块化RAG架构特性解耦为可插拔模块检索器重排器路由代理等核心能力迭代检查逐步优化结果动态路由将查询分配到最佳模块如API数据库用途企业及知识管理平台需整合多元异构数据如金融风控系统Agentic RAG智能体RAG技术分支单质能体路由动态分配任务至专属模块多智能体协同并行调用多个工具如数据库搜索引擎用途超复杂任务处理如全球新闻汇总多轮跨工具推理企业为什么需要RAG传统语言模型的局限性推动了RAG发展知识滞后模型训练后无法获取新知识幻觉风险对未知问题可能造成看似合理实则错误的答案专业领域局限缺乏特定专业领域知识RAG的优势实时性通过更新知识库获取最新信息准确性答案基于检索内容生成减少幻觉可解释性答案追溯可致知识原文方便验证轻量化无需重新训练大语言模型成本更低RAG快速上手工具选型LangChain提供预制RAG链支持快速集成LLM与向量数据库LlamaIndex专为知识索引优化简单化文档分块与嵌入流程Milvus开源高性能向量数据库FIASS轻量级向量搜索库Pinecone云服务向量数据库极简RAG数据准备格式支持pdf网页文本等分块策略按语意或固定长度切分避免信息碎片化索引构建嵌入模型选用开源的模型或者领域专用模型向量化将文本分块转换为向量存入数据库减索优化混合检索结合关键词BM25与语义搜索向量相似度提升召回率重排序用小模型筛选topk相关片段生成集合提示工程设计模板引导大语言模型融合检索相关内容大语言模型选型GPTOllama等# 使用LangChain构建最小化RAG from langchain_community.vectorstores import FAISS from langchain_community.embeddings import HuggingFaceEmbeddings # 1. 加载知识库PDF/TXT/CSV改成自己的知识库 docs load_documents(企业知识库.zip) # 2. 文本分块与向量化 embeddings HuggingFaceEmbeddings(model_nameBAAI/bge-large-zh-v1.5) db FAISS.from_documents(docs, embeddings) # 3. 检索增强问答 retriever db.as_retriever() qa_chain RetrievalQA.from_chain_type(llmChatGPT, retrieverretriever) print(qa_chain.run(Q我司产品X的技术参数))第2节学习准备工作搭建Conda环境地址https://www.anaconda.com/download/succes使用conda -v查看版本号创建环境conda create -n rag-study python3.10 -y激活环境conda activate myenv退出环境conda deactivate查看环境conda env list阿里百炼API申请官方地址https://bailian.console.aliyun.com/第3节极简RAG搭建相关包安装pip install pypdf2 # 用途PDF 文件基础操作纯文本提取、页面级操作 pip install dashscope # 用途调用阿里云大模型 API如通义千问 # 用途构建大模型LLM应用的开发框架 pip install langchain-openai # - langchain-openai专用于 OpenAI 模型如 GPT 系列的适配器 pip install langchain-community # - langchain-community社区贡献的扩展工具向量库/文件加载器等 pip install faiss-cpu # 用途高效向量相似性搜索CPU 优化版必要库类导入#提供跨平台的操作系统交互接口允许开发者执行文件管理、进程控制、环境配置等底层操作 import os #专业日志管理核心工具可以监控生产环境、调试、运行状态等 import logging #Python中的序列化库可以将Python对象序列化二进制字节流保存到文件在中同时可以反序列化还原对象 import pickle #用于读取PDF文件内容提取文本、元数据作者/标题、页面对象等基础信息 from PyPDF2 import PdfReader #加载预定义的问答任务链自动化实现“检索→生成”流程 from langchain.chains.question_answering import load_qa_chain #调用OpenAI的GPT系列模型,实现文本生成、问答、摘要等任务 from langchain_openai import OpenAI, ChatOpenAI #阿里云DashScope提供的嵌入模型适合中文场景优化功能类似OpenAI Embeddings from langchain_community.embeddings import DashScopeEmbeddings #监控OpenAI API调用开销消耗的tokens数量、费用调试性能瓶颈 from langchain_community.callbacks.manager import get_openai_callback #将长文本按语义递归分割为小片段如按段落、句子适配语言模型的上下文长度限制 from langchain.text_splitter import RecursiveCharacterTextSplitter #Facebook开源的向量数据库库支持快速相似性搜索最近邻检索 from langchain_community.vectorstores import FAISS #Python类型标注库用于声明函数参数/返回值的类型如List[str]表示字符串列表提升代码可读性与静态检查支持 from typing import List, Tuple核心代码数据读取#函数一读取pdf文件提取每行内容和每行对应的页码同时拼接成一个大文本 def extract_text_with_page_numbers(pdf) - Tuple[str,List[int]]: 从pdf中提取文本并记录每行文本对应的页码 参数 pdf: PDF文件对象 返回: text: 提取的文本内容 page_numbers: 每行文本对应的页码列表 text page_numbers [] #遍历PDF的每一页enumerate从1开始计数页码 for page_number,page in enumerate(pdf.pages, start1): #提取当前页的文本 extracted_text page.extract_text() #如果该页面有文本 if extracted_text: #将当前页文本追加到总文本中字符串拼接文本 text extracted_text #记录每行文本对应的页码按换行符分隔 page_numbers.extend([page_numbers] * len(extracted_text.split(\n))) else: #处理无文本页面的情况 logging.warning(fNO TEXT FOUND ON page {page_number}.) return text ,page_numbers向量化处理#向量化处理函数对识别到的PDF文件进行分割将分割好的文本块构建成向量存储 def process_text_with_splitter(text: str, page_numbers: List[int], save_path: str None): 处理文本并创建向量存储 参数: text: 提取的文本内容 page_numbers: 每行文本对应的页码列表 save_path: 可选保存向量数据库的路径 返回: knowledgeBase: 基于FAISS的向量存储对象 #创建递归式文本分割器 text_splitter RecursiveCharacterTextSplitter( separators[\n\n, \n, \t, ., ], #按语义单位分割 chunk_size512, #区块最大长度 chunk_overlap 128, #区块间重叠长度 length_function len, #长度计算函数 ) #文本分块处理 chunks text_splitter.split_text(text) #print(f文本被分割成: {len(chunks)}个块。) #使用阿里云DashScope生成文本嵌入向量 embeddings DashScopeEmbeddings(modeltext-embedding-v2) #构建FAISS向量数据库 knowledgeBase FAISS.from_texts(chunks,embeddings) #print(已从文本块创建知识库...) #建立区块-页码映射关系,enumerate(chunks)同时获取分块的索引 i和内容 chunk。 #page_numbers[i]表示第 i个分块在源文档中的起始页码 page_info {chunk: page_numbers[i] for i, chunk in enumerate(chunks)} knowledgeBase.page_info page_info #附加元数据 #持久化存储 if save_path: #确保目录存在 os.makedirs(save_path, exist_okTrue) # 保存向量索引 knowledgeBase.save_local(save_path) #print(f向量数据库已保存到: {save_path}) #序列化储存页码元数据保存页码信息到同一目录 with open(os.path.join(save_path, page_info.pkl), wb) as f: pickle.dump(page_info, f) #print(f页码信息已保存到: {os.path.join(save_path, page_info.pkl)}) return knowledgeBase加载向量化数据库def load_knowledge_base(load_path: str, embeddings None) - FAISS: 从磁盘加载向量数据库和页码信息 参数: load_path: 向量数据库的保存路径 embeddings: 可选嵌入模型。如果为None将创建一个新的DashScopeEmbeddings实例 返回: knowledgeBase: 加载的FAISS向量数据库对象 #初始化嵌入模型默认阿里云 if embeddings is None: embeddings DashScopeEmbeddings(modeltext-embeddings-v2) #加载FAISS向量库需要启用反序列化安全选项 knowledgeBase FAISS.load_local( load_path, embeddings, allow_dangerous_deserializationTrue ) #加载页码元数据 page_info_path os.path.join(load_path, page_info.pkl) if os.path.exists(page_info_path): with open(page_info_path, rb) as f: knowledgeBase.page_info pickle.load(f) return knowledgeBase运行代码#初始化PyPDF2读取器这个pdf文件可以放到py文件同一个地址下面这样就不要找文件地址了真正开发的时候不要这样还是要另起文件夹专门放数据文件 pdf_reader PdfReader(大学生创新创业三年行动计划.pdf) #执行文本提取load_knowledge_base text, page_numbers extract_text_with_page_numbers(pdf_reader) #处理文本并创建知识库同时保存到磁盘 save_dir vertor_db knowledgeBase process_text_with_splitter(text, page_numbers, save_pathsave_dir) #处理文本并创建知识库 knowledgeBase process_text_with_splitter(text, page_numbers) # print(knowledgeBase)查询内容生成#设置查询问题 query 大学生可以领取什么补贴可以领多少钱 if query: #执行相似度搜索找到与查询相关的文档 docs knowledgeBase.similarity_search(query) #初始化对话大模型 chatLLM ChatOpenAI( #大模型中还有一些参数如temperature、max_tokens等这里没有配置参数的具体用法可以看dashscope官网或者看这个网站https://www.promptingguide.ai/zh/introduction/settings #若没有配置环境变量请用百炼API Key将下行替换为api_keysk-xxx api_key你的key, base_urlhttps://dashscope.aliyuncs.com/compatible-mode/v1, modeldeepseek-v3 ) #加载问答链 chain load_qa_chain(chatLLM, chain_typestuff)process_text_with_splitter #准备输入数据 input_data {input_documents: docs,question: query} #使用回调函数跟踪API调用成本 with get_openai_callback() as cost: #执行问答链 response chain.invoke(inputinput_data) print(f查询已处理。成本: {cost}) print(response[output_text])

更多文章