RAG 从零到一:让大模型读懂你的文档

RAG 从零到一:让大模型读懂你的文档

目录

  1. 什么是 RAG
  2. RAG 的核心流程
  3. 环境搭建与依赖安装
  4. 完整代码实现
  5. 代码逐行解析
  6. 运行测试
  7. 优化建议
  8. 总结

一、什么是 RAG

RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合信息检索和文本生成的技术。

核心思想:让大模型在回答问题前,先从你的文档中检索相关信息,然后基于这些信息生成答案。

解决的核心问题:

问题 说明 RAG 的解决方案

知识陈旧 大模型训练数据有截止日期 实时检索最新文档

幻觉问题 模型会编造不存在的信息 强制基于检索内容回答

私有数据 模型不知道你的内部文档 让模型读取你的文档

通俗理解:

· 普通大模型 = 闭卷考试(凭记忆回答)

· RAG = 开卷考试(允许查阅资料)


二、RAG 的核心流程

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                        RAG 完整流程                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   阶段一:索引(预处理)                                          │
│   ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐     │
│   │ 加载文档 │ -> │ 文本分割 │ -> │ 向量化  │ -> │ 存储    │     │
│   │ PDF/TXT │    │ Chunk   │    │ Embed   │    │ Chroma  │     │
│   └─────────┘    └─────────┘    └─────────┘    └─────────┘     │
│                                                                  │
│   阶段二:检索(查询时)                                          │
│   ┌─────────┐    ┌─────────┐    ┌─────────┐                    │
│   │ 用户问题 │ -> │ 向量化  │ -> │ 相似度  │                    │
│   │ "什么是  │    │ Embed   │    │ 检索    │                    │
│   │  RAG?"  │    │         │    │ Top-K   │                    │
│   └─────────┘    └─────────┘    └─────────┘                    │
│                                       │                          │
│                                       ▼                          │
│   阶段三:生成(回答)                                            │
│   ┌─────────┐    ┌─────────┐    ┌─────────┐                    │
│   │ 问题+    │ -> │ 大模型  │ -> │ 最终    │                    │
│   │ 检索结果 │    │ LLM    │    │ 答案    │                    │
│   └─────────┘    └─────────┘    └─────────┘                    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

三、环境搭建与依赖安装

3.1 依赖库清单

text 复制代码
langchain
langchain-openai
langchain-community
langchain-chroma
langchain-huggingface
chromadb
sentence-transformers
pypdf
python-dotenv

3.2 一键安装

bash 复制代码
pip install langchain langchain-openai langchain-community langchain-chroma langchain-huggingface chromadb sentence-transformers pypdf python-dotenv -i https://pypi.tuna.tsinghua.edu.cn/simple

3.3 配置 API Key

创建 .env 文件:

bash 复制代码
DASHSCOPE_API_KEY="你的阿里云百炼API Key"
DASHSCOPE_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"

3.4 准备测试文档

创建 sample.txt:

text 复制代码
人工智能(AI)是计算机科学的一个分支,致力于创建能够执行通常需要人类智能的任务的系统。
这些任务包括视觉感知、语音识别、决策制定和语言翻译等。

机器学习是人工智能的一个子集,它使系统能够从数据中学习并改进,而无需明确编程。
深度学习是机器学习的一个子集,使用多层神经网络来处理复杂的数据模式。

大语言模型(LLM)如GPT、通义千问等,是基于深度学习技术的模型,能够理解和生成人类语言。
LangChain 是一个用于开发由大语言模型驱动的应用程序的框架。

检索增强生成(RAG)是一种结合信息检索和文本生成的技术,可以让大模型基于外部知识库回答问题,
有效解决大模型知识陈旧和幻觉问题。

四、完整代码实现

python 复制代码
# rag_demo.py
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_chroma import Chroma
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain

# 加载环境变量
load_dotenv()

# 初始化大模型
llm = ChatOpenAI(
    model="qwen3-max",
    temperature=0.7,
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base=os.getenv("DASHSCOPE_BASE_URL"),
)

print("=" * 60)
print("RAG 从零到一:让大模型读懂你的文档")
print("=" * 60)

# ========== 步骤1:加载文档 ==========
print("\n📄 步骤1:加载文档...")
loader = TextLoader("sample.txt", encoding="utf-8")
documents = loader.load()
print(f"✅ 已加载 {len(documents)} 个文档")

# ========== 步骤2:分割文档 ==========
print("\n✂️ 步骤2:分割文档...")
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=300,      # 每块最大字符数
    chunk_overlap=50,    # 块之间的重叠字符数
)
chunks = text_splitter.split_documents(documents)
print(f"✅ 文档已分割成 {len(chunks)} 个文本块")

# 显示前3个块
print("\n📝 文本块示例:")
for i, chunk in enumerate(chunks[:3]):
    print(f"   块{i+1}: {chunk.page_content[:60]}...")

# ========== 步骤3:向量化 ==========
print("\n🔢 步骤3:向量化(将文本转换为向量)...")
embeddings = HuggingFaceEmbeddings(
    model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
)
print("✅ Embedding 模型已加载")

# ========== 步骤4:存储向量 ==========
print("\n🗄️ 步骤4:创建向量数据库...")
vectorstore = Chroma.from_documents(chunks, embeddings)
print("✅ 向量数据库已创建")

# ========== 步骤5:创建检索器 ==========
print("\n🔍 步骤5:创建检索器...")
retriever = vectorstore.as_retriever(
    search_kwargs={"k": 3}  # 每次检索返回3个最相关的文本块
)
print("✅ 检索器已创建")

# ========== 步骤6:创建 RAG 链 ==========
print("\n🔗 步骤6:创建 RAG 链...")

# 定义提示词模板
system_prompt = """
你是一个基于文档的问答助手。请根据以下检索到的文档内容回答问题。

检索到的相关内容:
{context}

问题:{input}

规则:
1. 只根据提供的文档内容回答
2. 如果文档中没有相关信息,明确说"根据现有文档无法回答"
3. 回答要准确、简洁
"""

prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    ("human", "{input}")
])

# 创建文档组合链
document_chain = create_stuff_documents_chain(llm, prompt)

# 创建检索链
rag_chain = create_retrieval_chain(retriever, document_chain)

print("✅ RAG 链已创建")

# ========== 步骤7:测试问答 ==========
print("\n" + "=" * 60)
print("💬 开始测试问答")
print("=" * 60)

test_questions = [
    "什么是人工智能?",
    "什么是RAG?",
    "LangChain 是什么?",
    "今天天气怎么样?",  # 文档外的问题
]

for question in test_questions:
    print(f"\n🤔 问题: {question}")
    response = rag_chain.invoke({"input": question})
    print(f"📖 回答: {response['answer']}")

print("\n" + "=" * 60)
print("✅ RAG 演示完成!")
print("=" * 60)

五、代码逐行解析

5.1 文档加载

python 复制代码
from langchain_community.document_loaders import TextLoader

loader = TextLoader("sample.txt", encoding="utf-8")
documents = loader.load()

参数 说明

TextLoader 加载 txt 文件,支持 PDF 可改用 PyPDFLoader

encoding="utf-8" 指定编码,避免中文乱码

load() 返回 Document 对象列表

5.2 文本分割

python 复制代码
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=300,
    chunk_overlap=50,
)
chunks = text_splitter.split_documents(documents)

参数 说明 建议值

chunk_size 每个块的最大字符数 300-1000

chunk_overlap 块之间的重叠字符数 chunk_size 的 10-20%

为什么需要重叠? 防止重要信息被切断在块边界。

5.3 向量化

python 复制代码
from langchain_huggingface import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(
    model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
)

模型 特点 大小

paraphrase-multilingual-MiniLM-L12-v2 支持中文,速度快 ~500MB

shibing624/text2vec-base-chinese 轻量中文 ~120MB

5.4 向量存储

python 复制代码
from langchain_chroma import Chroma

vectorstore = Chroma.from_documents(chunks, embeddings)

from_documents 会自动:

  1. 遍历每个文本块
  2. 调用 Embedding 模型转换为向量
  3. 存储到 Chroma 数据库

5.5 检索器

python 复制代码
retriever = vectorstore.as_retriever(
    search_kwargs={"k": 3}
)

参数 说明

k 返回最相关的 Top-K 个文本块

5.6 RAG 链

python 复制代码
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain

document_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriever, document_chain)

组件 作用

create_stuff_documents_chain 将检索到的文档"填充"到提示词中

create_retrieval_chain 组合检索器和生成链


六、运行测试

6.1 执行脚本

bash 复制代码
python rag_demo.py

6.2 预期输出

复制代码
============================================================
RAG 从零到一:让大模型读懂你的文档
============================================================

📄 步骤1:加载文档...
✅ 已加载 1 个文档

✂️ 步骤2:分割文档...
✅ 文档已分割成 8 个文本块

📝 文本块示例:
   块1: 人工智能(AI)是计算机科学的一个分支...
   块2: 机器学习是人工智能的一个子集...
   块3: 深度学习是机器学习的一个子集...

🔢 步骤3:向量化...
✅ Embedding 模型已加载

🗄️ 步骤4:创建向量数据库...
✅ 向量数据库已创建

🔍 步骤5:创建检索器...
✅ 检索器已创建

🔗 步骤6:创建 RAG 链...
✅ RAG 链已创建

============================================================
💬 开始测试问答
============================================================

🤔 问题: 什么是人工智能?
📖 回答: 人工智能(AI)是计算机科学的一个分支,致力于创建能够执行通常需要人类智能的任务的系统。

🤔 问题: 什么是RAG?
📖 回答: 检索增强生成(RAG)是一种结合信息检索和文本生成的技术,可以让大模型基于外部知识库回答问题,有效解决大模型知识陈旧和幻觉问题。

🤔 问题: LangChain 是什么?
📖 回答: LangChain 是一个用于开发由大语言模型驱动的应用程序的框架。

🤔 问题: 今天天气怎么样?
📖 回答: 根据现有文档无法回答

============================================================
✅ RAG 演示完成!
============================================================

七、优化建议

7.1 分块策略优化

python 复制代码
# 针对不同文档类型调整
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,           # 增大块大小,保留更多上下文
    chunk_overlap=100,        # 增加重叠,避免信息丢失
    separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""]
)

7.2 检索优化

python 复制代码
# 提高检索数量
retriever = vectorstore.as_retriever(
    search_kwargs={"k": 5}    # 返回更多相关块
)

# 设置相似度阈值
retriever = vectorstore.as_retriever(
    search_type="similarity_score_threshold",
    search_kwargs={"score_threshold": 0.7, "k": 3}
)

7.3 提示词优化

python 复制代码
system_prompt = """
你是公司内部文档助手,回答要专业、准确。

参考文档:
{context}

用户问题:{input}

要求:
1. 优先使用文档原文
2. 引用来源
3. 不确定时说不确定
"""

7.4 持久化存储

python 复制代码
# 保存向量数据库,避免重复处理
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db"  # 指定保存目录
)

# 下次直接加载
vectorstore = Chroma(
    persist_directory="./chroma_db",
    embedding_function=embeddings
)

八、常见问题

Q1:首次运行很慢?

首次运行需要下载 Embedding 模型(约 500MB),之后会缓存到本地。

Q2:中文乱码?

确保文档使用 UTF-8 编码,加载时指定 encoding="utf-8"。

Q3:回答不准确?

· 调整 chunk_size 和 chunk_overlap

· 增加 k 值,检索更多相关块

· 优化提示词模板

Q4:内存不足?

· 减小 chunk_size

· 使用更轻量的 Embedding 模型

· 分批处理文档


九、总结

本文完整实现了 RAG 的核心流程:

步骤 功能 代码实现

1 加载文档 TextLoader

2 分割文档 RecursiveCharacterTextSplitter

3 向量化 HuggingFaceEmbeddings

4 存储向量 Chroma.from_documents

5 创建检索器 vectorstore.as_retriever

6 创建 RAG 链 create_retrieval_chain

7 问答测试 rag_chain.invoke

核心代码(极简版):

python 复制代码
# 5 行代码实现 RAG
loader = TextLoader("sample.txt")
chunks = RecursiveCharacterTextSplitter().split_documents(loader.load())
vectorstore = Chroma.from_documents(chunks, HuggingFaceEmbeddings())
retriever = vectorstore.as_retriever()
rag_chain = create_retrieval_chain(retriever, create_stuff_documents_chain(llm, prompt))

相关推荐
挖AI金矿2 小时前
(六)文件与搜索 - 信息处理的正确姿势
人工智能·python·开源·个人开发·ai编程
Fleshy数模2 小时前
Python+MediaPipe 实现实时手部关键点检测(新手避坑完整版)
python
2401_833033622 小时前
c++如何实现简单的文件签名验证_HMAC-SHA1算法应用【进阶】
jvm·数据库·python
重庆若鱼文化创意2 小时前
包装设计公司哪家好?价格差很多时,关键看材质、印刷工艺和实际包装成本
人工智能·python·材质
qq_392690662 小时前
SQL报表查询标准规范_SQL书写规范优化
jvm·数据库·python
爱码小白2 小时前
排除LhPyQt5疑难bug的经验
python·pyqt
好奇龙猫2 小时前
[大学院-python-base gammer learning2: python base programming ]
开发语言·python
2301_803875612 小时前
c++如何通过重定向streambuf流捕获标准错误输出并记录到运行日志【详解】
jvm·数据库·python
2301_795099742 小时前
HTML怎么创建时间轴布局_HTML结构化时间线写法【方法】
jvm·数据库·python