时间:2026-03-18 18:31
人气:
作者:admin
全网最细 RAG 工程实战教程(2026 大佬版)|小白也能落地,附可直接运行代码
最近在做 AI 大模型相关的课程小项目,本来想做个“私有文档问答”,结果一开始被各种概念绕晕:RAG、Embedding、向量数据库、文本分块、检索增强……越看越懵。
前后踩了无数坑:环境装不上、代码跑不通、PDF 读不出来、检索出来全是无关内容、大模型还在瞎编。
折腾了快两周,终于把最简单、最能跑、最容易理解的一整套 RAG 流程跑通了。
今天这篇文章,我用最小白、最通俗、最不官方的话,把 RAG 从 0 到 1 讲清楚,代码全部可直接复制运行,不管你是大二大三、刚学 Python,还是完全不懂 AI,跟着做就能成功。
RAG = 检索增强生成(Retrieval-Augmented Generation)
大白话解释:
大模型本身不知道你本地文档里的内容(比如你的笔记、PDF、手册)
直接问,大模型只会瞎编(幻觉)
RAG 就是:先从你的文档里找答案 → 再把找到的内容给大模型 → 让大模型用这些内容回答
就这么简单!
把你的 PDF / TXT 读进来
把长文章切成小段(文本分块)
把每段变成“向量”(Embedding)
存进向量数据库(方便快速查找)
你提问题 → 系统去数据库找最相关的几段
把这几段丢给大模型 → 得到真实答案
新建一个文件夹,打开终端执行:
pip install langchain chromadb pypdf openai python-dotenv
各库作用(小白不用记,知道就行):
langchain:RAG 最常用框架,帮我们整合所有步骤
chromadb:本地轻量向量数据库(不用安装服务器,直接跑,小白友好)
pypdf:专门读取 PDF 文件,解决小白“读不出PDF”的痛点
openai:调用 OpenAI 大模型和向量模型
python-dotenv:安全存放 API Key,避免泄露
新建文件,命名为:1_load_and_split.py(文件名别改,后续会调用)
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 1. 加载 PDF(把你自己的 PDF 放在同目录下,替换文件名即可)
loader = PyPDFLoader("test.pdf") # 重点:改成你的 PDF 文件名(比如 课程笔记.pdf)
documents = loader.load()
# 2. 文本分块(最关键!新手直接用我的参数,不用改,避开踩坑)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=800, # 每块文本的字符数(中文800字符≈200字,适配大模型)
chunk_overlap=100, # 块之间重叠100字符,保证句子不被切断,语义连贯
separators=["\n\n", "\n", "。", "!", "?", " "] # 按中文标点拆分,更贴合中文语义
)
texts = text_splitter.split_documents(documents)
# 打印结果,验证是否成功
print("文档总页数:", len(documents))
print("分块后总数:", len(texts))
print("✅ 加载 & 分块完成!")
运行命令(终端输入):
python 1_load_and_split.py
✅ 成功提示:打印出“文档总页数”“分块后总数”,说明步骤没问题;若报错,大概率是 PDF 路径/文件名错了。
新建文件,命名为:2_embedding_and_save.py
import os
from dotenv import load_dotenv
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
# 加载 .env 文件中的 API Key(后面会教你创建)
load_dotenv()
# 1. 加载第一步分块后的数据(直接调用上一个文件的结果,不用重复写代码)
from 1_load_and_split import texts
# 2. 初始化向量模型(把文本转成计算机能理解的“向量”)
embedding = OpenAIEmbeddings(
model="text-embedding-3-small" # 轻量模型,免费额度足够,小白首选
)
# 3. 把向量存入本地 Chroma 数据库(持久化,下次不用重新生成)
db = Chroma.from_documents(
documents=texts,
embedding=embedding,
persist_directory="./chroma_db" # 向量数据存在本地 chroma_db 文件夹,可直接查看
)
db.persist() # 持久化数据,避免程序退出后丢失
print("✅ 向量已保存到本地 chroma_db 文件夹")
在代码同目录下,新建一个文本文件,重命名为 .env(前面有个点),打开后写入:
OPENAI_API_KEY=你的OpenAI_API_Key # 替换成你自己的 API Key
⚠️ 注意:API Key 别泄露,.env 文件不用运行,代码会自动读取。
运行命令:
python 2_embedding_and_save.py
✅ 成功提示:打印“向量已保存到本地 chroma_db 文件夹”,此时目录会多一个 chroma_db 文件夹,说明向量存储成功。
新建文件,命名为:3_rag_chat.py(这是最终可交互的问答文件)
import os
from dotenv import load_dotenv
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
# 加载 API Key
load_dotenv()
# 1. 加载本地向量库(不用重新生成向量,直接加载之前保存的 chroma_db)
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
embedding = OpenAIEmbeddings(model="text-embedding-3-small")
db = Chroma(
persist_directory="./chroma_db", # 加载本地向量库路径
embedding_function=embedding
)
# 2. 初始化大模型(GPT-3.5-turbo,性价比高,免费额度足够小白使用)
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.1 # 0-1,越小越精准,避免大模型瞎编,RAG 场景固定设 0.1
)
# 3. 自定义提示词(重点!防止大模型瞎编,小白别改这个模板)
prompt_template = """
你只能根据下面提供的上下文信息回答用户的问题,不允许使用你自己的知识库,不允许编造任何内容。
上下文:
{context}
用户的问题:{question}
注意:
1. 答案必须严格基于上面的上下文,不能添加任何额外信息;
2. 如果上下文里没有相关答案,直接说:“抱歉,文档中没有找到相关内容。”;
3. 回答简洁明了,不用冗余铺垫,直接给出答案。
"""
# 封装提示词
prompt = PromptTemplate(
template=prompt_template,
input_variables=["context", "question"]
)
# 4. 构建 RAG 链(检索+生成,核心逻辑,小白不用改)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 新手固定用 stuff,把检索到的内容全部传给大模型
retriever=db.as_retriever(search_kwargs={"k": 3}), # 检索3个最相关的片段,k=2-5最合适
return_source_documents=True, # 返回检索到的原文片段,方便验证答案
chain_type_kwargs={"prompt": prompt} # 传入自定义提示词,防止瞎编
)
# 5. 交互问答(循环输入,输入 q 退出)
print("✅ RAG 问答已启动,可输入问题提问(输入 q 退出)")
while True:
question = input("\n请输入你的问题(输入 q 退出):")
if question.strip().lower() == "q":
print("???? 退出问答,感谢使用!")
break
# 执行问答
res = qa_chain({"query": question})
# 打印结果
print("\n???? 回答:", res["result"])
# 可选:打印检索到的原文片段(验证答案来源,小白可注释掉)
# print("\n???? 参考原文片段:")
# for i, doc in enumerate(res["source_documents"]):
# print(f"\n【片段{i+1}】:{doc.page_content[:200]}...")
运行命令:
python 3_rag_chat.py
✅ 成功效果:输入你 PDF 里有的问题(比如“课程笔记里的 Python 基础语法有哪些?”),就能得到基于 PDF 的精准回答,不会瞎编!
⚠️ 常见报错:若提示 API Key 无效,检查 .env 文件里的 Key 是否写错;若提示网络错误,OpenAI 需要科学上网。
很多小白没有 OpenAI API Key,我专门准备了文心一言的替换代码,只需要改两处,其他代码完全不用动,直接复制替换即可!
pip install langchain-community baidu-aip
# 替换原来的 OpenAIEmbeddings,复制这段代码替换即可
from langchain_community.embeddings import BaiduERNIEEmbeddings
embedding = BaiduERNIEEmbeddings(
baidu_api_key="你的文心一言API Key",
baidu_secret_key="你的文心一言Secret Key",
model_name="ernie-3.0-base-zh" # 文心一言轻量嵌入模型,免费可用
)
# 替换原来的 ChatOpenAI,复制这段代码替换即可
from langchain_community.chat_models import ChatBaiduERNIE
llm = ChatBaiduERNIE(
baidu_api_key="你的文心一言API Key",
baidu_secret_key="你的文心一言Secret Key",
model_name="ernie-3.5", # 文心一言3.5版本,免费额度足够
temperature=0.1
)
⚠️ 提示:文心一言的 API Key 和 Secret Key,在百度智能云官网注册就能获取,全程免费,不用科学上网,小白友好!
PDF 路径不对、文件名写错:比如把“test.pdf”写成“test1.pdf”,或者 PDF 不在代码同目录,直接报错,一定要核对文件名和路径。
分块参数乱改:把 chunk_size 设成 2000(太大)或 100(太小),导致检索不到相关内容,新手直接用我给的 800+100 参数。
不设置 chunk_overlap:把 overlap 设为 0,导致句子被切断,语义不完整,检索不准,必须设 50-100。
提示词不限制:不用我给的提示词模板,导致大模型依然瞎编,一定要保留“只能基于上下文回答”的约束。
API Key 写错 / 没加载 .env:要么 Key 输错,要么没创建 .env 文件,导致调用模型失败,仔细核对 Key 和 .env 文件名。
检索 k 值太大:把 k 设成 10 甚至 20,引入大量无关内容,答案混乱,新手固定设 2-3 即可。
我这套代码已经把这些坑全部避开,直接复制运行就能少走弯路!
课程 PDF 智能问答:期末复习,不用逐页翻笔记,直接问问题找答案(期末救命神器)
个人笔记知识库:把自己的学习笔记、错题整理成 PDF,打造专属问答机器人
企业员工手册问答(练手项目):适合找实习前做,提升简历含金量
论文文献快速总结:上传论文 PDF,让 RAG 总结核心观点,节省看文献时间
毕设项目:RAG 是当前 AI 热门方向,做一个可视化 RAG 知识库,毕设轻松加分
RAG 真的没有那么难,难的是没人用小白的话讲清楚,难的是踩坑后没人指路。
我也是从完全不懂、到处报错、甚至想放弃一路走过来的,所以我知道大家卡在哪里——不是不会写代码,是怕概念太复杂,是怕代码跑不通,是怕踩坑没人帮。
这篇文章我尽量写得通俗、简单、能跑通,没有复杂术语,没有多余废话,代码全部可复制,就是希望和我一样的普通计算机学生,能少走弯路,快速做出属于自己的 AI 项目。
如果你也在入门 RAG、大模型、AI 项目,遇到了报错、跑不通的问题,欢迎在评论区交流,我会尽量回复,咱们一起踩坑、一起进步!
觉得有用的话,欢迎 点赞 + 收藏,我后面会继续更新小白友好的 AI 教程:
RAG 进阶优化:解决“检索不准”的问题
本地免费模型跑 RAG:不用 API Key,不用一分钱
用 Gradio 做可视化界面:让 RAG 更美观,毕设更加分
完整毕设项目教程:从需求分析到部署上线,一步到位
我们一起从小白变大佬,一起搞定 AI 项目,一起在计算机这条路上走得更顺!????