AI6 min read
RAG 技术详解:让大模型拥有你的私有知识
RAG 技术详解:让大模型拥有你的私有知识
RAG大模型向量数据库AI开发
RAG(Retrieval-Augmented Generation)是当前最热门的 AI 应用技术,让大模型能基于你的私有数据回答问题。
什么是 RAG?
RAG = 检索 + 生成
用户提问 → 检索相关文档 → 文档 + 问题 → 大模型 → 回答
为什么需要 RAG?
大模型的问题:
- 知识截止:不知道最新信息
- 没有私有数据:不知道你公司的文档
- 会编造答案:幻觉问题
RAG 解决这些问题:先检索相关文档,再让大模型基于文档回答。
RAG 架构
┌─────────────────────────────────────────┐
│ RAG 系统 │
├─────────────────────────────────────────┤
│ │
│ 离线阶段(索引构建) │
│ ┌─────┐ ┌──────┐ ┌──────────────┐ │
│ │文档 │ → │分块 │ → │向量化(Embedding)│ │
│ └─────┘ └──────┘ └──────┬───────┘ │
│ ↓ │
│ ┌──────────┐ │
│ │向量数据库 │ │
│ └──────────┘ │
│ │
│ 在线阶段(查询) │
│ ┌─────┐ ┌──────┐ ┌──────────────┐ │
│ │问题 │ → │向量化│ → │相似度检索 │ │
│ └─────┘ └──────┘ └──────┬───────┘ │
│ ↓ │
│ ┌──────────────────────┐ │
│ │相关文档 + 问题 → LLM │ │
│ └──────────┬───────────┘ │
│ ↓ │
│ ┌────────┐ │
│ │ 回答 │ │
│ └────────┘ │
└─────────────────────────────────────────┘
实现 RAG
1. 文档分块
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每块 500 字符
chunk_overlap=50 # 重叠 50 字符
)
chunks = splitter.split_documents(documents)
2. 向量化
from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
vectors = embeddings.embed_documents([chunk.page_content for chunk in chunks])
3. 存储到向量数据库
from langchain.vectorstores import FAISS
vectorstore = FAISS.from_documents(chunks, embeddings)
vectorstore.save_local("my_index")
4. 检索和回答
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o")
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectorstore.as_retriever(search_kwargs={"k": 3})
)
answer = qa_chain.run("公司的年假政策是什么?")
向量数据库选择
| 数据库 | 特点 | 适合场景 |
|---|---|---|
| FAISS | Facebook 开源,本地运行 | 原型开发、小规模 |
| Chroma | 轻量级,易上手 | 原型开发 |
| Pinecone | 云托管,易扩展 | 生产环境 |
| Weaviate | 开源,功能丰富 | 中大规模 |
| Milvus | 开源,高性能 | 大规模生产 |
分块策略
固定长度分块
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
按段落分块
splitter = RecursiveCharacterTextSplitter(
separators=["\n\n", "\n", "。", "!"],
chunk_size=500
)
按语义分块
from langchain.text_splitter import SemanticChunker
splitter = SemanticChunker(embeddings)
chunks = splitter.split_text(document)
Prompt 工程
RAG 的 Prompt 很关键:
prompt_template = """
基于以下文档内容回答用户问题。
如果文档中没有相关信息,请说"我无法根据现有文档回答这个问题"。
不要编造信息。
相关文档:
{context}
用户问题:{question}
回答:
"""
优化技巧
1. 优化分块大小
- 太小:丢失上下文
- 太大:检索不精确
- 推荐:300-1000 字符
2. 增加重叠
重叠确保跨块信息不丢失:
chunk_overlap = chunk_size * 0.1 # 10% 重叠
3. 混合检索
结合关键词检索和向量检索:
from langchain.retrievers import EnsembleRetriever
retriever = EnsembleRetriever(
retrievers=[vector_retriever, bm25_retriever],
weights=[0.7, 0.3]
)
4. 重排序
对检索结果重新排序:
from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank
reranker = CohereRerank()
retriever = ContextualCompressionRetriever(
base_compressor=reranker,
base_retriever=vectorstore.as_retriever()
)
实际应用
1. 企业知识库问答
员工问:公司的报销流程是什么?
RAG 检索到《财务报销制度》相关段落
LLM 基于文档回答具体流程
2. 客服机器人
用户问:如何退货?
RAG 检索到《退货政策》相关段落
LLM 基于政策回答退货流程
3. 代码文档问答
开发者问:这个 API 怎么用?
RAG 检索到 API 文档相关段落
LLM 基于文档给出使用示例
常见问题
1. 检索不到相关内容
- 检查分块是否合理
- 增加检索数量 k
- 尝试不同的 Embedding 模型
2. 回答不准确
- 优化 Prompt,要求基于文档回答
- 增加重排序步骤
- 检查文档质量
3. 响应太慢
- 减少检索数量
- 使用更快的 Embedding 模型
- 缓存常见问题
总结
RAG 是让大模型拥有私有知识的关键技术:
- 离线:文档分块 → 向量化 → 存储
- 在线:问题向量化 → 检索 → LLM 回答
掌握 RAG,就能构建基于企业私有数据的 AI 应用。