RAG 解决了什么问题

LLM 有两个顽固问题:知识截止(训练数据只到某个日期)和幻觉(编造不存在的事实)。RAG(Retrieval-Augmented Generation)用外部知识库解决了这两个问题——查询时实时检索相关文档,把文档内容作为上下文喂给 LLM。

flowchart TD
    A[📄 文档上传] --> B[✂️ 文本分块]
    B --> C[🧮 Embedding 向量化]
    C --> D[(🗄️ 向量数据库)]
    E[❓ 用户提问] --> F[🔍 检索相似文档]
    D --> F
    F --> G[📋 Top-K 文档]
    G --> H[🤖 LLM 生成答案]
    H --> I[✅ 带引用的回答]

技术栈选型

一个生产级 RAG 系统需要四个组件,每个都有多种可选方案:

组件作用推荐方案
文档处理解析+分块Unstructured, LlamaIndex
Embedding文本转向量BGE-M3, text-embedding-3-large
向量数据库存储和检索Milvus, Qdrant, Chroma
LLM生成答案GPT-4o, Claude, Qwen

关键决策一:如何分块

分块策略直接影响检索质量。分太细语义不完整,分太粗噪声太多:

策略适用场景示例
固定大小通用文档512 tokens, overlap 64
语义分块结构化文档按段落/章节分割
递归分割混合格式先按 \n\n,不够再按句子
from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,        # 每块 500 tokens
    chunk_overlap=50,      # 相邻块重叠 50 tokens
    separators=["\n\n", "\n", "。", ".", " "]
)
chunks = splitter.split_documents(documents)

关键决策二:检索策略

简单的向量相似度检索会漏掉相关文档。生产环境常用混合检索:

# 混合检索 = 向量检索 + BM25 关键词检索
from langchain.retrievers import EnsembleRetriever

dense_retriever = vector_store.as_retriever(search_kwargs={"k": 5})
sparse_retriever = BM25Retriever.from_documents(docs)

hybrid = EnsembleRetriever(
    retrievers=[dense_retriever, sparse_retriever],
    weights=[0.7, 0.3]  # 向量检索权重更高
)

检索后再用重排序模型(如 BGE-Reranker)对 Top-K 文档重新打分,准确率可提升 10-20%。

评估 RAG 系统的好坏

三个关键指标:

  1. 召回率:相关文档有没有被检索到
  2. 忠实度:生成的答案是否基于检索到的文档
  3. 相关性:答案有没有回答用户的问题

RAGAS 是一个流行的 RAG 评估框架,可以自动计算这些指标。

RAG 是目前对抗 LLM 幻觉问题研究现状 中最有效的方案之一。关于个人实践参考 搭建个人 RAG 知识库