本文从 大模型应用开发技术路线清单 中拆分,聚焦”二、RAG 检索增强生成”部分。让模型能”查资料再回答”,解决幻觉和知识过时问题。
为什么 RAG 是必修课? 大模型有两个致命弱点:
幻觉 :不知道的事情也会编造答案
知识过时 :训练数据有截止日期,无法获取最新信息
RAG(Retrieval-Augmented Generation)的核心思想:先检索相关资料,再让模型基于资料生成回答 。
1 2 传统方式:用户问题 → LLM → 回答(可能幻觉) RAG 方式:用户问题 → 检索相关文档 → 拼接上下文 → LLM → 回答(有据可查)
RAG 解决了 80% 的企业知识问答需求 ,是大模型应用开发的第二优先级(仅次于 Prompt Engineering)。
一、RAG 基础架构 1.1 标准 RAG 流程 1 2 3 4 5 6 7 ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ 用户问题 │ → │ Query 改写 │ → │ 向量检索 │ └──────────────┘ └──────────────┘ └──────┬───────┘ ↓ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ LLM 生成 │ ← │ 拼接上下文 │ ← │ 重排序 │ └──────────────┘ └──────────────┘ └──────────────┘
两个阶段:
索引阶段 (离线):文档 → 分块 → Embedding → 存入向量数据库
检索阶段 (在线):用户问题 → Embedding → 向量检索 → 重排序 → 拼接 → 生成
1.2 索引阶段详解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain_openai import OpenAIEmbeddingsfrom langchain_qdrant import Qdrantwith open ("company_docs.md" , "r" ) as f: raw_text = f.read() splitter = RecursiveCharacterTextSplitter( chunk_size=500 , chunk_overlap=50 , separators=["\n\n" , "\n" , "。" , "," , " " ], ) chunks = splitter.split_text(raw_text)print (f"分成了 {len (chunks)} 个块" ) embeddings = OpenAIEmbeddings(model="text-embedding-3-small" ) vectorstore = Qdrant.from_texts( texts=chunks, embedding=embeddings, url="http://localhost:6333" , collection_name="company_docs" , )print ("索引完成!" )
1.3 检索阶段详解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from langchain_openai import ChatOpenAIdef rag_query (question: str , vectorstore, k=5 ): """标准 RAG 查询""" docs = vectorstore.similarity_search(question, k=k) context = "\n\n---\n\n" .join([doc.page_content for doc in docs]) llm = ChatOpenAI(model="gpt-4" , temperature=0 ) response = llm.invoke([ {"role" : "system" , "content" : "基于以下参考资料回答问题。如果参考资料中没有相关信息,请说明。" }, {"role" : "user" , "content" : f"参考资料:\n{context} \n\n问题:{question} " }, ]) return response.content answer = rag_query("公司的年假制度是什么?" , vectorstore)
二、RAG 核心技术详解 2.1 文本分块策略 分块是 RAG 系统的第一道关卡 ,分块质量直接决定检索质量。
策略
原理
适用场景
固定长度分块
按字符数/Token数切分
简单文本,快速原型
递归分块
按分隔符层级递归切分
结构化文档(推荐)
语义分块
根据语义相似度切分
长文、连贯文本
文档结构分块
按标题/段落/表格切分
技术文档、法律文件
1 2 3 4 5 6 7 8 9 10 11 12 13 splitter = RecursiveCharacterTextSplitter( chunk_size=500 , chunk_overlap=50 , separators=["\n\n" , "\n" , "。" , "." , " " ], )from langchain.text_splitter import MarkdownHeaderTextSplitter headers = [("#" , "H1" ), ("##" , "H2" ), ("###" , "H3" )] md_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers) md_chunks = md_splitter.split_text(markdown_content)
分块大小的经验值 :
文档类型
推荐 chunk_size
chunk_overlap
技术文档
300-500 字符
50-100
对话记录
200-400 字符
30-50
法律/学术
500-800 字符
100-150
代码
按函数/类切分
0
2.2 Embedding 模型选型 Embedding 模型将文本转为向量,是语义检索的基础。
模型
维度
最大长度
特点
OpenAI text-embedding-3-small
1536
8191
性价比高,英文强
OpenAI text-embedding-3-large
3072
8191
精度最高
BGE-M3
1024
8192
多语言、多粒度、多功能
Jina Embeddings v3
1024
8192
长文本优化
M3E
768
512
中文优化,开源
1 2 3 4 5 6 7 8 9 10 11 12 from langchain_community.embeddings import HuggingFaceBgeEmbeddings embeddings = HuggingFaceBgeEmbeddings( model_name="BAAI/bge-m3" , model_kwargs={"device" : "cuda" }, encode_kwargs={"normalize_embeddings" : True }, )from langchain_openai import OpenAIEmbeddings embeddings = OpenAIEmbeddings(model="text-embedding-3-small" )
选型建议 :
中文为主 → BGE-M3 或 text-embedding-3-large
预算有限 → text-embedding-3-small
私有化部署 → BGE-M3 (HuggingFace)
多语言 → BGE-M3 或 Jina v3
2.3 向量数据库对比
数据库
特点
适用场景
Milvus
功能最全,分布式,GPU 加速
大规模生产环境
Qdrant
Rust 实现,性能好,API 友好
中等规模,性能敏感
Chroma
最简单,嵌入式
开发/原型/小规模
Weaviate
内置混合搜索,GraphQL API
需要混合检索
pgvector
PostgreSQL 插件,复用现有基础设施
已有 PG 的团队
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from langchain_chroma import Chroma vectorstore = Chroma.from_texts(chunks, embeddings, persist_directory="./chroma_db" )from langchain_qdrant import QdrantVectorStore vectorstore = QdrantVectorStore.from_texts( chunks, embeddings, url="http://localhost:6333" , collection_name="my_docs" , )from langchain_milvus import Milvus vectorstore = Milvus.from_texts( chunks, embeddings, connection_args={"uri" : "./milvus_demo.db" }, )
2.4 相似度检索 1 2 3 4 5 6 7 8 9 10 docs = vectorstore.similarity_search("公司年假政策" , k=5 ) docs_and_scores = vectorstore.similarity_search_with_score("公司年假政策" , k=5 )for doc, score in docs_and_scores: print (f"分数: {score:.4 f} | 内容: {doc.page_content[:100 ]} ..." ) docs = vectorstore.max_marginal_relevance_search("公司年假政策" , k=5 , fetch_k=20 )
2.5 Query 改写 用户的原始问题往往不是最优的检索 Query,需要改写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 def hyde_rewrite (query, llm ): prompt = f""" 请针对以下问题,写一段假设性的回答(不需要准确,只需要格式和风格对): 问题:{query} """ hypothetical_answer = llm.invoke(prompt).content return hypothetical_answer def multi_query_rewrite (query, llm ): prompt = f""" 将以下问题拆分为 3 个不同角度的子问题,每行一个: 问题:{query} """ sub_queries = llm.invoke(prompt).content.strip().split("\n" ) return [q.strip() for q in sub_queries if q.strip()]def stepback_rewrite (query, llm ): prompt = f""" 针对以下具体问题,生成一个更通用、更高层次的问题: 具体问题:{query} """ return llm.invoke(prompt).content.strip()
2.6 重排序(Rerank) 向量检索是”粗排”,Rerank 是”精排”,显著提升准确率。
1 2 3 4 5 6 7 8 9 10 11 12 13 from langchain_cohere import CohereRerank reranker = CohereRerank(model="rerank-multilingual-v3.0" , top_n=3 ) docs = vectorstore.similarity_search(query, k=20 ) reranked_docs = reranker.compress_documents(docs, query)from langchain_community.cross_encoders import HuggingFaceCrossEncoder reranker = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-v2-m3" )
Rerank 的效果 :通常能将准确率提升 10-20%,是 RAG 系统的标准配置。
三、RAG 进阶技术 3.1 混合检索(Hybrid Search) 向量检索擅长语义理解,BM25 擅长关键词匹配。两者结合效果更好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from langchain.retrievers import EnsembleRetrieverfrom langchain_community.retrievers import BM25Retriever bm25_retriever = BM25Retriever.from_texts(chunks, k=10 ) vector_retriever = vectorstore.as_retriever(search_kwargs={"k" : 10 }) ensemble_retriever = EnsembleRetriever( retrievers=[bm25_retriever, vector_retriever], weights=[0.4 , 0.6 ], ) docs = ensemble_retriever.invoke("公司年假政策" )
何时需要混合检索?
用户问题包含专业术语、产品编号等精确关键词
向量检索召回率不够时
需要兼顾语义和字面匹配
3.2 GraphRAG(知识图谱增强) 用知识图谱增强检索,适合复杂关系推理 。
1 2 3 4 5 6 7 传统 RAG:用户问题 → 向量检索 → 回答 GraphRAG:用户问题 → 向量检索 + 图谱遍历 → 回答 优势: - 捕捉实体间的关系(A公司与B公司的合作) - 支持多跳推理(X的导师的学生是谁?) - 全局摘要能力(这批数据的整体趋势是什么)
GraphRAG 架构 :
1 2 3 文档 → 实体抽取 → 构建知识图谱 → 社区检测 → 社区摘要 ↓ 用户问题 → 全局/局部检索 → 拼接上下文 → LLM 生成
3.3 Agentic RAG Agent 控制检索策略,动态决定是否检索、检索什么、怎么检索 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def agentic_rag (query, tools ): """ Agent 根据问题复杂度决定: - 简单事实 → 直接回答 - 需要检索 → 选择最合适的知识库 - 复杂问题 → 多次检索 + 推理 """ prompt = f""" 你是一个知识问答助手。你可以使用以下工具: - search_kb(query): 搜索知识库 - search_web(query): 搜索网页 - calculate(expr): 数学计算 请分析问题,决定是否需要检索,选择合适的工具。 问题:{query} """
3.4 多模态 RAG 处理图片、表格、PDF 等非纯文本内容。
1 2 3 4 5 6 7 8 9 from docling.document_converter import DocumentConverter converter = DocumentConverter() result = converter.convert("financial_report.pdf" ) markdown_content = result.document.export_to_markdown()
3.5 评估框架 RAG 系统上线前必须评估。
1 2 3 4 5 6 7 8 9 10 11 12 13 from ragas import evaluatefrom ragas.metrics import faithfulness, answer_relevancy, context_precision results = evaluate( dataset=eval_dataset, metrics=[faithfulness, answer_relevancy, context_precision], )
指标
含义
理想值
Faithfulness
回答忠实于上下文的比例
> 0.9
Answer Relevancy
回答与问题的相关度
> 0.85
Context Precision
检索结果的精确度
> 0.8
Context Recall
检索结果的召回率
> 0.8
3.6 父页面检索(Parent Document Retriever) 检索时用小块(精确),生成时用大块(完整上下文)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from langchain.retrievers import ParentDocumentRetrieverfrom langchain.storage import InMemoryStorefrom langchain_text_splitters import RecursiveCharacterTextSplitter child_splitter = RecursiveCharacterTextSplitter(chunk_size=200 ) parent_splitter = RecursiveCharacterTextSplitter(chunk_size=1000 ) retriever = ParentDocumentRetriever( vectorstore=vectorstore, docstore=InMemoryStore(), child_splitter=child_splitter, parent_splitter=parent_splitter, ) docs = retriever.invoke("公司年假政策" )
四、RAG 系统优化 4.1 文档解析优化
工具
特点
适用场景
Docling
IBM 出品,结构保留好
PDF、Word、PPT
MinerU
中文优化,表格识别强
中文文档
Unstructured
通用,格式支持广
多格式混合
4.2 企业 RAG 冠军方案 1 2 3 4 5 架构:多路由 + 动态知识库 ├── 解析模块:Docling 优化 → 表格序列化 → 内容提取 ├── 检索模块:向量检索 → BM25 → LLM 重排序 → 父页面回溯 ├── 生成模块:思维链 + 结构化输出 → 指令细化 └── 调参:Embedding 模型选择 → 分块策略 → Top-K 优化
4.3 常见问题排查
问题
可能原因
解决方案
检索不到相关内容
分块太大/太小、Embedding 不适合
调整分块策略,换 Embedding 模型
检索到但回答不对
上下文拼接方式不好
改用父页面检索,优化 Prompt
回答幻觉
模型忽视上下文
强化 Prompt 约束,降低 Temperature
速度慢
检索量大、Rerank 慢
减少 Top-K,用更快的 Reranker
五、学习建议 动手路径 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Week 1: 搭一个最简单的 RAG ├── LangChain + Chroma + OpenAI ├── PDF 问答系统 └── 能跑通就行 Week 2: 优化检索质量 ├── 换 Embedding 模型(BGE-M3) ├── 加 Rerank(Cohere / BGE-reranker) ├── 加 Query 改写(HyDE / Multi-Query) └── 用 RAGAS 评估 Week 3: 生产化 ├── 换 Qdrant / Milvus ├── 混合检索 ├── 父页面检索 └── 监控和调参
推荐资源
上一篇:一、Prompt Engineering 下一篇:三、Agent 智能体 返回导航:大模型应用开发技术路线清单