解锁RAG

55 阅读3分钟

1.RAG定义

RAG,英文全称Retrieval-Augmented Generation,检索增强生成,它通过从外部知识库中检索相关的实时信息,来增强大语言模型的回答生成能力。

2.为什么需要使用RAG

  • 让模型在不重新训练的情况下,也能使用外部最新的领域知识,RAG最核心的价值在于突破了模型预训练知识的局限。
  • 降低了模型“幻觉”,大模型有时候一本正经地胡说八道,RAG要求模型根据提供的资料回答,能有效降低模型编造事实的概率,让模型的回答更有依据。
  • 私有/专业知识获取,大模型在训练阶段无法直接获取企业内部的私有数据或内部文件,导致在某些特定场景下,大模型的回答往往不是那么“专业”,引入RAG可以在不需要重新训练模型的前提下,让它掌握特定领域的新的专业知识。
  • 可溯源性,在构建向量存储的过程中,存储文字内容+向量+元信息数据,在溯源时,RAG 可以告诉答案引自哪些内容。

3.RAG的核心流程

  • 数据准备,文本切分
  • 构建向量存储:将外部知识库通过嵌入模型编码为向量索引,存入向量数据库
  • 查询检索:用户发起查询时,通过相同的嵌入模型将问题向量化,通过相似度检索锁定知识库中与问题描述相关性最高的内容
  • 生成集成:将上一步中得到的文档,用户查询的问题,进行上下文整合到模型预设的提示词中,再发送给大模型进行回答

4.练习

1.LangChain代码最终得到的输出携带了各种参数,查询相关资料尝试把这些参数过滤掉得到content里的具体回答。

答:输出answer.content

answer = llm.invoke(prompt.format(question=question, context=docs_content))
print(answer.content)

2.修改Langchain代码中RecursiveCharacterTextSplitter()的参数chunk_sizechunk_overlap,观察输出结果有什么变化。

答:类TextSplitter中控制块chunk_size默认是4000,重复块chunk_overlap默认是200,以下是一些运行结果

Snipaste_2026-01-13_14-37-13.png

大块检索更精准一些,能直接定位到某条具体的内容,小块的上下文更丰富,逻辑更连贯

3.给LlamaIndex代码添加代码注释。

import os
# os.environ['HF_ENDPOINT']='https://hf-mirror.com'
from dotenv import load_dotenv
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings 
from llama_index.llms.dashscope import DashScope
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

load_dotenv()

# 模型配置
Settings.llm = DashScope(model="qwen-plus", api_key=os.getenv("DASHSCOPE_API_KEY"))
Settings.embed_model = HuggingFaceEmbedding("BAAI/bge-small-zh-v1.5")

# 自动识别文件格式并读取全文,返回一个包含文档原始文本和元数据的 Document 对象列表。
docs = SimpleDirectoryReader(input_files=["../../data/C1/markdown/easy-rl-chapter1.md"]).load_data()

# 做向量索引,将文本切片并转换为向量存储
index = VectorStoreIndex.from_documents(docs)

# 创建查询引擎,准备进行语义搜索和答案生成
query_engine = index.as_query_engine()

print(query_engine.get_prompts())

print(query_engine.query("文中举了哪些例子?"))

参考文章 DataWhale All-in-RAG | 大模型应用开发实战一:RAG技术全栈指南

引用代码 github.com/datawhalech…