【RAG扫盲系列】RAG基础认知

一、检索增强生成(RAG)前言

1. LLM的缺陷分析

试想这样一个例子,有人问了你这样一个问题:木星有多少颗卫星?可能你之前曾经看到过有人说,木星有92颗卫星,于是你就自信地回答说92颗。但实际上,当你上网一搜,被网上众多消息迷住眼睛,看得头晕眼花,最后勉强确定最新消息说木星有95颗卫星,你知道的92颗卫星已经是过时的消息了。这种情况也出现在大模型身上。

大语言模型(LLM, Large Language Model) 在近几年展现了惊人的语言理解与生成能力,但它们并非完美无缺。它们也会和人类犯一样的错误。

  • 比如说,它们的知识库里的信息是过时的,但它们并不知道,就会自信地告诉你一个错误的、过时的答案。
  • 再比如说,它们可能干脆就不知道答案,但是以为自己知道,于是自信地编出一个驴唇不对马嘴的答案。
  • 继续比如说,这些答案它们说不出一个具体的来源,甚至当你给它一大段信息让它阅读并回答时,它也很难给出一个确定的答案,就像你也不知道你知道的“木星有92颗卫星”是从哪里看到的、搜索起来也很费劲一样。

总的来说,大语言模型有以下局限性:

局限 解释
知识时效性不足 LLM 的知识来自训练语料,通常存在时间“冻结点”,无法自动更新
幻觉问题(Hallucination) 模型可能生成看似合理但事实错误的内容
缺乏可控性 模型回答往往是“黑箱式”的,难以保证引用来源或解释推理过程
上下文窗口限制 输入长度有限,难以直接处理大规模文档或数据库

因此,单纯依赖大语言模型并不足以满足高可靠性场景的需求。我们需要一种方法,既能发挥 LLM 的语言生成能力,又能引入外部的、可更新的知识库来弥补它的不足——这就是 检索增强生成(RAG) 出现的背景。

2. RAG的定义

检索增强生成(Retrieval-Augmented Generation, RAG) 是一种结合信息检索与文本生成的混合范式。其核心思想是:

  • 检索:从外部知识库(文档、数据库、向量库等)中找到与用户问题相关的内容。

  • 增强:将检索到的内容作为额外上下文,拼接到提示词中。

  • 生成:LLM 在增强后的上下文基础上生成答案。

这样,RAG 既能利用 LLM 的语言生成能力,又能借助外部知识库保证答案的准确性、时效性和可解释性。

3. RAG的三大范式

RAG 的发展大致可以分为三个层次(或范式):

范式 核心特征 优点 局限
Naive RAG 简单检索 + 拼接上下文 实现容易,适合做原型(初步模型) 检索粗糙,易受噪声干扰
Advanced RAG 引入重排序、过滤、动态上下文选择 提高相关性与答案质量 架构更复杂,需额外计算
Agentic RAG 多智能体协作,带推理链与任务分解 可处理复杂问题,具备自适应能力 设计难度高,计算开销大

4. Prompt 工程 vs RAG vs Fine-tuning

除了 RAG 之外,提升大语言模型能力的常见手段还包括 Prompt 工程 和 Fine-tuning。三者在原理、成本和适用场景上各有不同。

先前的文章里介绍过Prompt工程,此处不再赘述,只简单介绍Fine-tuning。Fine-tuning是在预训练模型基础上,用特定领域数据继续训练,让模型更适应某个任务或领域。可以理解为让一个刚毕业的高中生选择某个专业(如医学),然后进行学习训练,最终成为专业的医生。接下来,我们将比较这三者的差别。

方法 是否改动模型 成本 知识更新 优势 局限 典型场景
Prompt 工程 ❌ 不改动 低 无法更新知识 简单灵活,快速试验 效果不稳定,难以解决知识缺失 原型验证、轻量级应用
RAG ❌ 不改动 中 更新知识库即可 时效性强,可解释性好 依赖检索质量,架构更复杂 企业知识库问答、科研助手
Fine-tuning ✅ 改动 高 需重新训练 针对性强,性能提升大 成本高,更新慢 专业化任务(法律、医疗、金融)

😈 选择 Prompt 工程、RAG 还是 Fine-tuning,取决于你的任务复杂度、数据可控性和资源预算。一般建议:轻量任务优先 Prompt 工程,知识密集型任务用 RAG,高精度定制任务考虑 Fine-tuning。

二、Naive RAG Pipeline

在上一节中,我们介绍了 RAG(Retrieval-Augmented Generation)的基本概念和三大范式。现在,我们将从最基础的 Naive RAG Pipeline 开始,手把手带你构建一个最小可用的 RAG 系统,帮助大语言模型“读懂”你的知识库,并基于外部文档回答问题。

我们可以将 Naive RAG 的核心流程拆解为四个步骤:

  1. 准备目标文档(Load):收集你希望大模型“参考”的资料,比如产品手册、论文、FAQ 等,并导入大模型。
  2. 文档切片(Split):将长文档切成小块(chunk),便于后续处理。
  3. 向量化(Embed & Store):将每个文本块转化为向量(embedding),存入向量数据库。
  4. 问答检索(Query):用户提问时,从向量库中找出最相关的文本块,拼接到 Prompt 中交给大模型生成答案。

接下来我们将详细拆解步骤。

1. 知识库构建

(1)文档加载与摄取

第一步是将你的原始资料导入系统。常见的文档来源包括:

  • PDF、Word、Markdown、TXT 等本地文件
  • 网页内容(通过爬虫或 API 抓取)
  • 数据库或企业知识库导出内容

PS:常用工具

  • langchain.document_loaders:支持多种格式的文档加载器
  • PyMuPDF、pdfplumber:用于解析 PDF
  • BeautifulSoup:用于解析 HTML 网页
from langchain.document_loaders import PyMuPDFLoader
loader = PyMuPDFLoader("example.pdf")
docs = loader.load()

(2) 文档分块策略

大语言模型的输入长度有限(如 4K、8K、32K tokens),所以我们需要将长文档切分成更小的“语义单元”,每个单元称为一个 chunk。

常见分块策略:

  • 按段落/句子/章节切分:每段/句/章为一个 chunk,适合结构清晰的文档。
  • 固定长度滑窗:每 N 个 token 为一个 chunk,支持重叠(overlap)以保留上下文。
  • 按语义切分:使用句法分析或语义边界进行智能切分(如 NLTK、spaCy)。

示例代码(固定长度切分):

from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
chunks = splitter.split_documents(docs)

2. 索引&向量化

(1)Embedding向量化

📌 什么是向量化?

向量化(Embedding)是将文本转化为多维空间中的向量表示,使得语义相近的文本在向量空间中距离更近。这样我们就可以用“找最近的向量”来实现语义检索。

🔧 向量化实践

  • 使用API向量化(如OpenAI)
from langchain.embeddings import OpenAIEmbeddings
embedding_model = OpenAIEmbeddings()
vectors = embedding_model.embed_documents([chunk.page_content for chunk in chunks])
  • 本地部署向量模型(如Ollama + Instractor)

如果你希望在本地运行向量模型(例如在隐私敏感场景),可以使用 Ollama + instructor-embedding 模型:

ollama run nomic-embed-text

然后通过 HTTP 请求或 Langchain 的 HuggingFaceEmbeddings 接口调用本地服务。

(2)向量间的相似度计算

当用户提问时,我们会将问题也向量化,然后与知识库中的所有向量进行相似度计算,找出最相关的几个 chunk。

常见相似度指标

指标 公式 特点
余弦相似度 $$\cos(\theta) = \frac{\vec{A} \cdot \vec{B}}{|\vec{A}| |\vec{B}|}$$ 衡量方向相似度,常用于文本
欧氏距离(L2) $$L_2(A, B) = \sqrt{\sum_{i=1}^{n} (a_i - b_i)^2}$$ 衡量距离远近,受向量长度影响较大

实际使用中,向量数据库通常默认使用余弦相似度。

(3)Indexing:构建向量索引

为了加速向量检索,我们需要将向量存入一个支持高效相似度搜索的数据库,称为向量数据库(Vector DB)。

  • 主流向量数据库功能对比
向量数据库 特点 是否开源 适合场景
FAISS Facebook 开源,轻量、快速 ✅ 本地开发、原型验证
Milvus 分布式、支持亿级数据 ✅ 企业级部署
Weaviate 内建 REST API,支持多模态 ✅ 快速集成、云部署
Pinecone 托管服务,免运维 ❌ 商业化应用,快速上线
  • 如何选型向量数据库
需求 选择
本地开发 FAISS、Chroma
需要 REST API / 多语言支持 Weaviate
大规模部署 Milvus、Qdrant
不想自己运维 Pinecone、Zilliz Cloud

三、常见误区小节

  • ❌ “我是不是要先训练一个模型才能用 RAG?” → 不需要,RAG 是无模型改动的增强方式。
  • ❌ “我是不是要把所有文档都一次性向量化?” → 可以分批处理,支持增量更新。
  • ❌ “向量越多越好?” → 不一定,质量比数量更重要,太多会影响检索效率。

本篇内容聚焦于 RAG 的原理与流程,帮助你建立清晰的认知框架。下一篇我们将动手搭建一个最小可运行的 RAG 系统,从环境配置到代码实现,一步步带你跑通整个流程。

posted @ 2026-07-17 18:25  Alkaid2077  阅读(71)  评论(0)    收藏  举报