资讯动态

检索增强生成RAG

发布时间:2026/9/9 23:59:35 来源:尧图企业网站定制
目录核心思想先检索后生成为什么需要 RAG解决大模型的根本痛点RAG 的基本工作流程RAG 的优势RAG vs 传统微调典型应用场景与你之前问题的关联rerank是必须的吗核心作用从“找得多”到“找得准”为什么需要Rerank向量检索的不足如何决策你的项目需要Rerank吗实践建议检索策略你的角色策略架构师一个典型的实现代码框架Python示例你依赖的工具与组件实践建议RAG 是Retrieval-Augmented Generation​ 的缩写中文译为检索增强生成。它是一种将信息检索与大语言模型生成相结合的技术框架旨在让大模型生成更准确、更可信、且能引用来源的答案。简单说RAG 就是让大模型在回答问题前先“翻书查资料”然后根据查到的资料来组织答案。核心思想先检索后生成想象一下这个过程你问一个问题例如“Django 中如何优化数据库查询”系统不是让大模型凭空回忆而是立刻去一个指定的知识库如你的项目文档、技术手册、公司资料里搜索相关段落。把搜索到的相关文本作为“参考资料”或“上下文”连同你的问题一起交给大模型。大模型基于这些提供的参考资料来生成最终答案并可以注明信息出自哪份文档。核心公式RAG 检索系统 大语言模型为什么需要 RAG解决大模型的根本痛点大模型的痛点RAG 如何解决知识过时/静态​模型训练后知识就冻结了。RAG 可以连接最新的、私有的知识库如公司文档、最新新闻实现知识实时更新。产生“幻觉”​模型可能编造看似合理但错误的信息。RAG 强制模型依据检索到的证据生成大幅减少胡编乱造。缺乏透明度/不可追溯​你不知道模型的答案从何而来。RAG 可以提供引用来源让答案可验证、可追溯。不了解私有/细分领域知识​通用模型不懂你公司的内部流程、产品细节。RAG 可以将这些私有数据作为检索库让模型“专业化”。RAG 的基本工作流程一个典型的 RAG 系统分为两个阶段索引预处理​ 和检索与生成运行时。第一阶段索引预处理一次性的加载文档收集所有知识源PDF、Word、网页、数据库等。分割文本将长文档切分成更小的、语义完整的“片段”或“块”。向量化使用嵌入模型将每个文本块转换为一个高维向量即“嵌入”。存储将这些向量及其对应的原始文本存入向量数据库。第二阶段检索与生成每次提问时用户提问。检索将用户问题同样用嵌入模型转换为向量。在向量数据库中搜索与问题向量最相似的几个文本块即“检索”。增强将检索到的相关文本块作为上下文与用户问题一起组合成新的提示。生成将组合好的提示发送给大语言模型让它基于给定的上下文生成最终答案。[你的知识库] - 分割 - 向量化 - 存入向量数据库 ↑ [你的问题] - 向量化 - 检索最相似的文本块 - 组合成提示 - [大模型] - 生成答案RAG 的优势准确性高答案基于事实依据更可靠。成本低无需为更新知识而重新训练大模型训练成本极高。实现简单架构清晰易于开发和集成。可解释性强“答案出自某某文档第X页”让人更信服。数据安全私有数据无需上传给模型厂商可留在本地。RAG vs 传统微调特性RAG微调知识更新​即时修改文档即可需要重新训练成本高防幻觉​好受限于检索内容一般模型仍可能自创可解释性​强有引用来源弱是模型内部参数实现速度​快天/周级别慢数据准备、训练周期长常见用途​知识库问答、客服、基于文档的分析让模型学习特定风格、格式或复杂推理模式通常两者可以结合使用用微调让模型更好地理解和遵循指令用RAG为它提供准确的外部知识。典型应用场景智能客服/问答机器人基于产品手册、FAQ文档回答用户问题。企业知识库助手员工可以快速查询公司制度、项目报告、会议纪要。学术研究助手基于大量论文库回答专业问题并提供引用。法律、医疗咨询辅助快速检索相关法条、病例生成参考意见。个人知识管理基于你的笔记、收藏的文章构建一个“第二大脑”。与你之前问题的关联你之前问到的rerank 模型就是 RAG 系统中用于优化“检索”步骤的一个高级组件。它在初步检索出一批相关文档后再进行一次精细排序挑出最相关的几个从而让最终生成答案的上下文质量更高。总结RAG 是一种让大模型“接地气”的关键技术。它通过引入外部知识源巧妙地弥补了大模型在事实性、时效性和专有知识方面的不足是当前构建企业级、高可靠AI应用最主流和实用的架构范式。rerank是必须的吗不是必须的但强烈推荐。​ 在大多数生产级RAG系统中rerank模型是显著提升答案准确性的关键优化组件而非基础必需品。简单来说没有rerankRAG系统能跑有了rerank它才能跑得好、答得准。核心作用从“找得多”到“找得准”RAG流程通常分为两步检索初步检索召回用向量搜索或关键词搜索从海量文档中快速找出Top-K例如20-100个​ 相关片段。目标是高召回率宁可多找不能漏掉。重排序Rerank用专门的rerank模型对初步检索的结果进行精细排序选出Top-N例如3-5个​ 最相关的片段送给大模型生成答案。目标是高精准率。类比就像找专家回答问题。没有rerank你用一个简单的关键词匹配找到20篇可能相关的文章全部扔给专家大模型专家需要自己从这堆质量参差不齐的材料里费力筛选。有rerank你先让一个擅长精读的助理rerank模型​ 快速读完这20篇文章挑出3篇最切题、质量最高的再交给专家。专家能更快、更准确地给出高质量答案。为什么需要Rerank向量检索的不足问题向量检索的局限Rerank模型的解决方式语义细微差别​可能混淆“苹果公司”和“水果苹果”因为向量空间上接近。能更好理解上下文和查询意图区分细微差异。关键词匹配偏差​查询“如何解决程序崩溃”可能检索到大量包含“崩溃”但讲的是经济崩溃的文章。基于交叉编码深度理解query和文档的关联性。多主题查询​查询“Python异步编程和机器学习区别”可能只偏向“异步编程”或“机器学习”其中一个主题。能同时评估文档与查询中多个子主题的相关性。文档长度影响​长文档可能因包含更多关键词而获得高向量相似度但关键信息可能只占一小部分。能判断文档中是否真正包含了查询所需的核心信息。如何决策你的项目需要Rerank吗场景建议说明原型验证/简单应用​可以不用​数据量小、问题简单直接使用向量检索的Top-5结果可能就足够了。优先跑通流程。生产级知识库/客服问答​强烈推荐使用​对答案准确性要求高文档库复杂。rerank能大幅减少“幻觉”和答非所问提升用户体验。高精度、专业领域​必须使用​法律、医疗、金融等领域容错率极低。需要最相关的证据支持rerank是必备过滤器。延迟敏感型应用​需要权衡​rerank会增加额外计算时间几十到几百毫秒。若对延迟要求极端苛刻需测试性能收益是否大于延迟成本。实践建议起步阶段先用纯向量检索搭建最小可行产品。效果瓶颈当发现大模型经常基于不相关上下文生成答案时引入rerank是性价比最高的优化手段。技术选型商业APICohere的Rerank API、Jina AI的Reranker等开箱即用效果稳定。开源模型BAAI/bge-reranker-v2-m3、Cohere/rerank-english-v3.0等可自行部署控制成本。经典架构“双路召回 Rerank”。同时使用向量检索语义匹配和关键词检索如BM25保证关键词匹配。合并两路结果去重后统一交给rerank模型进行精排。这是目前公认能最大化召回率和准确率的工业级方案。结论虽然RAG系统的基础流程检索-生成不需要rerank但若你追求可靠、准确、可用的生产级系统引入rerank模型几乎是不可或缺的一步。它用相对较小的计算开销换取了生成答案质量的巨大提升。检索策略RAG的检索策略完全由构建该RAG系统的工程师或团队来设计和实现。没有一个现成的“黑盒”会自动为你决定最佳策略你需要根据具体的应用场景、数据特点和性能要求自主选择和组合各种检索技术。简单来说你是检索策略的“总设计师”。你的角色策略架构师作为实现者你需要负责以下几个核心决策和实现步骤你需要做的决策可选的方案/组件实现方式1. 选择“检索器”类型​•向量检索器语义相似如用text-embedding模型•关键词检索器字面匹配如BM25/Elasticsearch•混合检索器结合两者编写代码来调用相应的库或服务如chromadb做向量检索elasticsearch做关键词检索。2. 设计检索流程​•简单检索单路向量检索•多路召回并行执行向量和关键词检索再合并•递归检索先检索大纲再根据大纲检索细节•迭代检索根据首轮答案发起新一轮检索设计程序逻辑控制不同检索器的调用顺序和结果合并方式。3. 优化排序Rerank​•是否加入Rerank模型•选择哪个Rerank模型如Cohere API、BGE-Reranker•在哪个环节Rerank对所有结果rerank还是对合并后结果rerank集成Rerank模型的API或本地部署的模型到你的检索流水线中。4. 设定参数​•检索数量K初步召回多少条如召回100条•返回数量N最终保留多少条给LLM如精排后选3条•相似度阈值低于多少分的结果丢弃在代码中配置这些超参数并通过实验确定最佳值。5. 上下文管理​•如何截断或组合检索到的文本块•如何避免重复•如何纳入元数据过滤如按日期、作者筛选编写后处理逻辑对检索结果进行清洗、去重、排序和格式化。一个典型的实现代码框架Python示例# 伪代码展示你作为实现者需要编写的核心逻辑 class RAGRetrievalStrategy: def __init__(self, vector_db, keyword_searcher, rerank_model): # 1. 初始化你选择的各种工具 self.vector_db vector_db # 例如 ChromaDB self.keyword_searcher keyword_searcher # 例如 Elasticsearch self.rerank_model rerank_model # 例如 BGE-Reranker def retrieve(self, query, top_k100, top_n5): # 2. 实现多路召回策略 vector_results self.vector_db.similarity_search(query, ktop_k) keyword_results self.keyword_searcher.search(query, sizetop_k) # 3. 实现结果合并策略如加权融合 combined_results self._merge_results(vector_results, keyword_results) # 4. 实现重排序策略 if self.rerank_model: reranked_results self.rerank_model.rerank(query, combined_results) final_contexts reranked_results[:top_n] else: final_contexts combined_results[:top_n] # 5. 实现上下文格式化 formatted_context self._format_context(final_contexts) return formatted_context def _merge_results(self, vec_results, kw_results): # 这里是你自定义的融合逻辑比如按分数加权、去重 pass def _format_context(self, results): # 这里是你自定义的提示词模板组装逻辑 pass你依赖的工具与组件虽然策略由你实现但你会依赖以下“积木”向量数据库提供向量检索能力如Chroma, Weaviate, Qdrant, Pinecone。嵌入模型将文本转换为向量如OpenAItext-embedding-3, BGE, Jina。传统搜索引擎提供关键词检索如Elasticsearch, Solr, BM25。Rerank 模型提供精排能力如Cohere Rerank API, BGE-Reranker。LLM最终生成答案如GPT-4, Claude, 本地LLM。你的工作就是将这些“积木”以合理的逻辑组装起来形成高效的检索流水线。实践建议从简单开始先用纯向量检索top_k5实现一个最简版本。评估效果用一批测试问题验证看检索到的上下文是否真的相关。引入优化如果发现召回不全加入关键词检索形成混合检索。如果发现精度不够引入Rerank模型。持续迭代检索策略是RAG系统的核心需要根据数据分布和业务反馈不断调优。总结RAG的检索策略是一个需要亲手设计和实现的系统工程。它考验的是你对业务需求的理解、对多种检索技术的掌握以及进行系统集成的工程能力。没有标准答案最佳策略取决于你的具体场景。向量模型https://blog.csdn.net/seanyang_/article/details/157466840使用示例我来写一个完整的 Embedding 模型使用示例涵盖本地模型和API调用两种方式以中文文本为例。1. 准备工作安装依赖pip install sentence-transformers torch transformers numpy # 如果使用API pip install openai2. 本地模型示例推荐示例1使用 Sentence-Transformers最简单from sentence_transformers import SentenceTransformer import numpy as np from sklearn.metrics.pairwise import cosine_similarity # 1. 加载模型会自动下载 # 中文模型推荐BAAI/bge-large-zh-v1.5 或 BAAI/bge-small-zh-v1.5 # 英文模型推荐all-MiniLM-L6-v2 model SentenceTransformer(BAAI/bge-small-zh-v1.5) # 轻量级中文模型 # 2. 准备文本 texts [ 今天天气真好我们去公园散步吧。, 明天的会议安排在下午三点。, 人工智能是当今最热门的技术之一。, 我喜欢在晴天出去运动。 ] # 3. 生成向量 embeddings model.encode(texts) print(f文本数量: {len(texts)}) print(f向量维度: {embeddings[0].shape}) print(f示例向量前10维: {embeddings[0][:10]}) # 4. 计算相似度 query 今天适合户外活动吗 query_embedding model.encode([query]) # 计算与所有文本的相似度 similarities cosine_similarity(query_embedding, embeddings)[0] print(\n相似度排名:) for i, (text, score) in enumerate(zip(texts, similarities)): print(f{i1}. [{score:.4f}] {text[:20]}...) # 5. 保存和加载向量 # 保存到文件 np.save(embeddings.npy, embeddings) # 加载 loaded_embeddings np.load(embeddings.npy)示例2使用 Transformers 原生库更灵活from transformers import AutoTokenizer, AutoModel import torch import torch.nn.functional as F # 1. 加载模型和分词器 model_name BAAI/bge-small-zh-v1.5 tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModel.from_pretrained(model_name) # 2. 编码函数 def get_embeddings(texts, batch_size32): 获取文本的向量表示 all_embeddings [] for i in range(0, len(texts), batch_size): batch_texts texts[i:ibatch_size] # 分词 encoded_input tokenizer( batch_texts, paddingTrue, truncationTrue, max_length512, # 根据模型调整 return_tensorspt ) # 计算 embedding with torch.no_grad(): model_output model(**encoded_input) # 使用 [CLS] token 的表示作为句子向量 embeddings model_output.last_hidden_state[:, 0] # 归一化提高余弦相似度准确性 embeddings F.normalize(embeddings, p2, dim1) all_embeddings.append(embeddings) return torch.cat(all_embeddings, dim0) # 3. 使用 texts [人工智能很有趣, 机器学习是AI的子领域] embeddings get_embeddings(texts) print(f向量维度: {embeddings[0].shape}) # 4. 计算相似度 similarity F.cosine_similarity(embeddings[0].unsqueeze(0), embeddings[1].unsqueeze(0)) print(f相似度: {similarity.item():.4f})3. API 调用示例OpenAIimport openai import os from typing import List import numpy as np # 设置API密钥 os.environ[OPENAI_API_KEY] your-api-key-here def get_openai_embeddings(texts: List[str], modeltext-embedding-3-small) - np.ndarray: 使用OpenAI Embedding API 模型选项 - text-embedding-3-small (1536维便宜) - text-embedding-3-large (3072维效果好) - text-embedding-ada-002 (旧版1536维) # 批量处理 batch_size 1000 # OpenAI一次最多2048个文本 all_embeddings [] for i in range(0, len(texts), batch_size): batch texts[i:ibatch_size] response openai.embeddings.create( modelmodel, inputbatch, encoding_formatfloat # 返回浮点数数组 ) batch_embeddings [data.embedding for data in response.data] all_embeddings.extend(batch_embeddings) return np.array(all_embeddings) # 使用 texts [ The weather is nice today., Artificial intelligence is transforming industries. ] embeddings get_openai_embeddings(texts) print(f向量形状: {embeddings.shape})4. 实战示例简易语义搜索import numpy as np from sentence_transformers import SentenceTransformer from sklearn.metrics.pairwise import cosine_similarity import json class VectorSearch: 简易向量搜索引擎 def __init__(self, model_nameBAAI/bge-small-zh-v1.5): self.model SentenceTransformer(model_name) self.embeddings None self.documents [] def add_documents(self, documents: list): 添加文档到搜索库 self.documents.extend(documents) new_embeddings self.model.encode(documents) if self.embeddings is None: self.embeddings new_embeddings else: self.embeddings np.vstack([self.embeddings, new_embeddings]) def search(self, query: str, top_k: int 5): 搜索相似文档 query_embedding self.model.encode([query]) # 计算余弦相似度 similarities cosine_similarity(query_embedding, self.embeddings)[0] # 获取top-k结果 top_indices np.argsort(similarities)[::-1][:top_k] results [] for idx in top_indices: results.append({ text: self.documents[idx], score: float(similarities[idx]), index: int(idx) }) return results def save(self, filepath: str): 保存索引 data { documents: self.documents, embeddings: self.embeddings.tolist() if self.embeddings is not None else None } with open(filepath, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse) def load(self, filepath: str): 加载索引 with open(filepath, r, encodingutf-8) as f: data json.load(f) self.documents data[documents] if data[embeddings]: self.embeddings np.array(data[embeddings]) # 使用示例 if __name__ __main__: # 1. 创建搜索器 searcher VectorSearch() # 2. 添加文档 docs [ Python是一种高级编程语言适合初学者学习。, 机器学习是人工智能的一个重要分支。, 深度学习使用神经网络进行模式识别。, 今天天气晴朗适合外出散步。, TensorFlow和PyTorch是流行的深度学习框架。 ] searcher.add_documents(docs) # 3. 搜索 query 有什么编程语言适合新手 results searcher.search(query, top_k3) print(f查询: {query}) print(搜索结果:) for i, r in enumerate(results, 1): print(f{i}. [{r[score]:.4f}] {r[text]}) # 4. 保存和加载 searcher.save(search_index.json)5. 性能优化技巧# 1. 批量处理 texts [文本1, 文本2, ...] # 大量文本 embeddings model.encode(texts, batch_size32) # 批处理提高速度 # 2. 设备选择 import torch device cuda if torch.cuda.is_available() else cpu model model.to(device) # 使用GPU加速 # 3. 精度权衡 embeddings model.encode(texts, precisionfp16) # 使用半精度节省内存 # 4. 缓存 from functools import lru_cache lru_cache(maxsize1000) def get_cached_embedding(text: str): return model.encode([text])[0]6. 不同场景的模型选择MODEL_CHOICES { # 中文场景 zh_small: BAAI/bge-small-zh-v1.5, # 768维速度快 zh_base: BAAI/bge-base-zh-v1.5, # 768维平衡 zh_large: BAAI/bge-large-zh-v1.5, # 1024维效果好 # 多语言/英文 multilingual: intfloat/multilingual-e5-large, english: all-MiniLM-L6-v2, # 384维英文专用 # 代码嵌入 code: microsoft/codebert-base, } def get_embedding_model(use_casezh_small): 根据使用场景选择模型 model_name MODEL_CHOICES.get(use_case, BAAI/bge-small-zh-v1.5) return SentenceTransformer(model_name)注意事项归一化比较余弦相似度前确保向量已归一化单位长度内存管理处理大量文本时注意内存使用模型大小大模型效果更好但更慢根据需求权衡文本清洗输入前可适当清洗文本去除特殊字符、统一大小写等这是最核心的使用模式。在实际RAG系统中还需要结合向量数据库如Chroma、Pinecone进行高效检索。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价