Retrieval-Augmented Generation (RAG) 检索增强生成
一、通俗定义
检索增强生成:给大模型外挂外部知识库,回答前先从自有文档检索相关内容,再交给模型生成答案。 解决原生大模型两大痛点:
- 知识截止:模型训练数据有时间上限,不知道最新信息;
- 幻觉(Hallucination):凭空编造不存在的事实、数据。
你前面全套工具链(all-MiniLM-L6-v2 + RecursiveCharacterTextSplitter + HuggingFaceEmbeddings + Chroma)就是标准 RAG 底层组件。
二、完整两大阶段:索引阶段 + 查询阶段
阶段 1:离线索引(文档入库,一次性执行)
- 加载文档:PDF/Markdown/TXT/ 网页等原始资料
- Document Chunking 文档分块 用
RecursiveCharacterTextSplitter切小块,避免超长文本超出 Embedding 模型 512token 限制,保留局部完整语义,设置 overlap 防止逻辑断裂。 - Embedding 向量化 通过
HuggingFaceEmbeddings调用蒸馏轻量模型all-MiniLM-L6-v2,每段 chunk 转为 384 维数值向量。 - 存入向量数据库 Chroma/FAISS/Milvus 保存「文本 chunk + 对应向量」,支持快速相似度检索。
阶段 2:在线问答(用户提问实时流程)
- Query Embedding 用户问题编码成相同维度向量;
- 语义检索 Retrieval 在向量库计算余弦相似度,召回 Top-K 最相关文档片段;
- Prompt 拼接增强上下文 把检索到的真实文档片段 + 用户问题一起塞进 Prompt,限制模型只能基于提供的资料作答;
- LLM Generation 生成回答 大模型依据检索到的真实素材输出答案,大幅减少瞎编。
三、极简流程图
原始文档 → 分块 → Embedding 向量 → 向量库存储 用户提问 → 向量化 → 检索相似 Chunk → 拼接上下文 Prompt → LLM 生成答案
四、核心组件对应你之前学的内容
表格
| 环节 | 工具 / 模型 | 作用 |
|---|---|---|
| 分块 | RecursiveCharacterTextSplitter | 切割长文本,控制 token 长度 |
| 嵌入封装 | langchain_huggingface.HuggingFaceEmbeddings | LangChain 统一接口加载向量化模型 |
| 向量模型 | all-MiniLM-L6-v2 | 蒸馏轻量化语义编码,384 维归一化向量,快速余弦匹配 |
| 向量存储 | Chroma | 本地轻量向量数据库,存储并检索文本向量 |
五、RAG 的核心优势
- 消除幻觉 所有回答依托自有真实文档,模型不能随意编造数据、案例、条款;
- 动态更新知识 新增文档只需重新分块入库,不用重新微调 / 蒸馏大模型,成本极低;
- 降低微调成本 不需要大量标注数据训练大模型,纯检索方案轻量化落地;
- 节约上下文窗口 只检索相关片段,不用把全部文档喂给 LLM,节省 token 开销、提升速度、降低 API 费用;
- 可溯源 回答可以附带引用对应的原始文档片段,方便核验信息真伪。
六、基础 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 分层演进(行业分级)
- 基础 RAG(上面代码) 单次检索、简单拼接上下文,适合简单知识库;
- 进阶 RAG
- 重写 Query(Hyde/Query Expansion):优化检索语句提升召回;
- 分层分块(父子检索 Parent-Child):小块检索、大块提供完整上下文;
- 重排序 Rerank:检索后用交叉编码器过滤无关片段;
- 高级 Agentic RAG 搭配工具调用、多轮检索、自校验、反思,处理复杂多步骤问答。
八、常见局限与优化方向
- 检索不准 → 优化 chunk 大小 /overlap、使用 rerank 模型、更换更强 Embedding;
- 上下文溢出 → 限制 Top-K 数量、精简 chunk;
- 无关噪声片段 → 增加重排序过滤低相似度内容;
- 领域语义弱 → 使用领域微调 Embedding,而非通用 MiniLM。
九、一句话总结
RAG 依靠文档分块 + 蒸馏嵌入模型语义检索调取私有资料,给大模型提供真实外部上下文,是低成本解决大模型知识滞后、生成幻觉的主流工程方案。