RAG检索增强生成实战教程
RAG 应用开发完整指南 2026:从 0 到 1 构建检索增强生成系统
2026-04-14 · 约 14 分钟阅读
RAG 应用开发完整指南 2026:从 0 到 1 构建检索增强生成系统
RAG(检索增强生成,Retrieval-Augmented Generation)是目前最实用的 AI 应用架构之一。它结合了检索系统和大语言模型的优势,既能利用私有知识,又能避免幻觉。本文手把手教你从零构建一个生产级 RAG 系统。
什么是 RAG?
| 传统 LLM | RAG 系统 |
|---|---|
| 知识截止到训练数据 | 可以实时检索最新知识 |
| 容易产生幻觉 | 基于真实文档生成,更可信 |
| 无法访问私有数据 | 可以连接私有权限库 |
| 无法追溯信息来源 | 可以显示引用来源 |
核心流程:
用户问题 →
问题向量化 →
向量数据库检索相关文档 →
把问题 + 相关文档一起发给 LLM →
LLM 基于文档生成答案
RAG 技术栈(2026 年推荐)
#### 向量数据库
| 数据库 | 特点 | 适用场景 |
|---|---|---|
| Pinecone | 托管服务,简单易用 | 快速上手,中小项目 |
| Weaviate | 开源自托管,功能全 | 有技术团队,生产级 |
| Chroma | 轻量级,本地开发 | 原型验证,小数据量 |
| Qdrant | 高性能,Rust 编写 | 大规模,高并发 |
| pgvector | PostgreSQL 扩展 | 已用 PG,不想多运维 |
#### Embedding 模型
| 模型 | 提供商 | 维度 | 中文效果 | 成本 |
|---|---|---|---|---|
| text-embedding-3-small | OpenAI | 1536 | 好 | 低 |
| Cohere Embed v3 | Cohere | 1024 | 好 | 中 |
| 智谱 Embedding | 智谱 | 1024 | 很好 | 低 |
| 通义千问 Embedding | 阿里 | 1536 | 很好 | 低 |
#### LLM 模型
| 任务 | 推荐模型 |
|---|---|
| 简单问答 | GPT-4o Mini / Claude 3 Haiku |
| 复杂推理 | Claude 3.7 Sonnet / GPT-4o |
| 中文场景 | 通义千问 Plus / 豆包 Pro |
#### 框架
| 框架 | 特点 |
|---|---|
| LangChain | 生态最丰富,快速原型 |
| LlamaIndex | 专注 RAG,优化更好 |
| 自定义 | 完全可控,生产级 |
实战:从零构建 RAG 系统
我们构建一个技术文档问答系统,支持查询公司内部技术文档。
#### 步骤 1:项目初始化
mkdir rag-demo
cd rag-demo
python3 -m venv venv
source venv/bin/activate
pip install langchain openai chromadb tiktoken pypdf
#### 步骤 2:文档加载和切分
首先,把文档加载并切分成小块(Chunk):
from langchain.document_loaders import DirectoryLoader, PyPDFLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 1. 加载文档
loader = DirectoryLoader(
"./docs",
glob="**/*.{pdf,txt,md}",
loader_cls=PyPDFLoader, # 用合适的 loader
show_progress=True
)
documents = loader.load()
# 2. 切分文档
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # 每块 1000 token
chunk_overlap=200, # 重叠 200 token
length_function=len,
)
chunks = text_splitter.split_documents(documents)
print(f"加载了 {len(documents)} 个文档,切分成 {len(chunks)} 个块")
切分策略建议:
- 通用文档:chunk_size=1000, overlap=200
- 代码文档:chunk_size=1500, overlap=300
- 表格密集:chunk_size=800, overlap=150
#### 步骤 3:向量化和存储
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
# 初始化 Embedding 模型
embeddings = OpenAIEmbeddings(
model="text-embedding-3-small",
openai_api_key="your-api-key"
)
# 创建向量数据库
db = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./chroma_db"
)
# 持久化
db.persist()
#### 步骤 4:构建检索链
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
# 1. 初始化 LLM
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0,
openai_api_key="your-api-key"
)
# 2. 自定义提示词(关键!)
prompt_template = """你是一个专业的技术文档助手。请根据以下上下文回答用户的问题。
上下文:
{context}
用户问题:{question}
请按以下要求回答:
1. 只基于提供的上下文回答,不要编造
2. 如果上下文中没有答案,请说"抱歉,我在文档中没有找到相关信息"
3. 回答要简洁、准确、有针对性
4. 如果引用了具体段落,可以注明来源
答案:"""
PROMPT = PromptTemplate(
template=prompt_template,
input_variables=["context", "question"]
)
# 3. 创建检索链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 把检索到的文档直接塞入 prompt
retriever=db.as_retriever(
search_type="similarity",
search_kwargs={"k": 4} # 检索最相关的 4 个块
),
return_source_documents=True, # 返回源文档
chain_type_kwargs={"prompt": PROMPT}
)
#### 步骤 5:测试 RAG 系统
# 测试查询
result = qa_chain({"query": "如何配置 API 认证?"})
print("回答:", result["result"])
print("\n源文档:")
for doc in result["source_documents"]:
print("-", doc.metadata["source"], "(第", doc.metadata.get("page", "?") ,"页)")
print(" ", doc.page_content[:100], "...")
RAG 优化技巧
#### 1. 检索优化
| 技术 | 效果 | 实现难度 |
|---|---|---|
| MMR(最大边际相关性) | 平衡相关性和多样性 | 低 |
| HyDE(假设文档嵌入) | 改善问题和文档的语义 gap | 中 |
| 查询重写 | 用 LLM 优化用户问题 | 中 |
| 父文档检索 | 检索小块,返回父块完整上下文 | 中 |
MMR 检索示例:
retriever = db.as_retriever(
search_type="mmr",
search_kwargs={
"k": 4,
"fetch_k": 10,
"lambda_mult": 0.7
}
)
查询重写示例:
from langchain.chains import LLMChain
rewrite_prompt = PromptTemplate(
template="请把用户的问题改写得更清晰、更具体,便于检索相关文档。\n\n原问题:{question}\n\n改写后:",
input_variables=["question"]
)
rewrite_chain = LLMChain(llm=llm, prompt=rewrite_prompt)
# 使用
original_question = "那个认证怎么弄?"
rewritten = rewrite_chain.run(original_question)
print("改写后:", rewritten) # "如何配置 API 认证机制?"
result = qa_chain({"query": rewritten})
#### 2. 生成优化
提示词工程是关键:
好的提示词 = 角色 + 任务 + 约束 + 输出格式
角色:你是一个专业的技术文档助手
任务:根据上下文回答用户问题
约束:只基于上下文,不要编造,不知道就说不知道
格式:简洁、准确、注明来源
#### 3. 评估 RAG 质量
关键指标:
- 召回率(Recall):相关文档被检索到的比例
- 准确率(Precision):检索到的文档中有多少是相关的
- 答案正确率:人工评估答案是否正确
- 幻觉率:答案中编造信息的比例
简单评估脚本:
# 测试集
test_cases = [
{
"question": "如何配置 API 认证?",
"expected_answer": "需要在设置中配置 API Key",
"expected_sources": ["docs/api-guide.md"]
},
# ... 更多测试用例
]
for case in test_cases:
result = qa_chain({"query": case["question"]})
# 检查源文档
sources = [doc.metadata["source"] for doc in result["source_documents"]]
has_expected_source = any(s in case["expected_sources"] for s in sources)
print(f"问题:{case['question']}")
print(f"回答:{result['result']}")
print(f"源文档正确:{'✅' if has_expected_source else '❌'}")
print("---")
生产部署注意事项
#### 1. 向量数据库选择
| 规模 | 推荐方案 |
|---|---|
| < 10k 文档 | Chroma(本地) |
| 10k - 100k 文档 | Pinecone / Weaviate |
| > 100k 文档 | Qdrant / Weaviate 集群 |
#### 2. 成本控制
| 优化项 | 效果 |
|---|---|
| 用小维度 Embedding | 降本 30-50% |
| 缓存相似查询 | 降本 40-80% |
| 批量向量化 | 降本 20-30% |
#### 3. 安全和隐私
- 不要把敏感数据发给第三方 LLM
- 考虑用自托管模型(Llama 3、Qwen 等)
- 数据传输加密
- 访问权限控制
总结
RAG 是 2026 年最实用的 AI 应用架构:
- ✅ 技术成熟,生态丰富
- ✅ 可以利用私有知识
- ✅ 减少幻觉,更可信
- ✅ 成本可控,ROI 高
建议:
1. 从小规模开始,用 LangChain + Chroma 快速验证
2. 提示词工程是关键,花时间优化
3. 持续评估检索和生成质量
4. 生产环境考虑托管服务(Pinecone)或自托管(Weaviate)
可在本站查看更多 AI API 中转平台,找到最适合你的 RAG 系统底层模型。