乐于分享
好东西不私藏

RAG 技术全解析-github源码开箱即用

RAG 技术全解析-github源码开箱即用

RAG 技术全解析

让大模型先「查资料」再回答

从零理解检索增强生成(Retrieval-Augmented Generation)——原理、实现与关键技术点一网打尽

标签:大语言模型 · 语义检索 · 向量数据库 · LangChain · Python 实战

最近有大家说到关于AI引用开发的知识点太零散,不适合系统性学习,针对大家的反馈我在github上开源了一些AI学习的demo,简单易懂,里面设计了很多启发性的问题帮助大家理解学习,后会持续更新,欢迎大家留言交流。

地址:https://github.com/share-budaozhe/AI-DevelopmentCourse

RAG链接:https://github.com/share-budaozhe/AI-DevelopmentCourse/tree/master/rag-demo

 

目录

1. 什么是 RAG?——先讲一个考试的比喻

2. RAG 的核心原理

3. RAG 完整架构图解

4. 完整实现:一步步搭建你的第一个 RAG 系统

5. 五大关键技术点深度解析

6. RAG vs 微调:该选哪个?

7. 常见坑与优化技巧

8. 总结与进阶方向

第1章什么是 RAG?——先讲一个考试的比喻

想象你参加一场开卷考试。普通学生(传统大模型)只靠脑子里记住的知识作答,如果题目考的内容超出了记忆范围,就只能凭感觉"猜"——这就是大模型的"幻觉"(Hallucination)问题。

而聪明的学生(RAG 系统)会在作答前先翻阅参考书:先检索相关页面,再结合书上内容生成答案。这样的回答既有理有据,又能覆盖最新知识。

RAG(Retrieval-Augmented Generation)= 检索 + 增强 + 生成 在大模型生成回答之前,先从外部知识库中检索出最相关的信息,把这些信息"塞"进提示词,让模型基于真实材料来回答问题。

RAG 解决了哪些问题?

•🕰️ 知识截止问题:大模型训练数据有时间截止点,RAG 可以实时接入最新文档

•🌀 幻觉问题:模型乱编答案?RAG 强迫它基于真实来源作答,大幅降低幻觉

•🏢 私有知识问题:企业内部文档、产品手册不在训练集里,RAG 轻松接入私有库

•💰 成本问题:全量微调模型极其昂贵,RAG 只需维护一个知识库即可更新知识

•🔎 可追溯性:每条回答都能标注来源文档,用户可自行核实

•⚡ 快速迭代:更新知识库即可更新系统,无需重新训练模型

第2章RAG 的核心原理

RAG 的本质是一个「先检索、再生成」的两阶段流程。整个系统由两大部分组成:

阶段一:离线构建知识库(Indexing)

1.文档加载:把 PDF、Word、网页、数据库等各种格式的文档导入系统

2.文本切分(Chunking):把长文档切成若干小段(Chunk),每段通常 200~500 个 token

3.向量化(Embedding):用嵌入模型把每个文本段转为一个高维向量(数字数组)

4.存入向量数据库:把向量和原文一起存入 Faiss / Chroma / Milvus 等数据库

阶段二:在线问答(Retrieval + Generation)

5.用户提问:用户输入一个问题

6.问题向量化:用同一个 Embedding 模型把问题也变成向量

7.相似度检索:在向量数据库中找到与问题向量最"接近"的 Top-K 个文本段

8.构建提示词:把检索到的文本段 + 原始问题拼接成新的 Prompt

9.LLM 生成回答:把 Prompt 发给大语言模型,生成有据可查的答案

💡 向量之间的"距离"代表语义相似度:向量越接近,文本含义越相似。这样即使用户用不同词语提问,也能找到语义相关的文档。

第3章RAG 完整架构图解

图1:RAG 整体架构——左侧为离线知识库构建流程,右侧为在线检索生成流程

数据流说明

RAG 系统中数据的流向如下:

•【离线阶段】原始文档 → 文本切分 → 向量化(Embedding Model)→ 存入向量数据库

•【在线阶段】用户提问 → 问题向量化 → 在向量数据库中做相似度匹配 → 取出 Top-K 段落

•【生成阶段】检索结果 + 用户问题 → 构造 Prompt → 送入 LLM → 输出最终回答

图2:向量 Embedding 可视化——语义相似的文本在向量空间中距离更近

第4章完整实现:一步步搭建你的第一个 RAG 系统

我们用 Python + LangChain + ChromaDB + OpenAI 来演示一个最小可用的 RAG 系统。整个流程分为 5 步:

📦 第一步:安装依赖

pip install langchain langchain-openai chromadb tiktoken pypdf

📄 第二步:加载并切分文档

from langchain.document_loaders import PyPDFLoader, TextLoader

from langchain.text_splitter import RecursiveCharacterTextSplitter

# 1. 加载 PDF 文档

loader = PyPDFLoader("your_document.pdf")

pages = loader.load()

# 2. 递归字符切分——优先按段落、句号切分

splitter = RecursiveCharacterTextSplitter(

chunk_size=500,#每段最多 500 个字符

chunk_overlap=50,#相邻段重叠 50 字符,避免语义割断

separators=["\n\n","\n", "。", ".", " "]

)

chunks = splitter.split_documents(pages)

print(f"共切分出 {len(chunks)} 个文本段")

🔢 第三步:向量化并存入数据库

from langchain_openai import OpenAIEmbeddings

from langchain.vectorstores import Chroma

# 3. 初始化 Embedding 模型(也可换成本地模型)

embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")

# 4. 构建向量数据库(自动完成 Embedding + 存储)

vectorstore = Chroma.from_documents(

documents=chunks,

embedding=embeddings,

persist_directory="./chroma_db"#持久化到磁盘

)

vectorstore.persist()

print("知识库构建完成!")

🔍 第四步:检索 + 生成(核心逻辑)

from langchain_openai import ChatOpenAI

from langchain.chains import RetrievalQA

from langchain.prompts import PromptTemplate

# 5. 加载已有向量库

vectorstore = Chroma(

persist_directory="./chroma_db",

embedding_function=OpenAIEmbeddings()

)

# 6. 定义检索器(Top-K=3)

retriever = vectorstore.as_retriever(

search_type="similarity",

search_kwargs={"k":3}# 取最相似的 3 段

)

# 7. 自定义 Prompt 模板

prompt_template = """你是一个专业助手。请根据以下参考资料回答问题。

如果资料中没有相关信息,请直接说'我不知道',不要编造。

参考资料:

{context}

问题:{question}

回答:"""

PROMPT = PromptTemplate(

template=prompt_template,

input_variables=["context","question"]

)

# 8. 构建 RAG Chain

llm = ChatOpenAI(model="gpt-4o", temperature=0)

qa_chain = RetrievalQA.from_chain_type(

llm=llm,

retriever=retriever,

chain_type_kwargs={"prompt":PROMPT},

return_source_documents=True#返回来源,方便追溯

)

# 9. 问答!

result = qa_chain.invoke({"query": "请介绍一下这份文档的主要内容"})

print("回答:", result["result"])

print("\n来源文档:")

for doc in result["source_documents"]:

print(f"-{doc.metadata['source']} 第{doc.metadata['page']}页")

💡 不想用 OpenAI?把 Embedding 换成 HuggingFaceEmbeddings(model_name='BAAI/bge-m3'),LLM 换成 Ollama 本地模型即可完全离线运行!

第5章五大关键技术点深度解析

🔑 关键技术一:文本切分策略(Chunking)

切分粒度直接决定检索质量。切太大:噪声多;切太小:上下文不完整。

策略

适用场景

优点

缺点

固定大小切分

均匀文本

简单快速

可能切断句子

递归字符切分(推荐)

通用文档

优先按自然边界切

段落长度不均

语义切分

技术文档

语义完整性最好

计算成本高

结构化切分

Markdown/HTML

保留文档结构

依赖格式规范

💡 一般推荐使用"递归字符切分",设置 chunk_size=300~500,chunk_overlap=50~100,既能保证语义完整,又避免切断句子。

🔑 关键技术二:向量嵌入(Embedding)

Embedding 是把文字变成数字向量的过程,是 RAG 的灵魂。质量直接影响检索准确率。

示例:

"苹果是水果"→[0.82, -0.14, 0.37, 0.91, -0.55, 0.23]

"香蕉也是水果" →[0.79, -0.18, 0.41, 0.88, -0.51, 0.27]

# 两个向量高度相似(余弦相似度 ≈ 0.99),因为语义相近

模型

维度

语言

特点

text-embedding-ada-002

1536

多语言

OpenAI 经典模型,性价比高

text-embedding-3-large

3072

多语言

OpenAI 最新,精度更高

BAAI/bge-m3

1024

中英双语

开源免费,中文效果最佳

moka-ai/m3e-base

768

中文

轻量级,本地部署首选

🔑 关键技术三:向量数据库(Vector Database)

向量数据库专门用于存储和高效检索高维向量。核心能力是近似最近邻(ANN)搜索——在数百万向量中快速找到最相似的几个。

数据库

特点

适用场景

Chroma

轻量,Python 原生,开箱即用

开发测试、小项目

Faiss (Facebook)

极速,支持 GPU 加速

大规模离线检索

Milvus

分布式,企业级

亿级向量生产环境

Pinecone

全托管云服务

快速上线,无需运维

Qdrant

Rust 编写,高性能+payload 过滤

需要元数据过滤场景

pgvector

PostgreSQL 扩展

已有 PG 环境的团队

🔑 关键技术四:检索策略优化

基础的向量相似度检索并不总是最好的选择,有几种进阶策略可以大幅提升效果:

•🔀 混合检索(Hybrid Search):向量检索 + 关键词检索(BM25)双路并行,用 RRF 算法融合排序,兼顾语义理解和精确匹配

•🔁 重排序(Re-ranking):先用向量粗检索 Top-20,再用 Cross-Encoder 精排找出真正相关的 Top-3,准确率提升显著

•🌐 父子文档检索(Parent-Child):小段用于精准检索,大段用于完整上下文。检索到小段后,自动扩展为其所属的大段送给 LLM

•❓ 问题增强(Query Expansion):用 LLM 把用户的原始问题改写成多个角度的子问题,分别检索再合并,覆盖更广的知识面

🔑 关键技术五:Prompt 工程

Prompt 是连接检索结果与 LLM 生成的桥梁。好的 Prompt 能让模型严格基于来源回答,坏的 Prompt 则可能让模型忽略检索内容。

⚠️ 不指定"基于资料回答"时,模型容易混入训练集里的旧知识,导致答案偏离文档内容!

推荐的 Prompt 模板结构:

你是一个严谨的知识库助手。

【规则】

1. 只根据「参考资料」中的内容回答问题

2. 如果资料中没有答案,回答'根据现有资料无法回答该问题'

3. 回答时注明来自哪段资料(如:据第2段所述...)

【参考资料】

{context}

【用户问题】

{question}

【你的回答】

第6章RAG vs 微调:该选哪个?

这是实际项目中最常见的选型困惑。一句话总结:知识更新用 RAG,行为/风格调整用微调。

维度

RAG

微调(Fine-tuning)

知识更新成本

✅ 更新文档即可,零训练

❌ 需要重新训练,费时费钱

幻觉控制

✅ 有外部来源约束

❌ 仍可能产生幻觉

私有知识

✅ 天然支持

⚠️ 需谨慎防止数据泄露

回答风格定制

⚠️ 靠 Prompt 调整

✅ 深度定制语气/格式

复杂推理能力

⚠️ 受检索质量限制

✅ 可训练特定推理能力

部署复杂度

⚠️ 需要维护向量库

✅ 推理时无需额外组件

费用

💰 API + 向量存储

💰💰💰 GPU 训练成本极高

💡 实际生产系统通常选择 RAG + 微调组合:微调用于塑造模型人格和格式风格,RAG 用于注入实时知识。

第7章常见坑与优化技巧

❌ 坑1:Chunk 切得太大或太小

症状:检索到的段落要么内容太泛无关,要么语义不完整。

解法:一般设置 chunk_size=300~500,chunk_overlap=10%~20%。可以实验几组看哪个 Recall 最高。

❌ 坑2:Embedding 模型与检索语言不匹配

症状:用英文 Embedding 模型处理中文文档,检索准确率极差。

解法:中文场景优先用 BGE-M3 或 M3E-Base 等专门支持中文的模型。

❌ 坑3:Top-K 设置不合理

症状:K太小漏掉关键信息;K太大塞满 Context Window,LLM 注意力分散。

解法:先设 K=4~6,再根据 Context Window 大小调整。使用 Rerank 进行二次精排。

❌ 坑4:文档预处理不干净

症状:PDF 解析出大量乱码、页眉页脚、表格破损。

解法:使用 pymupdf4llm 或 unstructured 库解析,加入清洗规则过滤噪声。

❌ 坑5:忽略元数据过滤

症状:用户问今年的政策,却检索到5年前的旧文档。

解法:存储时记录 date、department、doc_type 等元数据,检索时加 filter 条件。

第8章总结与进阶方向

📌 核心要点回顾

10.RAG = 文档切分 → Embedding → 向量存储 → 语义检索 → LLM 生成,两阶段流程缺一不可

11.切分策略、Embedding 模型、检索方式、Prompt 设计是四大核心变量,每一个都影响最终效果

12.混合检索(向量 + BM25)+ Rerank 是目前业界精度最高的检索方案

13.RAG 适合知识密集型问答;微调适合行为/风格定制;两者结合效果最好

🚀 进阶方向

方向

简介

适用场景

GraphRAG

把知识库构建为知识图谱,支持多跳推理

强关联关系的复杂问答

Agentic RAG

让 LLM 自主决定何时检索、检索什么

多步骤规划与工具调用

Self-RAG

模型自我反思检索结果的相关性

高精度问答,减少无效检索

RAG 评估体系

用 RAGAS 框架量化 Faithfulness 等指标

系统质量监控与优化

多模态 RAG

支持图片、表格、图表的向量化检索

不局限于纯文本的场景

流式 RAG

检索与生成并行执行,减少延迟

对响应速度敏感的产品

🎯 实践建议:从最简单的 LangChain + Chroma + OpenAI 组合入手,先跑通基础流程,再逐步引入混合检索、Rerank、元数据过滤等优化手段。RAG 的进步是迭代的,不要一开始就追求完美架构。

— END —

相关学习资料