初识 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 核心工作流程动图

动图:完整 RAG Pipeline——从文档入库到最终生成答案

阶段一:知识入库(索引构建)

在用户提问之前,系统需要先把所有"参考书"处理好、建好索引:

  1. 文档解析:将 PDF、Word、网页等格式的文档切割成小片段(Chunk)
  2. 向量化:调用 Embedding 模型,将每个文本片段转化为一串数字(向量),这串数字能代表文本的"语义含义"
  3. 存入向量库:将所有向量存入专门的向量数据库(如 Chroma、Faiss、Milvus)

阶段二:检索 + 生成(推理)

用户提问时,实时执行:

  1. 问题向量化:将用户的问题同样转化为向量
  2. 相似度检索:在向量库中找出与问题向量"最近"的若干个文档片段(Top-K 召回)
  3. 上下文整合:将检索到的片段 + 用户原始问题,拼成一个完整的 Prompt
  4. LLM 生成答案:将这个 Prompt 交给大模型,大模型基于提供的上下文给出有据可查的回答

三、为什么选 RAG,而不是微调?

面对"大模型不知道我的私域数据"这个问题,技术上有几种解法。我们来理清它们的关系:
技术选型象限图

💡 技术选型口诀:先 Prompt → 再 RAG → 最后微调,成本逐级递增,改动逐级加深。

横轴代表对模型本身的修改程度,纵轴代表对输入信息(上下文)的增强程度。

在实际选型时,应遵循"最小改动原则",按以下顺序依次尝试:

第一步:提示词工程(Prompt Engineering)

适用场景:模型已经具备相关知识,只是回答不够好

做法:精心设计提问方式、给出示例、明确格式要求

成本:极低,不需要改动任何代码或模型

局限:模型真的"不知道"时,再好的提示词也无济于事


第二步:RAG(检索增强生成)✅ 推荐优先选择

适用场景:模型缺乏特定领域知识或实时信息

做法:外挂知识库,让模型"参考"外部资料回答

成本:中等,需要搭建检索管道和向量库,但不修改模型参数

优势

  • 知识可实时更新,无需重新训练模型
  • 答案有据可查,可追溯来源,减少幻觉
  • 成本远低于微调

第三步:微调(Fine-tuning)

适用场景:需要改变模型的"行为方式"而非"知识储备"

做法:用特定数据集重新训练部分或全部模型参数

成本:极高,需要高质量数据集、大量 GPU 算力和专业知识

什么时候才真正需要微调?

  • 让模型严格遵循某种特殊输出格式
  • 模仿特定人物的写作风格
  • 将极其复杂的指令"内化"进模型权重
  • 在某个极度垂直的专业领域提升推理能力

一句话总结:大多数企业级 AI 应用,RAG 是性价比最高的选择。


四、代码实战:用 LangChain 搭建你的第一个 RAG

文档切割 Chunking 动图

动图:长文档被切割成带 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开发日志】

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐