初识 RAG:让 AI 学会“开卷考试“
初识 RAG:让 AI 学会"开卷考试"
导读: 你是否遇到过 ChatGPT 一本正经地"胡说八道"?或者发现它对去年发生的事情一无所知?本文将带你认识 RAG——一项让 AI 既能"博学"又能"查资料"的核心技术,零基础友好,附代码实战。
一、大模型的"阿喀琉斯之踵"
在使用 ChatGPT、DeepSeek 这类大语言模型(LLM)时,你可能遇到过这两种让人抓狂的情况:
场景一:自信地"胡说八道"
你问:“2025 年诺贝尔物理学奖得主是谁?”
AI 答:(编造一个听起来很合理的名字)……
场景二:对新知识一问三不知
你问:“我们公司最新的产品手册里,第三章讲的是什么?”
AI 答:“对不起,我没有相关信息……”
这两个问题的根源是一样的——大模型的知识是"冻结"的。

LLM 在训练完成后,其内部参数(“记忆”)就被固定下来了。它:
- ❌ 不知道训练数据截止日期之后发生的事(知识时效性问题)
- ❌ 不了解你的私域数据(企业内部文档、个人知识库等)
- ❌ 有时会"幻觉"——用错误信息填补知识空白
那么,如何破解这个困局?答案就是 RAG。
二、什么是 RAG?
RAG,全称 Retrieval-Augmented Generation(检索增强生成),是目前 AI 应用领域最火热的技术范式之一。
用一句话来概括它的精髓:
💡 RAG 就是让 LLM 学会了"开卷考试"——它既能利用训练时学到的通识知识,也能在回答时临时"翻阅"指定的外部资料。
2.1 两种知识,一个系统
理解 RAG,首先要理解两种知识的概念:
| 知识类型 | 存储位置 | 特点 | 类比 |
|---|---|---|---|
| 参数化知识 | 模型权重(参数)中 | 固化、模糊、有截止日期 | 你脑子里记住的知识 |
| 非参数化知识 | 外部知识库 | 精准、可实时更新 | 你手边的参考书 |
RAG 的核心价值,就是在生成答案之前,先通过检索机制从外部知识库动态捞取最相关的"参考资料",再交给 LLM 综合作答。
动图:参数化知识(模型内部)vs 非参数化知识(外部知识库)的核心差异
2.2 RAG 的工作流程
RAG 系统的运作分为两个核心阶段:检索阶段 与 生成阶段。
动图:完整 RAG Pipeline——从文档入库到最终生成答案
阶段一:知识入库(索引构建)
在用户提问之前,系统需要先把所有"参考书"处理好、建好索引:
- 文档解析:将 PDF、Word、网页等格式的文档切割成小片段(Chunk)
- 向量化:调用 Embedding 模型,将每个文本片段转化为一串数字(向量),这串数字能代表文本的"语义含义"
- 存入向量库:将所有向量存入专门的向量数据库(如 Chroma、Faiss、Milvus)
阶段二:检索 + 生成(推理)
用户提问时,实时执行:
- 问题向量化:将用户的问题同样转化为向量
- 相似度检索:在向量库中找出与问题向量"最近"的若干个文档片段(Top-K 召回)
- 上下文整合:将检索到的片段 + 用户原始问题,拼成一个完整的 Prompt
- LLM 生成答案:将这个 Prompt 交给大模型,大模型基于提供的上下文给出有据可查的回答
三、为什么选 RAG,而不是微调?
面对"大模型不知道我的私域数据"这个问题,技术上有几种解法。我们来理清它们的关系:
💡 技术选型口诀:先 Prompt → 再 RAG → 最后微调,成本逐级递增,改动逐级加深。
横轴代表对模型本身的修改程度,纵轴代表对输入信息(上下文)的增强程度。
在实际选型时,应遵循"最小改动原则",按以下顺序依次尝试:
第一步:提示词工程(Prompt Engineering)
适用场景:模型已经具备相关知识,只是回答不够好
做法:精心设计提问方式、给出示例、明确格式要求
成本:极低,不需要改动任何代码或模型
局限:模型真的"不知道"时,再好的提示词也无济于事
第二步:RAG(检索增强生成)✅ 推荐优先选择
适用场景:模型缺乏特定领域知识或实时信息
做法:外挂知识库,让模型"参考"外部资料回答
成本:中等,需要搭建检索管道和向量库,但不修改模型参数
优势:
- 知识可实时更新,无需重新训练模型
- 答案有据可查,可追溯来源,减少幻觉
- 成本远低于微调
第三步:微调(Fine-tuning)
适用场景:需要改变模型的"行为方式"而非"知识储备"
做法:用特定数据集重新训练部分或全部模型参数
成本:极高,需要高质量数据集、大量 GPU 算力和专业知识
什么时候才真正需要微调?
- 让模型严格遵循某种特殊输出格式
- 模仿特定人物的写作风格
- 将极其复杂的指令"内化"进模型权重
- 在某个极度垂直的专业领域提升推理能力
一句话总结:大多数企业级 AI 应用,RAG 是性价比最高的选择。
四、代码实战:用 LangChain 搭建你的第一个 RAG

动图:长文档被切割成带 overlap 的小片段,黄色高亮区域为相邻块的重叠部分
理论说了这么多,现在来动手实现一个最简单的 RAG Demo。我们使用 LangChain 框架,它是目前最流行的 LLM 应用开发框架,极大地简化了 RAG 的搭建流程。
4.1 环境准备
pip install langchain langchain-community langchain-openai chromadb
4.2 准备知识库文档
假设我们有一个关于公司产品的文本文件 knowledge.txt:
# 关于 SuperBot 3000 产品手册
## 第一章:产品简介
SuperBot 3000 是一款智能客服机器人,支持 7x24 小时全天候服务,
可同时接入微信、钉钉、飞书等平台。
## 第二章:核心功能
- 多轮对话:支持上下文感知的多轮对话
- 知识库管理:支持导入 PDF、Word、Excel 等格式文档
- 数据统计:提供详细的会话质量分析报表
## 第三章:定价方案
基础版:每月 299 元,支持 3 个坐席
专业版:每月 999 元,支持 20 个坐席,含高级数据分析
企业版:定制报价,无限坐席,含专属技术支持
4.3 完整 RAG 代码
# simple_rag.py
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
# ==================== 第一步:加载文档 ====================
print("📚 正在加载知识库文档...")
loader = TextLoader("knowledge.txt", encoding="utf-8")
documents = loader.load()
# ==================== 第二步:切割文档 ====================
# 将长文档切割成小片段(Chunk),便于精准检索
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=200, # 每个片段最多 200 个字符
chunk_overlap=20 # 相邻片段重叠 20 字符,避免语义断裂
)
chunks = text_splitter.split_documents(documents)
print(f"✅ 文档切割完成,共 {len(chunks)} 个片段")
# ==================== 第三步:向量化并存入向量库 ====================
print("🔢 正在生成向量索引...")
embedding_model = OpenAIEmbeddings() # 可替换为本地 Embedding 模型
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embedding_model,
persist_directory="./chroma_db" # 向量库持久化路径
)
print("✅ 向量索引构建完成!")
# ==================== 第四步:构建 RAG 检索链 ====================
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# RetrievalQA 自动完成:检索 → 拼接 Prompt → 调用 LLM → 返回答案
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # "stuff" 策略:直接将检索结果塞入 Prompt
retriever=vectorstore.as_retriever(
search_kwargs={"k": 3} # 检索最相关的 3 个片段
),
return_source_documents=True # 同时返回参考来源,便于溯源
)
# ==================== 第五步:提问!====================
questions = [
"SuperBot 3000 的专业版每月多少钱?",
"这个产品支持哪些平台接入?",
]
for question in questions:
print(f"\n❓ 问题:{question}")
result = qa_chain.invoke({"query": question})
print(f"💬 答案:{result['result']}")
print(f"📄 参考来源:{result['source_documents'][0].page_content[:50]}...")
4.4 运行结果
📚 正在加载知识库文档...
✅ 文档切割完成,共 8 个片段
🔢 正在生成向量索引...
✅ 向量索引构建完成!
❓ 问题:SuperBot 3000 的专业版每月多少钱?
💬 答案:SuperBot 3000 专业版每月 999 元,支持 20 个坐席,并含高级数据分析功能。
📄 参考来源:专业版:每月 999 元,支持 20 个坐席,含高级数据分析...
❓ 问题:这个产品支持哪些平台接入?
💬 答案:SuperBot 3000 支持接入微信、钉钉、飞书等平台。
📄 参考来源:可同时接入微信、钉钉、飞书等平台...

动图:查询向量(Q)在语义空间中飞入,系统找到距离最近的 3 个文档片段(Top-3 召回)
关键点说明:
| 步骤 | 对应 RAG 原理 | 核心作用 |
|---|---|---|
TextLoader |
知识获取 | 读取原始文档 |
RecursiveCharacterTextSplitter |
文档切割 | 将长文本切成可检索的小片段 |
OpenAIEmbeddings + Chroma |
向量化 + 存储 | 建立语义检索索引 |
as_retriever(k=3) |
相似度检索 | 召回最相关的 Top-3 片段 |
RetrievalQA |
生成 | 整合上下文,让 LLM 作答 |
五、总结与展望

学到这里,你已经掌握了 RAG 的核心概念和基础实现。让我们回顾一下今天的重点:
- 是什么:RAG = 检索(Retrieval)+ 增强(Augmented)+ 生成(Generation),通过外部知识库弥补 LLM 的知识局限
- 为什么用:相比微调,RAG 成本低、可更新、答案可溯源,是企业 AI 应用的首选方案
- 怎么做:索引构建(文档切割 → 向量化 → 存库)+ 检索生成(相似度召回 → 拼接 Prompt → LLM 作答)
当然,本文展示的只是一个最基础的 Naive RAG。在真实的生产环境中,还有大量值得深入探索的进阶话题:
| 进阶方向 | 关键技术 | 解决的问题 |
|---|---|---|
| 高级 RAG | 查询改写、混合检索、重排序(Rerank) | 提升检索召回的精准度 |
| 模块化 RAG | 自定义检索策略、多路召回融合 | 应对复杂业务场景 |
| Agentic RAG | 工具调用、多步推理、自我反思 | 处理需要多轮推理的复杂问题 |
vx:【阿杰Agent开发日志】
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)