前言
在大模型应用开发中,RAG(检索增强生成) 是最常用、最落地的技术。它可以让 AI 基于你自己的 PDF 文档进行回答,而不是胡编乱造。
本文带你从零实现:
读取本地 PDF 文件
文本分块(切分长文本)
文本向量化(阿里通义 DashScope)
构建 FAISS 本地向量库
文档检索问答
一、环境安装
python
pip install langchain langchain-community langchain-text-splitters
pip install pypdf faiss-cpu
pip install dashscope # 阿里通义 embedding
二、完整可运行代码
python
# 1. 导入依赖
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.embeddings import DashScopeEmbeddings
import os
# 2. 加载 PDF 文档
loader = PyPDFLoader("./PDFQA/卢浮宫.pdf")
docs = loader.load()
# 3. 文本分块(关键步骤)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=100,
separators=["\n\n", "\n", "。", "!", "?", ",", "、", ""]
)
texts = text_splitter.split_documents(docs)
# 4. 初始化向量模型(阿里通义)
embeddings_model = DashScopeEmbeddings(
model="text-embedding-v2",
dashscope_api_key=os.getenv("DASHSCOPE_API_KEY"),
)
# 5. 构建 FAISS 向量库
db = FAISS.from_documents(texts, embeddings_model)
# 6. 创建检索器
retriever = db.as_retriever()
# 7. 开始检索问答
print("===== 问题1:卢浮宫这个名字怎么来的? =====")
retrieved_docs = retriever.invoke("卢浮宫这个名字怎么来的?")
print(retrieved_docs[0].page_content)
print("\n===== 问题2:是否可以使用闪光灯? =====")
retrieved_docs = retriever.invoke("是否可以使用闪光灯")
print(retrieved_docs[0].page_content)
三、代码逐行超详细讲解
- 文档加载:读取 PDF
python
loader = PyPDFLoader("./PDFQA/卢浮宫.pdf")
docs = loader.load()
使用 PyPDFLoader 加载本地 PDF 文件
返回 Document 列表,一页 = 一个 Document
包含文本内容 page_content 和元信息 metadata
- 文本分块:RAG 最核心步骤
python
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每块大小
chunk_overlap=100, # 块之间重叠
separators=["\n\n", "\n", "。", "!", "?", ",", "、", ""]
)
texts = text_splitter.split_documents(docs)
为什么要分块?
- 大模型有输入长度限制
- 长文本必须切成小块才能检索
- 分块越好,检索越准
参数说明:
chunk_size=500:每块 500 字符
chunk_overlap=100:块之间重叠 100 字符,保证语义连贯
separators:按中文标点、换行符智能切分,最适合中文
- 向量模型:阿里通义 DashScope
python
embeddings_model = DashScopeEmbeddings(
model="text-embedding-v2",
dashscope_api_key=os.getenv("DASHSCOPE_API_KEY"),
)
将文本变成向量(数字数组)
向量相似 = 语义相似
国内稳定、速度快、免费额度高
- 构建 FAISS 本地向量库
python
db = FAISS.from_documents(texts, embeddings_model)
FAISS 是 Meta 开源的高性能本地向量数据库
不需要服务器,直接本地文件运行
速度极快,适合个人项目
- 创建检索器
python
retriever = db.as_retriever()
把向量库变成可查询的检索器
输入问题 → 返回最相关的文本块
- 开始提问(文档检索)
python
retrieved_docs = retriever.invoke("卢浮宫这个名字怎么来的?")
print(retrieved_docs[0].page_content)
系统自动在 PDF 里查找最相关的内容
返回结果按相似度从高到低排序
0\] 就是最匹配的答案 四、运行效果示例 ```python ===== 问题1:卢浮宫这个名字怎么来的? ===== 卢浮宫最初是用于防御的城堡,名称来源有两种说法... ===== 问题2:是否可以使用闪光灯? ===== 博物馆内禁止使用闪光灯拍照,以免对文物造成损害... ``` 五、本项目的核心价值 这就是 RAG 的底层核心流程: 加载文档 切分文本 向量化 建库 检索 学会这套流程,你就能做: PDF 智能问答 文档知识库 企业内部问答机器人 小说 / 论文检索工具 六、总结 本文实现了一个轻量、高效、中文友好的 PDF 检索系统: 使用 PyPDFLoader 读取 PDF 使用 RecursiveCharacterTextSplitter 智能分块 使用阿里通义 DashScopeEmbeddings 向量化 使用 FAISS 构建本地向量库 实现精准的文档内容检索 这是大模型应用开发必须掌握的基础技能!