Appearance
RAG 实战:构建智能知识库问答系统
RAG(Retrieval-Augmented Generation,检索增强生成)是当前 AI 应用最热门的技术之一。它解决了 LLM 知识截止和幻觉问题,让 AI 能够基于你的私有数据回答问题。本文将带你实战构建一个 RAG 系统。
什么是 RAG?
RAG = 检索 + 生成
用户问题 → 检索相关文档 → 拼接到 Prompt → LLM 生成回答核心优势:
- 知识实时更新:不需要重新训练模型
- 减少幻觉:基于真实数据回答
- 领域定制:针对特定业务场景
- 数据隐私:数据不离开你的控制
核心组件
1. 文档加载器
支持多种格式:
- 文本文件(txt, md, csv)
- 文档(PDF, Word, PowerPoint)
- 网页
- 数据库
python
from langchain.document_loaders import (
TextLoader,
PDFLoader,
WebBaseLoader,
NotionDBLoader
)
# 加载文本
loader = TextLoader("docs/intro.md")
docs = loader.load()
# 加载 PDF
pdf_loader = PDFLoader("docs/manual.pdf")
pdf_docs = pdf_loader.load()
# 加载网页
web_loader = WebBaseLoader("https://example.com")
web_docs = web_loader.load()2. 文档分割器
将长文档切分为小块:
python
from langchain.text_splitter import (
RecursiveCharacterTextSplitter,
MarkdownTextSplitter
)
# 按字符分割
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
splits = splitter.split_documents(docs)3. 嵌入模型
将文本转换为向量:
python
from langchain.embeddings import OpenAIEmbeddings
from langchain.embeddings import HuggingFaceEmbeddings
# OpenAI Embeddings(需要 API key)
embeddings = OpenAIEmbeddings()
# 开源 Embeddings(本地运行)
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)4. 向量数据库
存储和检索向量:
选择:
- Chroma:简单易用,本地运行
- Pinecone:托管服务,性能好
- Qdrant:开源,功能强大
- Weaviate:混合搜索
- FAISS:Meta 开源,高性能
python
from langchain.vectorstores import Chroma
# 创建向量库
vectorstore = Chroma.from_documents(
documents=splits,
embedding=embeddings,
persist_directory="./chroma_db"
)
# 检索
results = vectorstore.similarity_search(
"如何部署 RAG 系统?",
k=3 # 返回前 3 个结果
)实战项目:企业知识库问答
系统架构
用户界面
↓
RAG 应用
↓
向量数据库 (Chroma)
↓
LLM (GPT-4o / Claude 3.5)代码实现
1. 初始化项目
bash
mkdir rag-knowledge-base
cd rag-knowledge-base
# 创建虚拟环境
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 安装依赖
pip install langchain chromadb openai tiktoken2. 配置
python
# config.py
import os
from dotenv import load_dotenv
load_dotenv()
# LLM 配置
LLM_MODEL = os.getenv("LLM_MODEL", "gpt-4o")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# 嵌入配置
EMBEDDING_MODEL = "text-embedding-3-small"
# 向量库配置
CHROMA_PERSIST_DIR = "./chroma_db"
CHROMA_COLLECTION_NAME = "knowledge_base"
# RAG 配置
CHUNK_SIZE = 1000
CHUNK_OVERLAP = 200
TOP_K = 33. 文档处理
python
# document_processor.py
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
class DocumentProcessor:
def __init__(self, config):
self.config = config
self.embeddings = OpenAIEmbeddings(
model=config.EMBEDDING_MODEL
)
self.splitter = RecursiveCharacterTextSplitter(
chunk_size=config.CHUNK_SIZE,
chunk_overlap=config.CHUNK_OVERLAP
)
def process_documents(self, documents):
"""分割文档"""
return self.splitter.split_documents(documents)
def create_vectorstore(self, documents, persist=True):
"""创建向量存储"""
splits = self.process_documents(documents)
vectorstore = Chroma.from_documents(
documents=splits,
embedding=self.embeddings,
persist_directory=self.config.CHROMA_PERSIST_DIR if persist else None,
collection_name=self.config.CHROMA_COLLECTION_NAME
)
return vectorstore4. RAG 查询
python
# rag_query.py
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
class RAGQuery:
def __init__(self, config, vectorstore):
self.config = config
self.vectorstore = vectorstore
self.llm = ChatOpenAI(
model=config.LLM_MODEL,
temperature=0.3
)
self._setup_chain()
def _setup_chain(self):
"""设置 RAG 链"""
prompt = PromptTemplate(
template="""你是一个专业的知识库助手。
根据以下检索到的文档回答问题。如果文档中没有答案,就说"我没有找到相关信息"。
文档:
{context}
问题:{question}
回答:""",
input_variables=["context", "question"]
)
self.chain = RetrievalQA.from_chain_type(
llm=self.llm,
chain_type="stuff",
retriever=self.vectorstore.as_retriever(
search_kwargs={"k": self.config.TOP_K}
),
return_source_documents=True,
chain_type_kwargs={"prompt": prompt}
)
def query(self, question):
"""查询"""
result = self.chain({"query": question})
return {
"answer": result["result"],
"sources": [
doc.metadata.get("source", "unknown")
for doc in result["source_documents"]
]
}5. 主应用
python
# app.py
from document_processor import DocumentProcessor
from rag_query import RAGQuery
from langchain.document_loaders import TextLoader
import config
def main():
print("📚 企业知识库问答系统")
# 加载文档
print("\n📖 加载文档...")
loader = TextLoader("docs/company_rules.md")
docs = loader.load()
# 处理文档
print("🔨 处理文档...")
processor = DocumentProcessor(config)
vectorstore = processor.create_vectorstore(docs)
# 初始化查询
print("✅ 初始化查询系统...")
rag = RAGQuery(config, vectorstore)
# 交互循环
while True:
question = input("\n❓ 请输入问题(或 'quit' 退出): ")
if question.lower() == "quit":
break
# 查询
result = rag.query(question)
print(f"\n💡 回答: {result['answer']}")
print(f"📄 来源: {', '.join(result['sources'])}")
if __name__ == "__main__":
main()优化技巧
1. 改进检索质量
python
# 混合检索(向量 + 关键词)
retriever = vectorstore.as_retriever(
search_type="similarity_score_threshold",
search_kwargs={
"k": 5,
"score_threshold": 0.7
}
)2. 重排序(Rerank)
python
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import CohereRerank
compressor = CohereRerank(top_n=3)
retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=vectorstore.as_retriever()
)3. 查询扩展
python
# 生成多个相关查询
related_queries = generate_queries(question)
all_results = []
for q in [question] + related_queries:
results = vectorstore.similarity_search(q, k=2)
all_results.extend(results)
# 去重
unique_results = remove_duplicates(all_results)4. 缓存
python
from langchain.cache import RedisCache
from langchain.globals import set_llm_cache
# Redis 缓存
set_llm_cache(RedisCache(redis_url="redis://localhost:6379"))部署选项
1. 本地部署
bash
# 使用 Streamlit
pip install streamlit
streamlit run app.py
# 使用 Gradio
pip install gradio
python app.py2. 云部署
- Vercel + Vercel AI SDK
- FastAPI + Docker
- AWS / GCP / Azure
3. 微服务
将 RAG 组件分离:
- 文档处理服务
- 向量检索服务
- LLM 推理服务
成本优化
选择合适的 Embedding 模型
- OpenAI:
text-embedding-3-small(便宜) - 开源:
sentence-transformers/all-MiniLM-L6-v2
- OpenAI:
缓存常见问题
- Redis / SQLite
批量处理
- 批量嵌入,减少 API 调用
混合检索
- 向量检索 + BM25(关键词)
扩展功能
多模态 RAG
- 图像检索
- 音频检索
实时更新
- 自动监控文档变化
- 增量更新向量库
用户反馈
- 收集用户反馈
- 微调检索策略
学习资源
总结
RAG 是构建企业级 AI 应用的核心技术。通过本文,你应该能够:
- 理解 RAG 的核心概念
- 搭建一个基本的 RAG 系统
- 优化检索和生成质量
- 部署到生产环境
下一步,你可以:
- 添加更多文档源
- 实现实时更新
- 构建用户友好的界面
有问题欢迎讨论! 🚀