Retrieval-Augmented Generation (RAG) 检索增强生成

Retrieval-Augmented Generation (RAG) 检索增强生成

一、通俗定义

检索增强生成:给大模型外挂外部知识库,回答前先从自有文档检索相关内容,再交给模型生成答案。 解决原生大模型两大痛点:

  1. 知识截止:模型训练数据有时间上限,不知道最新信息;
  2. 幻觉(Hallucination):凭空编造不存在的事实、数据。

你前面全套工具链(all-MiniLM-L6-v2 + RecursiveCharacterTextSplitter + HuggingFaceEmbeddings + Chroma)就是标准 RAG 底层组件。

二、完整两大阶段:索引阶段 + 查询阶段

阶段 1:离线索引(文档入库,一次性执行)

  1. 加载文档:PDF/Markdown/TXT/ 网页等原始资料
  2. Document Chunking 文档分块RecursiveCharacterTextSplitter 切小块,避免超长文本超出 Embedding 模型 512token 限制,保留局部完整语义,设置 overlap 防止逻辑断裂。
  3. Embedding 向量化 通过 HuggingFaceEmbeddings 调用蒸馏轻量模型 all-MiniLM-L6-v2,每段 chunk 转为 384 维数值向量。
  4. 存入向量数据库 Chroma/FAISS/Milvus 保存「文本 chunk + 对应向量」,支持快速相似度检索。

阶段 2:在线问答(用户提问实时流程)

  1. Query Embedding 用户问题编码成相同维度向量;
  2. 语义检索 Retrieval 在向量库计算余弦相似度,召回 Top-K 最相关文档片段;
  3. Prompt 拼接增强上下文 把检索到的真实文档片段 + 用户问题一起塞进 Prompt,限制模型只能基于提供的资料作答;
  4. LLM Generation 生成回答 大模型依据检索到的真实素材输出答案,大幅减少瞎编。

三、极简流程图

原始文档 → 分块 → Embedding 向量 → 向量库存储 用户提问 → 向量化 → 检索相似 Chunk → 拼接上下文 Prompt → LLM 生成答案

四、核心组件对应你之前学的内容

表格

环节 工具 / 模型 作用
分块 RecursiveCharacterTextSplitter 切割长文本,控制 token 长度
嵌入封装 langchain_huggingface.HuggingFaceEmbeddings LangChain 统一接口加载向量化模型
向量模型 all-MiniLM-L6-v2 蒸馏轻量化语义编码,384 维归一化向量,快速余弦匹配
向量存储 Chroma 本地轻量向量数据库,存储并检索文本向量

五、RAG 的核心优势

  1. 消除幻觉 所有回答依托自有真实文档,模型不能随意编造数据、案例、条款;
  2. 动态更新知识 新增文档只需重新分块入库,不用重新微调 / 蒸馏大模型,成本极低;
  3. 降低微调成本 不需要大量标注数据训练大模型,纯检索方案轻量化落地;
  4. 节约上下文窗口 只检索相关片段,不用把全部文档喂给 LLM,节省 token 开销、提升速度、降低 API 费用;
  5. 可溯源 回答可以附带引用对应的原始文档片段,方便核验信息真伪。

六、基础 RAG 代码完整串联(整合你所有知识点)

python

运行

复制代码
from langchain_huggingface import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma

# 1. 加载蒸馏嵌入模型 all-MiniLM-L6-v2
embeddings = HuggingFaceEmbeddings(
    model_name="all-MiniLM-L6-v2",
    model_kwargs={"device": "cpu"},
    encode_kwargs={"normalize_embeddings": True}
)

# 2. 定义token统计函数
def token_counter(text):
    return len(embeddings.client.tokenizer.encode(text))

# 3. 递归字符分块器
splitter = RecursiveCharacterTextSplitter(
    chunk_size=400,
    chunk_overlap=80,
    length_function=token_counter,
    separators=["\n\n", "\n", ". ", "! ", "? "]
)

# 自有知识库文本
docs_raw = """
Retrieval Augmented Generation (RAG) combines retrieval and LLM generation.
First split documents into chunks via RecursiveCharacterTextSplitter.
Then encode chunks with distilled embedding model all-MiniLM-L6-v2.
Vectors are stored in vector database like Chroma for semantic search.
When user asks a question, retrieve relevant chunks as context for LLM, reduce hallucination.
Knowledge distillation compresses large BERT into small MiniLM without heavy performance loss.
"""

# 分块
chunks = splitter.split_text(docs_raw)

# 构建向量库
vector_db = Chroma.from_texts(
    texts=chunks,
    embedding=embeddings,
    persist_directory="./rag_db"
)
vector_db.persist()

# 检索环节:用户查询
query = "What is RAG and how does MiniLM work in the pipeline?"
relevant_chunks = vector_db.similarity_search(query, k=2)

# 打印检索到的增强上下文
for idx, doc in enumerate(relevant_chunks):
    print(f"检索片段{idx+1}:\n{doc.page_content}\n")

七、RAG 分层演进(行业分级)

  1. 基础 RAG(上面代码) 单次检索、简单拼接上下文,适合简单知识库;
  2. 进阶 RAG
    • 重写 Query(Hyde/Query Expansion):优化检索语句提升召回;
    • 分层分块(父子检索 Parent-Child):小块检索、大块提供完整上下文;
    • 重排序 Rerank:检索后用交叉编码器过滤无关片段;
  3. 高级 Agentic RAG 搭配工具调用、多轮检索、自校验、反思,处理复杂多步骤问答。

八、常见局限与优化方向

  1. 检索不准 → 优化 chunk 大小 /overlap、使用 rerank 模型、更换更强 Embedding;
  2. 上下文溢出 → 限制 Top-K 数量、精简 chunk;
  3. 无关噪声片段 → 增加重排序过滤低相似度内容;
  4. 领域语义弱 → 使用领域微调 Embedding,而非通用 MiniLM。

九、一句话总结

RAG 依靠文档分块 + 蒸馏嵌入模型语义检索调取私有资料,给大模型提供真实外部上下文,是低成本解决大模型知识滞后、生成幻觉的主流工程方案。