RAG(Retrieval-Augmented Generation) 是一种授予生成式人工智能模型信息检索功能的技术。它修改与大型语言模型的交互 (LLM),以便模型响应用户对一组指定文档的查询,使用此信息来增强从其自身庞大的静态训练数据中提取的信息。这允许LLMs使用特定于域和/或更新的信息。

可以简单理解为"检索+生成"的人工智能技术。想象你正在做一个复杂的研究项目,除了大脑里已有的知识,你还需要查阅额外的资料来提高回答的准确性和深度。RAG就是AI模型的这个"查阅资料"过程。

RAG主要分为三个关键步骤

  1. 索引

    将要引用的数据转换为LLM embedding,即大向量空间形式的数字表示。RAG 可用于非结构化(通常是文本)、半结构化或结构化数据,然后,这些嵌入内容将存储在矢量数据库中,以便进行文档检索。

    就像把所有相关的资料数据全部翻译为中文,聚合为一本书

  2. 检索

    当收到一个问题时,AI首先在大规模知识库中快速搜索相关信息

    就像图书馆里用关键词检索最相关的书籍和资料

  3. 增强

    将检索到的相关信息作为"额外知识"注入到原始问题中

    相当于给AI喂些额外上下文

  4. 生成

    AI基于原始问题和检索到的额外信息,生成更加准确、丰富的回答

    就像写论文,不仅依赖了本身知识,还参考了大量文献

代码demo

from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.chains import RetrievalQA
from langchain_community.document_loaders import TextLoader
import os

# 设置OpenAI API密钥
os.environ["OPENAI_API_KEY"] = "your_openai_api_key"

# 加载文档
loader = TextLoader("./罪与罚(陀思妥耶夫斯基著).txt",encoding="utf-8")
documents = loader.load()

# 文本分割
text_splitter = CharacterTextSplitter(
    chunk_size=500,
     chunk_overlap=50,
     separator="\n"
     )
texts = text_splitter.split_documents(documents)

# 限制处理的文本数量
max_texts = 50  # 设置最大处理文档数
texts = texts[:max_texts]

# 创建向量存储
embeddings = OpenAIEmbeddings(
    model="text-embedding-ada-002"
)
vectorstore = Chroma.from_documents(texts, embeddings)

# 创建检索式问答链
qa = RetrievalQA.from_chain_type(
    llm=ChatOpenAI(
        model_name="gpt-3.5-turbo",
        temperature=0.7,
        max_tokens=1000
    ),
    chain_type="stuff",
    retriever=vectorstore.as_retriever(
        search_kwargs={
            "k": 10
        }
    )
)

# 示例查询
query = "请分析主人公拉斯柯尔尼科夫的心理变化"
result = qa.invoke({"query": query})
print(f"问题: {query}")
print(f"回答: {result}")

索引

Loader

在langchain中有以下加载器

加载器 数据源 示例
TextLoader 纯文本(.txt) TextLoader(“document.txt”)
CSVLoader 逗号分隔的 CSV 文件 CSVLoader(“data.csv”)
UnstructuredFileLoader 自动解析 PDF、Word、HTML UnstructuredFileLoader(“doc.pdf”)
PDFMinerLoader 解析 PDF 纯文本 PDFMinerLoader(“report.pdf”)
PyMuPDFLoader 解析 PDF(更快) PyMuPDFLoader(“doc.pdf”)
Docx2txtLoader Microsoft Word(.docx) Docx2txtLoader(“file.docx”)
JSONLoader JSON 文件 JSONLoader(“data.json”)

切分策略

  • 固定大小切分
  • 语义切分
  • 递归切分
  • 基于文档结构的切分
  • 基于LLM的切分

在langchain中提供的分割器如下

CharacterTextSplitter

按字符分割

📌 介绍:

  • 固定字符长度 分割文本,并可以 重叠 一定数量的字符,防止信息丢失。
  • 默认按照 \n\n(两次换行)和 \n(单换行)进行拆分,也可以自定义分隔符。

✅ 适用于:

  • 处理长文档,如 书籍、文章、代码
  • 需要重叠片段来保持上下文连续性的场景
RecursiveCharacterTextSplitter

递归字符分割

📌 介绍:

  • 优先使用较大的分隔符(如 \n\n),如果拆分后仍然超出 chunk_size,则继续使用更小的分隔符(如 . 句号)。
  • 更智能,不会直接切断单词或句子,适用于 较大文本

✅ 适用于:

  • 处理 书籍、论文、API 文档
  • 需要更自然的文本分割方式(避免断句)
TokenTextSplitter

按 Token 分割

📌 介绍:

  • 按 Token(子词单元)分割文本,避免切割单词。
  • 使用 tiktoken(OpenAI 的 tokenizer)或 HuggingFace tokenizer 计算 Token 数量。

✅ 适用于:

  • 处理 OpenAI GPT 模型(因为有 Token 限制)
  • 需要更精确的 Token 控制,防止超出模型的最大 Token 长度
MarkdownTextSplitter

按 Markdown 结构分割

📌 介绍:

  • 专门用于 Markdown 文档,可按 # 一级标题、## 二级标题、代码块 等结构进行拆分。
  • 保持 Markdown 的 层级关系,不会破坏格式。

✅ 适用于:

  • 处理 技术文档、Wiki、API 文档
  • 需要 按标题或段落 进行检索
SentenceTransformersTokenTextSplitter

按 Token + 句子分割

📌 介绍:

  • 结合 SentenceTransformerTokenTextSplitter,按 Token 数量切割,但尽量不破坏句子结构
  • 适用于 LLM 需要 按 Token 数量优化输入,但又不能随意拆句的情况。

✅ 适用于:

  • 需要对 长文本 进行向量化,并保证语义完整性
  • 适配 Hugging Face TransformersBERT 相关模型

LanguageModelTextSplitter

按 LLM Token 限制分割

📌 介绍:

  • 大模型(如 GPT-4)决定如何分割文本,并确保每段都符合模型 Token 限制。
  • 适合需要适配 OpenAI API 的任务,防止超出 max_tokens 限制。

✅ 适用于:

  • OpenAI、Anthropic Claude 需要 Token 限制 的情况
  • 处理 超大文档(如法律、医学文本)
CodeTextSplitter

按代码结构分割

📌 介绍:

  • 适用于 代码文件(Python、Java、C++ 等),按函数、类或逻辑块拆分。
  • 避免在 关键语法结构(如函数、类) 之间随意切割,保持代码完整性。

✅ 适用于:

  • 处理 GitHub 代码库
  • 代码检索、代码对话(如 Code Llama)

embeddings

OpenAIEmbeddings 是 langchain 提供的一个 嵌入模型(Embedding Model),用于将文本转换为 向量表示,以便进行语义搜索、文本相似性计算等任务。它是 langchain 的 Embeddings 接口的实现之一,内部调用了 OpenAI 提供的 文本嵌入模型 API

模型名称 维度 说明 适用场景
text-embedding-3-large 3072 最新模型,准确性更高,适用于复杂应用 高精度语义搜索、大规模文本分析
text-embedding-3-small 1536 最新模型,性价比高,适用于一般应用 一般语义搜索、问答系统
text-embedding-ada-002 1536 旧版模型,仍然可用,但不如 text-embedding-3 旧项目兼容

向量数据库Chroma

Chroma是一款轻量级、高性能的开源向量数据库,专为 LLM 应用设计,支持文档存储元数据过滤语义搜索,并提供本地和云端存储

✅ 主要特点

  • 🏗 简洁易用:Python 直接调用,无需复杂配置
  • 🗂 支持文档存储:可存储文本 + 向量 + 元数据
  • 🔄 检索增强生成(RAG)友好

📦 适用场景

  • LLM 问答系统(如 OpenAI + RAG)
  • 本地化知识库(文档搜索)
  • AI 助手

chain_type

chain_type是指定不同的处理方式的参数,决定了如何处理检索到的文档以及如何与LLM进行交互

  • stuff: 最简单的链类型,将所有文档直接传递给语言模型。适用于少量短文档。
  • map_reduce: 先对每个文档单独处理,然后将结果合并。适用于大量文档
  • refine: 逐步细化答案,每次处理一个文档。适用于需要高质量答案的场景
  • map_rerank: 对每个文档单独处理,然后根据相关性重新排序。适用于需要最相关答案的场景
场景 推荐chain_type 原因
文档较短(可直接传递) “stuff” 速度快
文档较长(超出 Token 限制) “map_reduce” 可处理长文本
需要更高质量的回答 “refine” 逐步优化答案
需要确保最优答案 “map_rerank” 选择最佳答案

Ref

  1. https://en.wikipedia.org/wiki/Retrieval-augmented_generation
Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐