RAG 技术详解:如何让大模型拥有“外置大脑“
RAG(检索增强生成)技术指南
目录
什么是 RAG?
RAG(Retrieval-Augmented Generation,检索增强生成)是一种将信息检索与语言生成相结合的 AI 技术。它通过在生成回答之前先从外部知识库检索相关信息,显著提升了大语言模型的回答质量和准确性。
核心理念
RAG = 检索(Retrieval) + 生成(Generation)
-
检索:从知识库中查找相关信息
-
生成:基于检索到的信息生成回答
为什么需要 RAG?
传统 LLM 的局限性:
-
知识截止 - 训练数据有时间限制
-
幻觉问题 - 可能生成虚假信息
-
缺乏专业性 - 通用知识多,专业知识少
-
无法更新 - 训练后知识固定
-
缺乏上下文 - 不了解特定业务场景
RAG 的优势:
-
✅ 实时获取最新信息
-
✅ 基于事实生成,减少幻觉
-
✅ 融入专业知识
-
✅ 知识可动态更新
-
✅ 提供引用来源
核心原理
基本思路
用户提问
↓
[检索模块] → 从知识库查找相关信息
↓
[增强提示词] → 问题 + 检索结果
↓
[生成模块] → LLM 生成回答
↓
返回答案(附引用)
技术特点
-
知识外置
-
知识存储在向量数据库
-
不需要重新训练模型
-
可随时更新知识
-
-
语义检索
-
使用向量相似度搜索
-
理解语义而非关键词匹配
-
支持模糊查询
-
-
上下文增强
-
检索结果作为上下文
-
提供生成依据
-
减少模型幻觉
-
技术架构
三层架构
┌─────────────────────────────────────┐
│ 应用层(Application) │
│ - 用户界面 │
│ - API 接口 │
│ - 业务逻辑 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ RAG 引擎层(Engine) │
│ - 查询处理 │
│ - 检索模块 │
│ - 提示词构建 │
│ - 生成模块 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 数据层(Data Layer) │
│ - 向量数据库 │
│ - 文档存储 │
│ - 嵌入模型 │
└─────────────────────────────────────┘
组件说明
1. 应用层
-
用户交互界面
-
API 服务
-
业务逻辑处理
2. RAG 引擎层
-
查询处理:理解用户问题
-
检索模块:查找相关信息
-
提示词构建:组合问题和检索结果
-
生成模块:LLM 生成回答
3. 数据层
-
向量数据库:存储文档向量
-
文档存储:原始文档
-
嵌入模型:文本向量化
工作流程
完整流程
1. 用户提问
↓
2. 查询预处理
- 文本清洗
- 意图识别
- 查询改写
↓
3. 向量检索
- 查询向量化
- 相似度搜索
- 返回 Top-K 结果
↓
4. 结果重排序
- 相关性评分
- 去重
- 选择最佳文档
↓
5. 构建提示词
- 系统指令
- 检索结果
- 用户问题
↓
6. LLM 生成
- 基于上下文生成
- 控制输出格式
↓
7. 后处理
- 格式化
- 引用标注
- 质量检查
↓
8. 返回答案
示例流程
用户问:公司 2024 年的销售目标是什么?
1. 查询向量化
"公司 2024 年销售目标" → [0.1, 0.5, -0.3, ...]
2. 检索相关文档
- 文档 1:2024 年销售计划.pdf(相似度 0.89)
- 文档 2:年度目标会议纪要.docx(相似度 0.85)
- 文档 3:Q1 销售报告.pdf(相似度 0.72)
3. 构建提示词
"""
基于以下信息回答问题:
【文档 1】2024 年销售目标为 1 亿元,同比增长 30%...
【文档 2】会议确定年度目标:第一季度 2000 万...
【文档 3】Q1 实际完成 2200 万...
问题:公司 2024 年的销售目标是什么?
"""
4. LLM 生成回答
"公司 2024 年的销售目标为 1 亿元,同比增长 30%。
其中第一季度目标 2000 万,实际完成 2200 万..."
5. 返回答案(附引用)
关键组件
1. 嵌入模型(Embedding Model)
作用:将文本转换为向量
常用模型:
| 模型 | 维度 | 特点 | 适用场景 |
|---|---|---|---|
| text-embedding-3-small | 1536 | 快速、便宜 | 一般场景 |
| text-embedding-3-large | 3072 | 精度高 | 专业场景 |
| BGE | 1024 | 中文优化 | 中文应用 |
| M3E | 768 | 轻量级 | 资源受限 |
2. 向量数据库
作用:存储和检索向量
主流选择:
| 数据库 | 特点 | 规模 | 成本 |
|---|---|---|---|
| Chroma | 轻量、易用 | 中小 | 免费 |
| Pinecone | 托管服务 | 大 | 付费 |
| Weaviate | 功能丰富 | 中大 | 免费/付费 |
| Milvus | 高性能 | 超大 | 免费 |
| FAISS | Facebook 开源 | 大 | 免费 |
3. 大语言模型
作用:生成最终回答
选择建议:
-
高质量:GPT-4、Claude 3
-
性价比:GPT-3.5、Claude
-
中文优化:文心一言、通义千问
-
本地部署:LLaMA、ChatGLM
4. 文档加载器
支持格式:
-
PDF、Word、Excel
-
TXT、Markdown
-
HTML、XML
-
JSON、CSV
-
数据库
5. 文本分割器
作用:将长文档切分为片段
分割策略:
# 按字符数分割
chunk_size = 1000
chunk_overlap = 200
# 按段落分割
保持段落完整性
# 按语义分割
使用 NLP 技术识别语义边界
应用场景
1. 智能客服
场景:企业产品咨询、售后支持
优势:
-
基于产品文档回答
-
答案准确可靠
-
可提供引用来源
案例:
用户:这款手机的电池容量是多少?
AI:根据产品规格文档,这款手机配备 5000mAh
电池,支持 65W 快充。(来源:产品规格书 v2.3)
2. 知识库问答
场景:企业内部知识管理
优势:
-
整合分散文档
-
快速查找信息
-
降低培训成本
案例:
员工:报销流程是什么?
AI:报销流程包括:1. 提交申请 2. 主管审批
3. 财务审核 4. 打款。(来源:财务制度手册)
3. 文档检索
场景:法律、医疗等专业领域
优势:
-
海量文档快速检索
-
语义理解更精准
-
支持复杂查询
4. 数据分析助手
场景:业务数据查询
优势:
-
自然语言查询
-
自动生成报告
-
数据可视化
5. 教育培训
场景:智能辅导、题库系统
优势:
-
个性化教学
-
即时答疑
-
知识点关联
6. 研发辅助
场景:代码检索、技术文档
优势:
-
代码片段检索
-
API 文档查询
-
技术方案推荐
优势与挑战
优势
1. 准确性高
-
✅ 基于事实生成
-
✅ 减少幻觉问题
-
✅ 可验证答案
2. 实时性强
-
✅ 知识即时更新
-
✅ 获取最新信息
-
✅ 时效性好
3. 专业性好
-
✅ 融入领域知识
-
✅ 支持专业场景
-
✅ 答案更精准
4. 可解释性强
-
✅ 提供引用来源
-
✅ 答案可追溯
-
✅ 增强信任度
5. 成本效益
-
✅ 无需重新训练
-
✅ 知识可复用
-
✅ 维护成本低
挑战
1. 检索质量
-
❌ 检索不准确影响生成
-
❌ 语义匹配有误差
-
❌ 长尾问题难处理
2. 上下文长度
-
❌ LLM 上下文限制
-
❌ 信息过多影响效果
-
❌ 需要精挑细选
3. 延迟问题
-
❌ 多步骤增加延迟
-
❌ 检索耗时
-
❌ 实时性要求高场景难满足
4. 数据质量
-
❌ 依赖知识库质量
-
❌ 需要数据清洗
-
❌ 更新维护成本
5. 复杂查询
-
❌ 多跳推理困难
-
❌ 需要多文档整合
-
❌ 逻辑推理有限
实现方案
方案 1:使用 LangChain(推荐)
特点:
-
组件丰富
-
生态完善
-
易于上手
安装:
pip install langchain langchain-community
pip install langchain-openai
pip install chromadb
方案 2:使用 LlamaIndex
特点:
-
专注 RAG
-
性能优秀
-
文档完善
安装:
pip install llama-index
方案 3:自建系统
特点:
-
完全可控
-
灵活定制
-
技术门槛高
技术栈:
-
向量库:FAISS / Milvus
-
嵌入模型:BGE / M3E
-
LLM:OpenAI API / 本地部署
代码示例
示例 1:使用 LangChain 实现基础 RAG
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
# 1. 加载文档
loader = TextLoader("documents/company_policy.txt")
documents = loader.load()
# 2. 分割文本
text_splitter = CharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
texts = text_splitter.split_documents(documents)
# 3. 创建向量存储
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
texts,
embeddings,
persist_directory="./chroma_db"
)
# 4. 创建 QA 链
llm = ChatOpenAI(model="gpt-3.5-turbo")
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectorstore.as_retriever(),
return_source_documents=True
)
# 5. 提问
query = "公司的年假政策是什么?"
result = qa_chain({"query": query})
print(f"答案:{result['result']}")
print(f"来源:{result['source_documents']}")
示例 2:自定义 RAG 流程
from langchain.embeddings import OpenAIEmbeddings
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
import chromadb
class CustomRAG:
def __init__(self, db_path, model_name="gpt-3.5-turbo"):
# 初始化组件
self.embeddings = OpenAIEmbeddings()
self.llm = ChatOpenAI(model=model_name)
# 加载向量数据库
self.client = chromadb.PersistentClient(path=db_path)
self.collection = self.client.get_or_create_collection("docs")
def retrieve(self, query, top_k=3):
"""检索相关文档"""
# 查询向量化
query_embedding = self.embeddings.embed_query(query)
# 相似度搜索
results = self.collection.query(
query_embeddings=[query_embedding],
n_results=top_k
)
# 返回文档内容
return results['documents'][0]
def build_prompt(self, query, contexts):
"""构建提示词"""
template = """基于以下信息回答问题:
{context}
问题:{question}
答案:"""
context_text = "\n\n".join(contexts)
return template.format(context=context_text, question=query)
def query(self, question):
"""完整查询流程"""
# 检索
contexts = self.retrieve(question)
# 构建提示词
prompt = self.build_prompt(question, contexts)
# 生成回答
response = self.llm.invoke(prompt)
return {
"answer": response.content,
"sources": contexts
}
# 使用示例
rag = CustomRAG(db_path="./chroma_db")
result = rag.query("公司产品有哪些?")
print(result["answer"])
示例 3:多文档检索
from langchain.document_loaders import (
PyPDFLoader,
Docx2txtLoader,
TextLoader
)
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
# 加载多种格式文档
loaders = [
TextLoader("docs/policy.txt"),
PyPDFLoader("docs/manual.pdf"),
Docx2txtLoader("docs/guide.docx")
]
documents = []
for loader in loaders:
documents.extend(loader.load())
# 创建向量库
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
documents,
embeddings,
persist_directory="./multi_docs_db"
)
# 查询
query = "如何申请休假?"
results = vectorstore.similarity_search(query, k=3)
for doc in results:
print(f"内容:{doc.page_content[:200]}")
print(f"来源:{doc.metadata}")
示例 4:带引用的 RAG
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.prompts import ChatPromptTemplate
# 定义提示词
system_prompt = """你是一个专业的助手。请基于以下上下文回答问题。
如果上下文中没有答案,请说明。
回答时请引用相关文档。
上下文:
{context}
"""
prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("human", "{input}")
])
# 创建链
question_answer_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriever, question_answer_chain)
# 查询
response = rag_chain.invoke({"input": "公司的晋升机制是什么?"})
print(f"答案:{response['answer']}")
print(f"来源文档:{response['context']}")
最佳实践
1. 文档处理
文档加载
# 使用合适的加载器
from langchain.document_loaders import DirectoryLoader
# 批量加载
loader = DirectoryLoader(
"docs/",
glob="**/*.pdf",
show_progress=True
)
documents = loader.load()
文本分割
# 优化分割策略
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # 每段 1000 字符
chunk_overlap=200, # 重叠 200 字符
length_function=len,
separators=["\n\n", "\n", "。", "!", "?", " ", ""]
)
2. 检索优化
混合检索
# 结合语义检索和关键词检索
from langchain.retrievers import EnsembleRetriever
from langchain.vectorstores import Chroma
from langchain.retrievers import BM25Retriever
# 向量检索
vector_retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={"k": 5}
)
# 关键词检索
bm25_retriever = BM25Retriever.from_documents(documents)
bm25_retriever.k = 5
# 混合检索
ensemble_retriever = EnsembleRetriever(
retrievers=[vector_retriever, bm25_retriever],
weights=[0.5, 0.5]
)
重排序
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain.cross_encoder import CrossEncoder
# 使用 CrossEncoder 重排序
compressor = CrossEncoderReranker(
model=CrossEncoder(model_name="cross-encoder/ms-marco-MiniLM"),
top_n=3
)
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=vectorstore.as_retriever()
)
3. 提示词优化
from langchain.prompts import PromptTemplate
template = """你是一个专业的知识助手。请基于提供的上下文回答问题。
要求:
1. 答案要准确、简洁
2. 如果上下文没有答案,请说明"根据现有资料无法回答"
3. 引用相关文档来源
4. 使用清晰的格式
上下文:
{context}
问题:{question}
答案:"""
prompt = PromptTemplate(
template=template,
input_variables=["context", "question"]
)
4. 性能优化
缓存
from langchain.cache import InMemoryCache
from langchain.globals import set_llm_cache
# 启用缓存
set_llm_cache(InMemoryCache())
批量处理
# 批量嵌入
from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
embeddings.embed_documents(large_text_list)
5. 质量评估
# 评估指标
- 检索准确率(Retrieval Precision)
- 答案相关性(Answer Relevance)
- 用户满意度(User Satisfaction)
- 响应时间(Response Time)
# A/B 测试
- 不同嵌入模型对比
- 不同分割策略对比
- 不同 LLM 对比
常见问题
Q1: RAG 和微调有什么区别?
RAG:
-
知识外置,动态更新
-
无需训练
-
适合知识密集型任务
微调:
-
知识内置,相对固定
-
需要训练数据
-
适合风格/任务适配
建议:优先使用 RAG,必要时结合微调。
Q2: 如何选择合适的嵌入模型?
考虑因素:
-
语言:中文选 BGE/M3E,英文选 OpenAI
-
性能:精度 vs 速度
-
成本:API 调用费用
-
部署:云端 vs 本地
Q3: 向量数据库如何选择?
小规模(<10 万文档):
-
Chroma(简单)
-
FAISS(高性能)
中等规模(10-100 万):
-
Weaviate
-
Pinecone
大规模(>100 万):
-
Milvus
-
Qdrant
Q4: 如何提高检索准确率?
-
优化文本分割
-
保持语义完整
-
合适 chunk 大小
-
-
使用混合检索
-
语义 + 关键词
-
-
重排序
-
CrossEncoder 精排
-
-
查询改写
-
扩展同义词
-
添加上下文
-
Q5: RAG 的成本如何?
主要成本:
-
LLM API 调用:$0.002-0.06/1K tokens
-
嵌入 API:$0.0001/1K tokens
-
向量数据库:免费 - 数百$/月
优化方法:
-
缓存常用查询
-
压缩上下文
-
选择性价比模型
Q6: 如何处理多轮对话?
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
# 在检索时考虑对话历史
query = f"{chat_history}\n{current_question}"
相关资源
官方文档
-
LangChain: https://python.langchain.com/
-
LlamaIndex: https://docs.llamaindex.ai/
-
Chroma: https://docs.trychroma.com/
学习资源
-
RAG 技术论文
-
LangChain 官方教程
-
向量数据库文档
社区资源
-
GitHub: RAG 相关项目
-
Hugging Face: 嵌入模型
-
Discord: LangChain 社区
总结
RAG 的核心价值
-
解决幻觉问题 - 基于事实生成
-
知识可更新 - 无需重新训练
-
专业领域应用 - 融入行业知识
-
可解释性强 - 提供引用来源
适用场景
✅ 推荐使用:
-
知识库问答系统
-
智能客服
-
文档检索
-
专业领域咨询
❌ 不推荐:
-
创意写作
-
开放式对话
-
简单问答
-
实时性要求极高场景
技术趋势
-
多模态 RAG - 支持图片、表格
-
Graph RAG - 结合知识图谱
-
Agentic RAG - 融合 Agent 能力
-
端侧 RAG - 本地部署优化
更多推荐


所有评论(0)