人工智能之 RAG 知识详细解析
Retrieval-Augmented Generation (检索增强生成)-- 让大语言模型拥有实时知识的能力
目录
- RAG 概述
- RAG 核心架构
- RAG 工作流程详解
- RAG 关键技术组件
- RAG 核心算法与模型
- RAG 优化策略
- RAG 应用场景
- RAG 代码实现示例
- RAG 挑战与未来发展
- 总结
1. RAG 概述
1.1 什么是 RAG
RAG (Retrieval-Augmented Generation, 检索增强生成)是一种将信息检索 (Information Retrieval) 与自然语言生成 (Natural Language Generation) 相结合的技术框架. 它通过在生成回答之前, 先从外部知识库中检索相关信息, 然后将检索结果作为上下文提供给大语言模型 (LLM), 从而生成更准确, 更可靠, 更具时效性的回答.
1.2 为什么需要 RAG
| 问题 | 说明 |
|---|---|
| 知识截止日期 | LLM 训练数据有截止时间, 无法获取最新信息 |
| 幻觉问题 | LLM 可能生成看似合理但实际错误的内容 |
| 领域知识缺失 | 通用 LLM 缺乏专业领域 (如医疗, 法律) 的私有知识 |
| 可解释性不足 | 难以追溯 LLM 回答的信息来源 |
| 成本高昂 | 频繁微调 LLM 成本极高 |
1.3 RAG 的核心价值
- 实时知识更新: 无需重新训练模型, 只需更新知识库
- 减少幻觉: 基于检索到的真实文档生成回答
- 可追溯性: 每个回答都可以追溯到具体的知识来源
- 成本效益: 避免昂贵的模型微调
- 领域适配: 轻松接入私有/专业领域知识
1.4 RAG 的发展历程
2020 -- Facebook 提出 RAG 原始论文 | 2022 -- ChatGPT 引爆 LLM 应用, RAG 成为解决知识更新的主流方案 | 2023 -- LangChain, LlamaIndex 等框架成熟, RAG 工程化落地 | 2024 -- Advanced RAG (高级检索增强): 多路召回, 重排序, Agentic RAG | 2025 -- GraphRAG, Modular RAG, Agentic RAG 成为主流方向2. RAG 核心架构
2.1 经典 RAG 架构
+-------------------------------------------------------------------------+ | RAG 系统架构 | +-------------------------------------------------------------------------+ | | | +--------------+ +--------------+ +----------------------+ | | | 用户查询 |---->| 检索模块 |---->| 重排序/过滤模块 | | | | (Query) | | (Retrieval) | | (Reranking) | | | +--------------+ +--------------+ +----------------------+ | | ^ | | | | v | | +--------------+ +--------------+ +----------------------+ | | | 向量数据库 |<----| 嵌入模型 |<----| 知识库/文档 | | | |(Vector DB) | |(Embedding) | | (Knowledge Base) | | | +--------------+ +--------------+ +----------------------+ | | ^ | | | | | +----------------------------------------------------------------+ | | | 生成模块 (Generation) | | | | +--------------+ +--------------+ +--------------+ | | | | | 检索结果 |--->| 提示工程 |--->| LLM 模型 | | | | | |(Retrieved | | (Prompt | | (Generation) | | | | | | Context) | | Engineering)| | | | | | | +--------------+ +--------------+ +--------------+ | | | +----------------------------------------------------------------+ | | | | | v | | +----------------------------------------------------------------+ | | | 最终回答 (Answer) | | | +----------------------------------------------------------------+ | | | +-------------------------------------------------------------------------+2.2 离线阶段 (Indexing)
原始文档 --> 文档加载 --> 文本分割 --> 向量化 --> 向量存储 | | | | | | Loader Splitter Embedding Vector DB | (加载器) (分割器) (嵌入模型) (向量数据库)2.3 在线阶段 (Querying)
用户查询 --> 查询向量化 --> 相似度检索 --> 上下文组装 --> LLM生成 --> 回答3. RAG 工作流程详解
3.1 第一阶段: 数据预处理 (离线)
3.1.1 文档加载 (Document Loading)
支持多种文档格式:
- 文本文件: .txt, .md, .csv
- 办公文档: .pdf, .docx, .pptx, .xlsx
- 网页数据: HTML, JSON, XML
- 数据库: SQL, NoSQL 数据库
- API 数据: REST API, GraphQL
3.1.2 文本分割 (Text Splitting / Chunking)
文本分割是 RAG 中最关键的预处理步骤之一, 直接影响检索质量.
常见分割策略:
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 固定长度分割 | 按固定字符数或 token 数分割 | 通用场景 |
| 递归字符分割 | 按段落, 句子, 单词层级递归分割 | 保持语义完整性 |
| 语义分割 | 基于语义相似度进行分割 | 高质量需求 |
| 结构化分割 | 按文档结构 (标题, 段落) 分割 | 结构化文档 |
| Agentic 分割 | 使用 LLM 智能决定分割边界 | 复杂文档 |
重叠策略 (Overlap):
- 相邻 chunk 之间保留一定重叠内容
- 避免关键信息被截断在边界处
- 通常设置 10%-20% 的重叠比例
3.1.3 向量化 (Embedding)
将文本转换为高维向量表示, 使得语义相似的文本在向量空间中距离相近.
# 向量化示例 from sentence_transformers import SentenceTransformer model = SentenceTransformer('BAAI/bge-large-zh-v1.5') text = "人工智能是计算机科学的一个分支" embedding = model.encode(text) # 输出: 1024 维向量主流 Embedding 模型:
| 模型 | 维度 | 语言 | 特点 |
|---|---|---|---|
| text-embedding-3-large | 3072 | 多语言 | OpenAI, 性能优秀 |
| text-embedding-3-small | 1536 | 多语言 | OpenAI, 性价比高 |
| BAAI/bge-large-zh | 1024 | 中文 | 中文场景首选 |
| BAAI/bge-m3 | 1024 | 多语言 | 支持 100+ 语言 |
| nomic-embed-text-v1 | 768 | 多语言 | 开源, 性能强 |
| jina-embeddings-v3 | 1024 | 多语言 | 支持长文本 |
3.2 第二阶段: 检索 (Retrieval)
3.2.1 向量检索 (Vector Search)
基于向量相似度进行检索, 核心算法:
余弦相似度 (Cosine Similarity):
cosine(a, b) = (a . b) / (||a|| * ||b||)欧氏距离 (Euclidean Distance):
d(a, b) = sqrt(sum((a_i - b_i)^2))近似最近邻算法 (ANN):
| 算法 | 原理 | 特点 |
|---|---|---|
| HNSW | 分层可导航小世界图 | 高召回率, 内存占用大 |
| IVF | 倒排文件索引 | 平衡速度与精度 |
| PQ | 乘积量化 | 内存效率高 |
| DiskANN | 磁盘上的 ANN | 支持海量数据 |
3.2.2 混合检索 (Hybrid Search)
结合向量检索和关键词检索 (BM25/TF-IDF), 提升召回率.
向量检索结果 --+ +--> 融合排序 --> 最终检索结果 BM25 检索结果 --+融合策略:
- RRF (Reciprocal Rank Fusion): 倒数排名融合
- 加权融合: 为不同检索方式分配权重
- 交叉编码器重排序: 使用更精确的模型重新排序
3.2.3 多路召回 (Multi-Route Retrieval)
查询 --+--> 语义向量检索 +--> 关键词检索 (BM25) +--> 稀疏向量检索 (SPLADE) +--> 图检索 (GraphRAG) +--> 结构化数据检索 (SQL)3.3 第三阶段: 生成 (Generation)
3.3.1 提示工程 (Prompt Engineering)
经典 RAG 提示模板:
你是一个专业的问答助手. 请基于以下参考信息回答问题. 如果参考信息不足以回答问题, 请明确说明. 参考信息: {retrieved_context} 用户问题: {user_query} 请用中文回答, 并在回答末尾列出参考来源.3.3.2 上下文压缩 (Context Compression)
由于 LLM 上下文长度限制, 需要对检索结果进行压缩:
- Map-Reduce: 分块处理, 逐步汇总
- Stuff: 直接拼接所有文档
- Refine: 迭代精炼
- LLM 摘要: 用 LLM 压缩每个 chunk
4. RAG 关键技术组件
4.1 向量数据库 (Vector Database)
| 数据库 | 特点 | 适用场景 |
|---|---|---|
| Milvus | 开源, 分布式, 高性能 | 大规模生产环境 |
| Pinecone | 托管服务, 易用 | 快速原型开发 |
| Weaviate | 支持 GraphQL, 模块化 | 复杂查询场景 |
| Chroma | 轻量级, 易集成 | 本地开发/小型项目 |
| Qdrant | Rust 编写, 高性能 | 高性能需求 |
| Faiss | Meta 开源, 纯向量检索 | 研究/高性能计算 |
| pgvector | PostgreSQL 扩展 | 已有 PG 基础设施 |
| Elasticsearch | 支持混合检索 | 已有 ES 基础设施 |
4.2 文档处理框架
| 框架 | 功能 | 特点 |
|---|---|---|
| LangChain | 全链路 RAG 框架 | 生态丰富, 模块化 |
| LlamaIndex | 数据索引与检索 | 专注检索, 高级功能多 |
| Haystack | 端到端 NLP 流水线 | 企业级, 可视化 |
| Semantic Kernel | 微软出品 | 与 Azure 深度集成 |
4.3 重排序模型 (Reranker)
重排序模型对初步检索结果进行精排, 显著提升最终质量.
| 模型 | 说明 |
|---|---|
| Cohere Rerank | 商业 API, 效果优秀 |
| BAAI/bge-reranker-large | 开源中文重排序 |
| cross-encoder/ms-marco | 开源英文重排序 |
4.4 大语言模型 (LLM)
| 模型 | 提供商 | 特点 |
|---|---|---|
| GPT-4o | OpenAI | 综合能力最强 |
| Claude 3.5 | Anthropic | 长上下文, 推理强 |
| Gemini Pro | 多模态, 长上下文 | |
| DeepSeek-V3 | DeepSeek | 中文优秀, 性价比高 |
| Qwen2.5 | 阿里巴巴 | 中文场景首选 |
| Llama 3 | Meta | 开源, 可本地部署 |
5. RAG 核心算法与模型
5.1 原始 RAG 论文
论文: Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (Lewis et al., 2020)
核心思想:
- 预训练一个 seq2seq 模型 (如 BART/T5)
- 使用 DPR (Dense Passage Retrieval) 检索相关文档
- 将文档与查询拼接后输入生成模型
5.2 密集段落检索 (DPR)
论文: Dense Passage Retrieval for Open-Domain QA (Karpukhin et al., 2020)
核心思想:
- 使用双编码器 (Bi-Encoder) 分别编码查询和段落
- 通过对比学习训练, 使相关查询-段落对在向量空间中靠近
- 检索时使用 FAISS 进行近似最近邻搜索
查询 q --> Encoder_q --> 向量 v_q 文档 d --> Encoder_d --> 向量 v_d 相似度: sim(q, d) = v_q . v_d5.3 稀疏检索: BM25
BM25 公式:
BM25(q, d) = sum(IDF(q_i) * f(q_i, d) * (k_1 + 1) / (f(q_i, d) + k_1 * (1 - b + b * |d| / avgdl)))其中:
- f(q_i, d): 词项 q_i 在文档 d 中的频率
- |d|: 文档长度
- avgdl: 平均文档长度
- k_1 和 b: 可调参数
5.4 学习稀疏检索: SPLADE
SPLADE通过学习将文档扩展为稀疏向量, 结合 BM25 的效率和神经网络的语义理解能力.
5.5 图检索: GraphRAG
GraphRAG将知识构建为图结构, 通过图遍历进行检索:
实体识别 --> 关系抽取 --> 知识图谱构建 --> 图查询 (社区检测/遍历)优势:
- 捕捉实体间复杂关系
- 支持多跳推理
- 更好的全局理解
6. RAG 优化策略
6.1 检索优化
6.1.1 查询重写 (Query Rewriting)
原始查询: "这个产品的价格" | v 查询扩展: "这个产品的价格是多少? 产品定价, 费用, 收费标准"技术:
- HyDE (Hypothetical Document Embeddings): 生成假设文档, 用假设文档检索
- 查询扩展: 同义词扩展, LLM 改写
- 多查询生成: 生成多个相关查询并行检索
6.1.2 多路召回与融合
# RRF 融合示例 def reciprocal_rank_fusion(results_lists, k=60): scores = {} for results in results_lists: for rank, doc_id in enumerate(results): if doc_id not in scores: scores[doc_id] = 0 scores[doc_id] += 1 / (k + rank + 1) return sorted(scores.items(), key=lambda x: x[1], reverse=True)6.1.3 重排序优化
初步检索 Top-100 --> 重排序模型 --> 精选 Top-5 --> LLM 生成6.2 生成优化
6.2.1 上下文窗口管理
| 策略 | 说明 |
|---|---|
| 窗口滑动 | 动态调整上下文窗口 |
| 优先级排序 | 按相关性排序, 优先放入高相关文档 |
| 摘要压缩 | 对长文档进行摘要后再放入 |
6.2.2 引用生成 (Citation Generation)
让 LLM 在生成回答时标注信息来源:
根据[文档1]和[文档3]的信息, 该产品的价格为 199 元.6.3 高级 RAG 模式
6.3.1 Self-RAG
论文: Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection (Asai et al., 2023)
核心思想:
- LLM 自主决定是否需要检索
- 生成过程中插入反思 token
- 对检索结果和生成结果进行自我评估
查询 --> LLM 判断是否需要检索 | +-- 不需要 --> 直接生成 | +-- 需要 --> 检索 --> 生成 --> 评估相关性 --> 支持/不支持/不相关6.3.2 Corrective RAG
在检索结果质量不佳时, 自动转向网络搜索或其他知识源.
6.3.3 Agentic RAG
将 RAG 与 Agent 框架结合:
用户查询 | v Agent 规划: 需要哪些信息? | +-- 子查询 1 --> 检索 --> 结果 1 +-- 子查询 2 --> 检索 --> 结果 2 +-- 子查询 3 --> 检索 --> 结果 3 | v Agent 综合: 整合所有结果生成最终回答6.3.4 Modular RAG
将 RAG 系统拆分为可插拔的模块:
- 检索模块可替换
- 生成模块可替换
- 支持动态路由
7. RAG 应用场景
7.1 企业知识库问答
企业内部文档 (产品手册, 技术文档, 规章制度) | v RAG 系统 | v 员工问答: "请假流程是什么?", "如何申请服务器资源?"7.2 智能客服
- 基于产品 FAQ 和文档自动回答客户问题
- 减少人工客服工作量
- 7x24 小时服务
7.3 法律/医疗咨询
- 法律: 基于法条, 判例进行法律咨询
- 医疗: 基于医学文献, 临床指南辅助诊断
7.4 代码辅助
- 基于代码库进行智能问答
- 代码解释, Bug 修复建议
7.5 学术研究
- 文献综述自动生成
- 跨论文知识关联
7.6 个性化推荐
- 基于用户历史行为文档进行个性化回答
8. RAG 代码实现示例
8.1 基础 RAG 实现 (Python)
""" 基础 RAG 实现示例 依赖: pip install langchain chromadb sentence-transformers """ from langchain.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Chroma from langchain.llms import OpenAI from langchain.chains import RetrievalQA # ========== 1. 文档加载 ========== loader = TextLoader("./knowledge_base.txt") documents = loader.load() # ========== 2. 文本分割 ========== text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, # 每个 chunk 500 字符 chunk_overlap=50, # 重叠 50 字符 separators=["\n\n", "\n", "。", "!", "?", " ", ""] ) chunks = text_splitter.split_documents(documents) # ========== 3. 向量化 ========== embedding_model = HuggingFaceEmbeddings( model_name="BAAI/bge-large-zh-v1.5" ) # ========== 4. 向量存储 ========== vectorstore = Chroma.from_documents( documents=chunks, embedding=embedding_model, persist_directory="./chroma_db" ) # ========== 5. 检索器 ========== retriever = vectorstore.as_retriever( search_type="similarity", search_kwargs={"k": 5} # 返回 Top-5 ) # ========== 6. 构建 RAG 链 ========== qa_chain = RetrievalQA.from_chain_type( llm=OpenAI(), chain_type="stuff", retriever=retriever, return_source_documents=True ) # ========== 7. 查询 ========== query = "什么是 RAG 技术?" result = qa_chain({"query": query}) print("回答:", result["result"]) print("来源:", [doc.page_content[:100] for doc in result["source_documents"]])8.2 高级 RAG 实现 (含重排序)
""" 高级 RAG 实现: 多路召回 + 重排序 """ from langchain.retrievers import BM25Retriever, EnsembleRetriever from langchain_community.cross_encoders import HuggingFaceCrossEncoder from langchain.retrievers.document_compressors import CrossEncoderReranker from langchain.retrievers import ContextualCompressionRetriever # ========== 多路召回 ========== # 向量检索器 vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 20}) # BM25 检索器 bm25_retriever = BM25Retriever.from_documents(chunks) bm25_retriever.k = 20 # 融合检索器 (Ensemble) ensemble_retriever = EnsembleRetriever( retrievers=[bm25_retriever, vector_retriever], weights=[0.5, 0.5] ) # ========== 重排序 ========== cross_encoder = HuggingFaceCrossEncoder( model_name="BAAI/bge-reranker-large" ) compressor = CrossEncoderReranker( model=cross_encoder, top_n=5 ) # 压缩检索器 (检索 + 重排序) compression_retriever = ContextualCompressionRetriever( base_compressor=compressor, base_retriever=ensemble_retriever ) # ========== 使用 ========== relevant_docs = compression_retriever.get_relevant_documents(query)8.3 使用 LlamaIndex 实现 RAG
""" 使用 LlamaIndex 实现 RAG 依赖: pip install llama-index """ from llama_index.core import VectorStoreIndex, SimpleDirectoryReader from llama_index.core.node_parser import SentenceSplitter from llama_index.embeddings.huggingface import HuggingFaceEmbedding from llama_index.llms.openai import OpenAI # 加载文档 documents = SimpleDirectoryReader("./docs").load_data() # 创建索引 index = VectorStoreIndex.from_documents( documents, embed_model=HuggingFaceEmbedding(model_name="BAAI/bge-large-zh-v1.5"), transformations=[SentenceSplitter(chunk_size=512, chunk_overlap=50)] ) # 创建查询引擎 query_engine = index.as_query_engine( llm=OpenAI(model="gpt-4"), similarity_top_k=5 ) # 查询 response = query_engine.query("解释 RAG 的工作原理") print(response)8.4 Self-RAG 简化实现
""" Self-RAG 简化概念实现 """ class SelfRAG: def __init__(self, llm, retriever): self.llm = llm self.retriever = retriever def need_retrieval(self, query): """判断是否需要检索""" prompt = f"""判断以下问题是否需要外部知识才能回答. 问题: {query} 如果需要检索请回答'是', 否则回答'否'.""" response = self.llm.generate(prompt) return "是" in response def retrieve(self, query): """执行检索""" return self.retriever.get_relevant_documents(query) def is_relevant(self, query, document): """判断文档是否与查询相关""" prompt = f"""判断以下文档是否与问题相关. 问题: {query} 文档: {document[:200]} 相关请回答'是', 否则回答'否'.""" response = self.llm.generate(prompt) return "是" in response def generate(self, query): """生成回答""" if not self.need_retrieval(query): return self.llm.generate(f"请回答: {query}") docs = self.retrieve(query) relevant_docs = [d for d in docs if self.is_relevant(query, d.page_content)] if not relevant_docs: return "抱歉, 没有找到相关信息." context = "\n\n".join([d.page_content for d in relevant_docs[:3]]) prompt = f"""基于以下信息回答问题: {context} 问题: {query}""" return self.llm.generate(prompt)9. RAG 挑战与未来发展
9.1 当前挑战
| 挑战 | 说明 | 解决方案方向 |
|---|---|---|
| 多跳推理 | 需要跨多个文档进行推理 | GraphRAG, Agentic RAG |
| 长文档处理 | 超长文档的分割和检索 | 长上下文模型, 层次化索引 |
| 多模态 RAG | 图像, 视频等非文本数据 | 多模态 Embedding |
| 实时性 | 知识更新的延迟 | 流式索引, 实时同步 |
| 评估困难 | 缺乏统一的评估标准 | RAGAS, ARES 等评估框架 |
| 幻觉问题 | 即使有检索, LLM 仍可能编造 | 更严格的约束生成 |
| 成本优化 | Embedding 和 LLM 调用成本高 | 模型蒸馏, 缓存策略 |
9.2 评估指标
| 指标 | 说明 |
|---|---|
| Context Precision | 检索到的上下文中相关 chunk 的比例 |
| Context Recall | 回答中引用的信息占所有相关 chunk 的比例 |
| Faithfulness | 生成内容与检索内容的一致性 |
| Answer Relevance | 回答与问题的相关性 |
| Latency | 端到端响应时间 |
评估框架:
- RAGAS: 自动化 RAG 评估框架
- ARES: 基于 LLM 判断的评估
- TruLens: 可解释性评估
9.3 未来发展方向
- Agentic RAG: RAG 与智能体深度结合, 支持复杂任务规划
- GraphRAG 普及: 知识图谱与 RAG 的融合成为标配
- 多模态 RAG: 支持图像, 音频, 视频的检索增强
- 联邦 RAG: 分布式知识库的安全检索
- 自适应 RAG: 系统自主学习最优检索策略
- RAG 即服务 (RAGaaS): 标准化的 RAG 云服务
10. 总结
RAG 核心要点回顾
+-------------------------------------------------------------+ | RAG 核心公式 | +-------------------------------------------------------------+ | | | RAG = 检索(Retrieval) + 增强(Augmentation) + 生成(Generation) | | | | 回答 = LLM(用户查询 + 检索到的相关知识) | | | +-------------------------------------------------------------+关键成功因素
- 高质量的文档预处理: chunk 大小, 重叠策略, 元数据标注
- 合适的 Embedding 模型: 根据语言和场景选择
- 有效的检索策略: 混合检索, 重排序, 查询优化
- 精准的提示工程: 清晰的指令和上下文组织
- 持续的评估迭代:基于真实用户反馈优化
