在大语言模型(LLM)飞速发展的今天,其在自然语言理解、生成等领域展现出强大能力,但同时也存在“知识滞后”“事实性错误”等固有缺陷。检索增强生成(Retrieval-Augmented Generation,简称RAG)技术应运而生,通过将“检索外部知识库”与“LLM生成”相结合,有效弥补了LLM的不足,让生成内容更具准确性、时效性和专业性。本文将从RAG技术的核心原理、工作流程、核心组件出发,结合完整代码示例,带大家从零搭建一个简单的RAG系统。
RAG的核心思想是“先检索,后生成”:在LLM生成回复之前,先从外部知识库中检索与用户问题相关的信息,将这些信息作为“上下文”与用户问题一起输入给LLM,让LLM基于检索到的准确信息进行回复。其核心价值在于:

一个完整的RAG系统主要包含两大阶段:数据准备阶段和查询推理阶段,具体流程如下:

搭建RAG系统需选择合适的核心组件,以下是主流且易上手的组件组合(适合初学者):
组件类型 | 推荐选型 | 优势 |
|---|---|---|
文档分割工具 | LangChain RecursiveCharacterTextSplitter | 自适应不同文档格式,可自定义片段长度和重叠度 |
嵌入模型 | Hugging Face sentence-transformers/all-MiniLM-L6-v2 | 轻量高效,开源免费,支持多语言,适合小规模场景 |
向量数据库 | Chroma | 轻量级,无需复杂部署,支持内存模式,适合快速验证 |
大语言模型 | OpenAI GPT-3.5-turbo(或开源的Llama 2) | GPT-3.5-turbo生成质量高、调用便捷;Llama 2可本地部署,隐私性好 |
开发框架 | LangChain | 封装了RAG全流程组件,降低开发难度,支持多组件灵活集成 |

本部分将使用上述组件,搭建一个“Python学习知识库”的RAG系统,支持用户查询Python相关知识点。
首先安装所需依赖库:
# 安装LangChain(RAG开发框架)
pip install langchain
# 安装嵌入模型依赖
pip install sentence-transformers
# 安装向量数据库Chroma
pip install chromadb
# 安装OpenAI SDK(调用GPT模型)
pip install openai
# 安装文档加载工具(用于加载文本文件)
pip install python-dotenv代码分为5个模块:环境配置、数据准备(加载+分割+编码+存储)、检索模块、生成模块、RAG整体流程封装。
import os
from dotenv import load_dotenv
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import RetrievalQA
# ---------------------- 1. 环境配置 ----------------------
# 加载环境变量(需在.env文件中配置OPENAI_API_KEY)
load_dotenv()
openai_api_key = os.getenv("OPENAI_API_KEY")
# 配置组件参数
# 文档分割参数:片段长度500字符,重叠度50字符(保证上下文连贯性)
CHUNK_SIZE = 500
CHUNK_OVERLAP = 50
# 嵌入模型:使用sentence-transformers的轻量模型
EMBEDDING_MODEL_NAME = "all-MiniLM-L6-v2"
# 向量数据库存储路径
VECTOR_DB_PATH = "./chroma_python_knowledge"
# LLM模型:GPT-3.5-turbo
LLM_MODEL_NAME = "gpt-3.5-turbo"
# ---------------------- 2. 数据准备:构建知识库 ----------------------
def build_knowledge_base(document_paths):
"""
加载文档、分割、编码并存储到向量数据库
:param document_paths: 文档路径列表(本示例使用.txt文档)
:return: 向量数据库检索器
"""
# 1. 加载文档(此处简化处理,加载.txt文本)
texts = []
for path in document_paths:
with open(path, "r", encoding="utf-8") as f:
texts.append(f.read())
# 2. 文档分割
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=CHUNK_SIZE,
chunk_overlap=CHUNK_OVERLAP,
length_function=len
)
splits = text_splitter.split_text("\n\n".join(texts)) # 合并所有文本后分割
# 3. 初始化嵌入模型
embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_NAME)
# 4. 构建并存储向量数据库
db = Chroma.from_texts(
texts=splits,
embedding=embeddings,
persist_directory=VECTOR_DB_PATH
)
db.persist() # 持久化存储
# 5. 创建检索器(返回Top 3最相似片段)
retriever = db.as_retriever(search_kwargs={"k": 3})
return retriever
# ---------------------- 3. 构建RAG生成链 ----------------------
def build_rag_chain(retriever):
"""
构建检索-生成链
:param retriever: 向量数据库检索器
:return: RAG链
"""
# 定义Prompt模板:将检索到的上下文和用户问题组合
prompt_template = """
你是一个Python学习助手,仅基于提供的上下文信息回答用户问题。
如果上下文没有相关信息,直接说明“没有找到相关知识点”,不要编造内容。
上下文信息:
{context}
用户问题:
{question}
回答:
"""
# 初始化Prompt模板
prompt = PromptTemplate(
template=prompt_template,
input_variables=["context", "question"]
)
# 初始化LLM
llm = ChatOpenAI(
model_name=LLM_MODEL_NAME,
api_key=openai_api_key,
temperature=0.3 # 降低随机性,保证回答准确性
)
# 构建检索-生成链
rag_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 将所有检索到的上下文塞入Prompt
retriever=retriever,
chain_type_kwargs={"prompt": prompt},
return_source_documents=True # 返回检索到的原始上下文(用于验证)
)
return rag_chain
# ---------------------- 4. 核心查询函数 ----------------------
def rag_query(rag_chain, question):
"""
执行RAG查询
:param rag_chain: RAG链
:param question: 用户问题
:return: 生成的回答和检索到的上下文
"""
result = rag_chain({"query": question})
answer = result["result"]
source_documents = result["source_documents"]
return answer, source_documents
# ---------------------- 5. 测试运行 ----------------------
if __name__ == "__main__":
# 准备测试文档(需提前创建,示例文档内容为Python基础知识点)
test_documents = ["./python_basics.txt"] # 文档内容示例:Python变量、函数、列表操作等基础知识点
# 步骤1:构建知识库
print("正在构建Python学习知识库...")
retriever = build_knowledge_base(test_documents)
# 步骤2:构建RAG链
print("正在初始化RAG生成链...")
rag_chain = build_rag_chain(retriever)
# 步骤3:测试查询
test_questions = [
"Python中如何定义函数?",
"列表和元组的区别是什么?",
"Python的装饰器有什么作用?"
]
for question in test_questions:
print(f"\n用户问题:{question}")
answer, sources = rag_query(rag_chain, question)
print(f"回答:{answer}")
print("检索到的相关知识点:")
for i, source in enumerate(sources, 1):
print(f" {i}. {source.page_content}").env文件,填入OpenAI API密钥:OPENAI_API_KEY=你的API密钥;
CTransformers封装调用本地模型。
python_basics.txt文件,填入Python基础知识点(如变量定义、函数、列表操作等),示例内容: Python函数定义:使用def关键字,语法为def 函数名(参数): 函数体。例如: def add(a, b): return a + b 列表和元组的区别: 1. 列表是可变对象(mutable),可通过append、insert等方法修改元素; 2. 元组是不可变对象(immutable),创建后无法修改元素; 3. 列表使用[]包裹,元组使用()包裹。 Python装饰器:用于在不修改原函数代码的前提下,增强函数功能。使用@装饰器名语法,例如: def log_decorator(func): def wrapper(*args, **kwargs): print(f"调用函数:{func.__name__}") return func(*args, **kwargs) return wrapper @log_decorator def hello(): print("Hello Python")
./chroma_python_knowledge目录);
运行代码后,对于问题“Python中如何定义函数?”,系统会从知识库中检索到“Python函数定义”相关的文本片段,然后让GPT-3.5-turbo基于该片段生成准确回答,避免了LLM编造错误语法的情况。若查询知识库中没有的内容(如“Python 4.0何时发布?”),系统会直接提示“没有找到相关知识点”。
上述实现是基础版RAG系统,实际应用中需根据场景进行优化,核心优化方向包括:
PyPDFLoader、MarkdownLoader);
RAG技术因其低门槛、高准确性的特点,已广泛应用于多个领域:
RAG技术通过“检索增强生成”的核心逻辑,有效弥补了LLM的知识滞后和事实性缺陷,是当前LLM落地应用的关键技术之一。本文从原理、流程、组件选型出发,提供了可直接运行的基础版RAG系统代码,帮助读者快速入门。实际应用中,需根据具体场景优化文档分割、嵌入模型、检索策略等环节,才能实现更高性能的RAG系统。随着技术的发展,RAG与微调、Agent等技术的结合,将进一步拓展LLM的应用边界,推动AI在各行业的深度落地。