1. 什么是 RAG?
检索增强生成(Retrieval-Augmented Generation,简称 RAG)是一种将信息检索(或向量搜索)与大型语言模型(LLM)生成能力相结合的技术架构。其核心思想是:在 LLM 生成答案之前,先从外部知识库(如文档、数据库、网页)中检索出与用户问题最相关的信息片段,然后将这些信息作为上下文提供给 LLM,从而生成更准确、更具事实依据且能减少"幻觉"的答案。
简单来说,RAG 让 LLM 具备了"实时查资料"的能力。
2. RAG 的核心价值
- 减少幻觉(Hallucination):LLM 仅依赖其训练数据中的知识,可能生成看似合理但事实错误的内容。RAG 通过提供来自可信知识源的准确上下文,极大地降低了这种风险。
- 知识实时更新:LLM 的训练成本高昂,知识存在滞后性。RAG 可以随时更新其背后的知识库(如添加最新产品文档、新闻),让模型能够回答关于新知识的问题,而无需重新训练模型。
- 增强可控性与可解释性:系统可以记录为每次回答提供了哪些参考文档,增强了答案的可追溯性和可信度。开发者也能更好地控制模型的知识边界。
- 保护私有数据:企业可以将内部文档、代码库、客户数据作为知识库,而无需将这些敏感数据用于训练 LLM,只需在推理时安全地检索即可。
3. RAG 的基本工作流程
一个典型的 RAG 系统通常包含以下步骤:
-
索引(Indexing):
- 文档加载:从各种来源(PDF、Word、网页、数据库)加载文档。
- 文本分割(Chunking):将长文档切分成更小的、语义连贯的片段(chunks)。这是关键步骤,分割质量直接影响检索效果。
- 向量化(Embedding):使用嵌入模型(Embedding Model)将每个文本片段转换为高维向量(即向量表示)。
- 存储:将这些向量及其对应的原始文本存储到向量数据库(如 Pinecone、Weaviate、Milvus、Chroma)中。
-
检索(Retrieval):
- 当用户提出一个问题(Query)时,系统使用相同的嵌入模型将问题转换为查询向量。
- 在向量数据库中执行相似性搜索(如余弦相似度),找出与查询向量最相似的 K 个文本片段(及其源文档)。
-
增强(Augmentation):
- 将检索到的 top-K 个相关文本片段(作为上下文)与用户的原始问题组合,构造出一个增强的提示(Prompt)提交给 LLM。
-
生成(Generation):
- LLM 基于提供的上下文和问题,生成最终的回答。
#mermaid-svg-VSeFWVlYn53ZjPUi{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VSeFWVlYn53ZjPUi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VSeFWVlYn53ZjPUi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VSeFWVlYn53ZjPUi .error-icon{fill:#552222;}#mermaid-svg-VSeFWVlYn53ZjPUi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VSeFWVlYn53ZjPUi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VSeFWVlYn53ZjPUi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VSeFWVlYn53ZjPUi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VSeFWVlYn53ZjPUi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VSeFWVlYn53ZjPUi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VSeFWVlYn53ZjPUi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VSeFWVlYn53ZjPUi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VSeFWVlYn53ZjPUi .marker.cross{stroke:#333333;}#mermaid-svg-VSeFWVlYn53ZjPUi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VSeFWVlYn53ZjPUi p{margin:0;}#mermaid-svg-VSeFWVlYn53ZjPUi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-VSeFWVlYn53ZjPUi .cluster-label text{fill:#333;}#mermaid-svg-VSeFWVlYn53ZjPUi .cluster-label span{color:#333;}#mermaid-svg-VSeFWVlYn53ZjPUi .cluster-label span p{background-color:transparent;}#mermaid-svg-VSeFWVlYn53ZjPUi .label text,#mermaid-svg-VSeFWVlYn53ZjPUi span{fill:#333;color:#333;}#mermaid-svg-VSeFWVlYn53ZjPUi .node rect,#mermaid-svg-VSeFWVlYn53ZjPUi .node circle,#mermaid-svg-VSeFWVlYn53ZjPUi .node ellipse,#mermaid-svg-VSeFWVlYn53ZjPUi .node polygon,#mermaid-svg-VSeFWVlYn53ZjPUi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VSeFWVlYn53ZjPUi .rough-node .label text,#mermaid-svg-VSeFWVlYn53ZjPUi .node .label text,#mermaid-svg-VSeFWVlYn53ZjPUi .image-shape .label,#mermaid-svg-VSeFWVlYn53ZjPUi .icon-shape .label{text-anchor:middle;}#mermaid-svg-VSeFWVlYn53ZjPUi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VSeFWVlYn53ZjPUi .rough-node .label,#mermaid-svg-VSeFWVlYn53ZjPUi .node .label,#mermaid-svg-VSeFWVlYn53ZjPUi .image-shape .label,#mermaid-svg-VSeFWVlYn53ZjPUi .icon-shape .label{text-align:center;}#mermaid-svg-VSeFWVlYn53ZjPUi .node.clickable{cursor:pointer;}#mermaid-svg-VSeFWVlYn53ZjPUi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VSeFWVlYn53ZjPUi .arrowheadPath{fill:#333333;}#mermaid-svg-VSeFWVlYn53ZjPUi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VSeFWVlYn53ZjPUi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VSeFWVlYn53ZjPUi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VSeFWVlYn53ZjPUi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VSeFWVlYn53ZjPUi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VSeFWVlYn53ZjPUi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VSeFWVlYn53ZjPUi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VSeFWVlYn53ZjPUi .cluster text{fill:#333;}#mermaid-svg-VSeFWVlYn53ZjPUi .cluster span{color:#333;}#mermaid-svg-VSeFWVlYn53ZjPUi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VSeFWVlYn53ZjPUi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VSeFWVlYn53ZjPUi rect.text{fill:none;stroke-width:0;}#mermaid-svg-VSeFWVlYn53ZjPUi .icon-shape,#mermaid-svg-VSeFWVlYn53ZjPUi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VSeFWVlYn53ZjPUi .icon-shape p,#mermaid-svg-VSeFWVlYn53ZjPUi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VSeFWVlYn53ZjPUi .icon-shape .label rect,#mermaid-svg-VSeFWVlYn53ZjPUi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VSeFWVlYn53ZjPUi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VSeFWVlYn53ZjPUi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VSeFWVlYn53ZjPUi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} "原始文档
(知识库)"
"文本分割
(Chunking)"
"向量化
(Embedding)"
"向量数据库
(Vector DB)"
"用户提问
(Query)"
"向量化
(Embedding)"
"相似性检索
(Similarity Search)"
"检索到的相关上下文
(Top-K Chunks)"
"构造增强提示
(Prompt)"
"大语言模型
(LLM)"
"最终答案
(Answer)"
4. 关键组件与技术选型
- 文档加载器:LangChain Document Loaders、LlamaIndex、Unstructured。
- 文本分割器:按字符、递归按分隔符、按标记(Token)或基于语义的分割。
- 嵌入模型 :OpenAI
text-embedding-3-*、Cohere Embed、BGE(智源)、all-MiniLM-L6-v2(开源轻量)。 - 向量数据库:Pinecone(云服务)、Weaviate(开源)、Milvus(开源)、Chroma(轻量开源)、Qdrant。
- 大语言模型(LLM):GPT-4、Claude、Gemini 或开源模型如 Llama、Qwen、DeepSeek。
- 编排框架:LangChain、LlamaIndex 提供了构建 RAG 流水线的高级抽象。
5. 一个简单的代码示例(使用 LangChain)
以下是一个使用 LangChain 和 OpenAI 构建最小化 RAG 管道的示例:
python
# 环境准备:pip install langchain-openai langchain-chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_chroma import Chroma
from langchain_core.documents import Document
from langchain_core.prompts import ChatPromptTemplate
from langchain.chains.combine_documents import create_stuff_documents_chain
# 1. 模拟知识库文档
documents = [
Document(page_content="LangChain 是一个用于开发由大语言模型驱动的应用程序的框架。"),
Document(page_content="RAG 结合了检索和生成,以提高回答的准确性。"),
Document(page_content="向量数据库用于高效存储和检索嵌入向量。"),
]
# 2. 创建嵌入模型和向量存储
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(documents, embeddings)
# 3. 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
# 4. 定义 LLM
llm = ChatOpenAI(model="gpt-4o-mini")
# 5. 定义提示模板
prompt = ChatPromptTemplate.from_template("""
请根据以下上下文回答问题。如果上下文不包含相关信息,请说"根据已知信息无法回答"。
上下文:
{context}
问题:{input}
""")
# 6. 创建链
document_chain = create_stuff_documents_chain(llm, prompt)
# 模拟用户查询
query = "LangChain 是什么?"
# 检索上下文
retrieved_docs = retriever.invoke(query)
# 生成答案
context = "\n\n".join([doc.page_content for doc in retrieved_docs])
answer = document_chain.invoke({"context": context, "input": query})
print(f"问题:{query}")
print(f"答案:{answer}")
6. 进阶优化方向
基础的 RAG 可能面临"检索精度不足"、"上下文窗口限制"等问题,常见的优化策略包括:
- 查询转换:对原始查询进行重写、扩展或分解,以提升检索效果。
- 混合搜索(Hybrid Search):结合关键词搜索(如 BM25)和向量搜索,兼顾精确匹配和语义相似度。
- 重排序(Re-ranking):使用更精细的模型对初步检索结果进行重新排序,将最相关的片段排在前面。
- 上下文压缩:对检索到的长文档进行摘要或过滤,只保留最相关的部分,以节省上下文窗口。
- 多跳检索(Multi-hop Retrieval):对于复杂问题,进行多次检索-推理循环,逐步深入。
7. 总结
RAG 已成为构建基于私有知识、事实准确、可解释的 AI 应用的主流范式。它巧妙地弥补了 LLM 在事实性、时效性和数据隐私方面的短板。从简单的文档问答到复杂的智能客服、知识库助手,RAG 都扮演着核心角色。掌握其基本原理和实现,是开发现代 AI 应用的关键一步。