返回博客
人工智能 2025年4月11日 6 分钟阅读 · 1326 字

RAG 检索增强生成实战:用向量数据库构建企业知识库

从 Embedding 到检索排序,搭建基于私有数据的 AI 问答系统。

#RAG #向量数据库 #Embedding #知识库
本文由 AI 辅助生成,经人工审核发布

RAG 是什么

RAG(Retrieval-Augmented Generation,检索增强生成)是一种将外部知识库与大语言模型结合的技术。它通过在生成回答前检索相关文档,让 AI 能够基于私有数据回答问题,而不需要重新训练模型。

为什么需要 RAG

问题纯 LLMRAG
知识时效性训练数据截止后无法更新实时检索最新文档
私有数据无法访问企业内部数据检索私有知识库
幻觉问题可能编造信息基于真实文档回答
成本微调成本高无需训练,成本低
可溯源无法追溯信息来源引用具体文档段落

RAG 架构全流程

文档处理:PDF/Word/网页 → 文本提取 → 分块(Chunking) → Embedding → 存入向量数据库

查询流程:用户提问 → Query Embedding → 向量检索 → 取 Top-K 文档 → 拼接 Prompt → LLM 生成回答

文档切分策略

固定长度切分

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,        # 每块 500 字符
    chunk_overlap=50,      # 块间重叠 50 字符
    separators=["\n\n", "\n", "。", "!", "?", ",", " ", ""]
)

chunks = splitter.split_text(long_document)

参数选择建议

文档类型chunk_sizeoverlap说明
技术文档500-80050-100保持段落完整
代码文档300-50030-50按函数/类切分
FAQ 问答200-3000每条一个块
长篇论文800-1200100-200保留上下文
法律条文按条款0自然分界

语义切分

from langchain.text_splitter import SemanticChunker
from langchain.embeddings import OpenAIEmbeddings

splitter = SemanticChunker(
    OpenAIEmbeddings(),
    breakpoint_threshold_type="percentile",
    breakpoint_threshold_amount=95
)

chunks = splitter.split_text(document)

语义切分根据相邻句子的语义相似度决定切分点,效果优于固定长度,但成本更高。

Embedding 模型选择

主流模型对比

模型维度最大输入多语言部署方式价格
text-embedding-3-large30728191API$0.13/M tokens
text-embedding-3-small15368191API$0.02/M tokens
BGE-M310248192本地免费
M3E-base768512中英本地免费
Cohere embed v31024512API$0.10/M tokens

中文场景推荐

# 使用 OpenAI Embedding(效果稳定)
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# 使用本地 BGE 模型(免费、中文优化)
from langchain_huggingface import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(
    model_name="BAAI/bge-m3",
    model_kwargs={"device": "cuda"}
)

向量数据库对比

数据库类型部署方式适用规模特色
Chroma嵌入式本地<100万轻量、零配置
Pinecone云服务SaaS任意规模全托管、高性能
Weaviate开源自托管/云中大型混合检索
Milvus开源自托管超大规模分布式、高可用
Qdrant开源自托管/云中大型Rust 编写、高性能
pgvectorPG 扩展自托管中小型与 PostgreSQL 集成

Chroma 快速上手

import chromadb

client = chromadb.PersistentClient(path="./vector_db")
collection = client.get_or_create_collection(
    name="knowledge_base",
    metadata={"hnsw:space": "cosine"}
)

# 添加文档
collection.add(
    documents=["文档内容1", "文档内容2"],
    metadatas=[{"source": "file1.pdf"}, {"source": "file2.pdf"}],
    ids=["doc1", "doc2"]
)

# 检索
results = collection.query(
    query_texts=["用户问题"],
    n_results=5
)

检索优化

基础检索

def basic_retrieve(query: str, k: int = 5):
    """基础向量检索"""
    query_embedding = embeddings.embed_query(query)
    results = vectorstore.similarity_search_by_vector(
        query_embedding, k=k
    )
    return results

Hybrid Search(混合检索)

from langchain.retrievers import BM25Retriever, EnsembleRetriever

# 关键词检索(BM25)
bm25_retriever = BM25Retriever.from_documents(documents)
bm25_retriever.k = 5

# 向量检索
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

# 混合检索
ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, vector_retriever],
    weights=[0.3, 0.7]  # BM25 权重 30%,向量权重 70%
)

results = ensemble_retriever.invoke("用户问题")

重排序(Reranking)

from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank

# 先检索 Top-20,再重排序为 Top-5
compression_retriever = ContextualCompressionRetriever(
    base_retriever=vectorstore.as_retriever(search_kwargs={"k": 20}),
    base_compressor=CohereRerank(top_n=5)
)

results = compression_retriever.invoke("用户问题")

检索质量对比

方法召回率准确率延迟成本
纯向量检索
纯关键词检索
混合检索
混合+重排序最高最高较高

完整 RAG 实现

from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate

# 1. 准备检索器
retriever = vectorstore.as_retriever(
    search_type="similarity",
    search_kwargs={"k": 5}
)

# 2. 设计 Prompt
system_prompt = """你是一个知识库助手。根据以下检索到的上下文回答用户问题。
如果上下文中没有相关信息,请明确说明"根据现有资料,我无法回答这个问题"。
回答时请引用来源文档。

上下文:
{context}
"""

prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    ("human", "{input}"),
])

# 3. 构建 RAG 链
llm = ChatOpenAI(model="gpt-4o", temperature=0)
question_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriever, question_chain)

# 4. 提问
response = rag_chain.invoke({
    "input": "公司的请假制度是什么?"
})
print(response["answer"])

企业部署建议

维度建议
文档管理建立文档更新机制,定期重新索引
权限控制按部门/角色过滤检索范围
监控指标追踪检索命中率、回答满意度
成本控制缓存高频查询结果
评估体系构建 Q&A 测试集,定期评估准确率
容灾方案向量数据库备份与恢复

总结

RAG 是目前将大模型能力与企业私有数据结合的最实用方案。通过合理的文档切分、Embedding 模型选择、向量数据库选型和检索优化,可以构建出准确、高效、可溯源的 AI 知识库系统。随着 reranking 模型和混合检索技术的成熟,RAG 系统的准确率正在快速提升,已经在客服、知识管理、法律咨询等场景实现了生产级应用。