当前位置: 首页 > news >正文

RAG了解与实践

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、HTMLUnstructuredFileLoader(“doc.pdf”)
PDFMinerLoader解析 PDF 纯文本PDFMinerLoader(“report.pdf”)
PyMuPDFLoader解析 PDF(更快)PyMuPDFLoader(“doc.pdf”)
Docx2txtLoaderMicrosoft Word(.docx)Docx2txtLoader(“file.docx”)
JSONLoaderJSON 文件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-large3072最新模型,准确性更高,适用于复杂应用高精度语义搜索、大规模文本分析
text-embedding-3-small1536最新模型,性价比高,适用于一般应用一般语义搜索、问答系统
text-embedding-ada-0021536旧版模型,仍然可用,但不如 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

相关文章:

  • QEMU源码全解析 —— 块设备虚拟化(1)
  • MySQL root用户密码忘记怎么办(Reset root account password)
  • Java面经
  • 字节跳动AI原生编程工具Trae和百度“三大开发神器”AgentBuilder、AppBuilder、ModelBuilder的区别是?
  • 蓝桥试题:传球游戏(二维dp)
  • 基于海思soc的智能产品开发(芯片sdk和linux开发关系)
  • unity console日志双击响应事件扩展
  • C#核心(21)万物之父Object中的方法
  • Lambda表达式使用介绍
  • 【Bootstrap5】Bootstrap5学习笔记
  • 数据库复习(第五版)- 第七章 数据库设计
  • 3.6c语言
  • 【算法系列】基数排序
  • 维度建模事实表技术基础解析(以电商场景为例)
  • 洛谷 P1480 A/B Problem(高精度详解)c++
  • 相机几何与标定:从三维世界到二维图像的映射
  • 【LeetCode101】对称二叉树
  • 逐梦DBA:MySQL的编码设置
  • PWM子系统芯片驱动源码pwm-tegra.c分析
  • leetcode15 三数之和
  • 中美贸易代表会谈后是否已确定下一次会谈?外交部回应
  • 国家主席习近平任免驻外大使
  • “上海-日喀则”援藏入境旅游包机在沪首航
  • 解放日报:“感觉全世界人都在上海买买买”
  • 词条数量大幅扩充,《辞海》第八版启动编纂
  • 福州一宋代古墓被指沦为露天厕所,仓山区博物馆:已设置围挡