澳八机器人 15天学会AI应用开发(十二)从PDF、WORD、网页构建RAG
前面的教程我们已经掌握了从纯文本TXT文件读取内容、搭建基础向量检索的方法,但日常办公和实际业务里,纯文本文件占比极低,大家接触更多的是PDF、Word这类标准办公文档,还有大量分布在公开网页里的行业资料。今天我们就把这三类主流数据源打通,一步步实现从多格式文件直接构建可用的RAG知识库,全程不需要依赖LangChain等重型框架,自己动手就能掌握每一个核心环节。
一、环境准备:安装三类文档解析依赖库
在开始写代码前,先在终端执行命令安装对应解析工具,不同文件格式有专门适配的高效库,比通用解析方案准确率更高:
bash
# PDF解析工具,比传统PyPDF2更擅长处理复杂排版
pip install pdfplumber
# Word文档解析工具,专门处理docx格式办公文件
pip install python-docx
# 网页正文提取工具,自动剔除广告、导航栏等冗余内容
pip install trafilatura
# 网页请求基础库
pip install requests
# 向量模型和向量检索依赖
pip install sentence-transformers faiss-cpu numpy
所有依赖都适配Python 3.8及以上版本,安装完成后就可以开始逐个实现数据源的文本读取逻辑。
二、分格式实现文本解析
我们针对三类不同数据源分别编写解析函数,保证不同格式的内容都能被完整、干净地提取出来。
1. PDF文件解析
pdfplumber可以精准识别PDF里的文字排版、换行和表格结构,逐页读取后拼接成完整文本,还能自动过滤页眉页脚的冗余内容:
python
import pdfplumber
def extract_pdf_text(file_path):
full_text = ""
with pdfplumber.open(file_path) as pdf:
for page in pdf.pages:
# 提取单页文本,自动保留段落换行
page_text = page.extract_text()
if page_text:
full_text += page_text + "\n"
return full_text
这个方法对扫描版PDF无效,如果是扫描件需要先搭配OCR工具完成文字识别,再接入后续流程。
2. Word文档解析
通过python-docx直接读取docx文件的所有段落文本,同时可以扩展支持读取表格内容,适配绝大多数办公场景的Word文档:
python
from docx import Document
def extract_docx_text(file_path):
doc = Document(file_path)
full_text = []
# 读取所有普通段落
for para in doc.paragraphs:
if para.text.strip():
full_text.append(para.text)
# 可选:读取表格内容,适合财报、数据类文档
for table in doc.tables:
for row in table.rows:
row_text = " | ".join([cell.text for cell in row.cells])
full_text.append(row_text)
return "\n".join(full_text)
注意这个方案仅支持docx格式,老旧的doc格式需要先转成docx再处理,避免解析失败。
3. 网页内容解析
直接用requests爬取网页源码后,通过trafilatura自动提取纯净正文,自动剔除侧边栏、广告、无关链接等噪音内容,比传统BeautifulSoup解析更省心:
python
import requests
import trafilatura
def extract_webpage_text(url):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
resp = requests.get(url, headers=headers, timeout=10)
resp.encoding = "utf-8"
# 自动提取正文,返回干净的纯文本
clean_text = trafilatura.extract(resp.text)
return clean_text if clean_text else "网页内容提取失败"
这个方法对绝大多数静态资讯网页适配效果很好,动态渲染的网页需要搭配Selenium等工具先完成页面加载。
三、统一文本分块逻辑
不管是从PDF、Word还是网页拿到的长文本,都需要切分成适合向量化的小片段,我们按句号作为语义分割边界,保证每个文本块的语义完整性,避免把完整句子从中间切断:
python
def split_text(raw_text, max_chunk_len=120):
# 先统一处理换行和多余空格
raw_text = raw_text.replace("\n", "").strip()
# 按中文句号分割句子
sentences = raw_text.split("。")
chunks = []
current_chunk = ""
for sen in sentences:
sen = sen.strip()
if not sen:
continue
# 补回句号保证语义完整
sen += "。"
if len(current_chunk) + len(sen) <= max_chunk_len:
current_chunk += sen
else:
if current_chunk:
chunks.append(current_chunk.strip())
current_chunk = sen
# 加入最后剩余的片段
if current_chunk:
chunks.append(current_chunk.strip())
return chunks
这里的max_chunk_len可以根据你使用的Embedding模型上下文长度调整,中文场景下100-200字是比较稳妥的选择。
四、整合构建完整RAG检索流程
把前面的解析、分块逻辑和向量模型、FAISS向量库结合起来,就可以直接实现一个支持多数据源的轻量RAG系统:
python
from sentence_transformers import SentenceTransformer
import faiss
import numpy as np
# 1. 加载中文Embedding模型,这里用bge-small-zh-v1.5,效果轻量且精准
embed_model = SentenceTransformer("./bge-small-zh-v1.5", device="cpu")
# 2. 示例:从医保局公开网页构建知识库,也可以替换成本地PDF/Word路径
target_url = "https://www.nhsa.gov.cn/art/2025/12/25/art_14_19130.html"
raw_knowledge = extract_webpage_text(target_url)
# 也可以替换成本地文件读取:
# raw_knowledge = extract_pdf_text("政策文件.pdf")
# raw_knowledge = extract_docx_text("内部培训资料.docx")
# 3. 文本分块
knowledge_chunks = split_text(raw_knowledge)
# 4. 生成向量并构建FAISS索引
vectors = embed_model.encode(knowledge_chunks, normalize_embeddings=True)
vector_dim = vectors.shape
index = faiss.IndexFlatIP(vector_dim)
index.add(np.array(vectors).astype("float32"))
# 5. 实现检索函数
def rag_query(user_query, top_k=3):
query_vec = embed_model.encode([user_query], normalize_embeddings=True)
scores, indices = index.search(np.array(query_vec).astype("float32"), top_k)
# 返回最相关的文本片段和对应相似度得分
return [
{"content": knowledge_chunks[idx], "score": float(scores[i])}
for i, idx in enumerate(indices)
]
# 测试:输入问题即可拿到相关知识库片段
result = rag_query("2025年医保报销的新规则是什么?")
for item in result:
print(f"相似度:{item['score']:.2f} 内容:{item['content']}")
五、实战优化小技巧
不同数据源可以给文本块打上来源元数据,比如标记是来自PDF第几页、哪个网页链接,后续回答时可以直接标注信息来源,方便用户溯源。
网页爬取时要遵守目标网站的robots协议,控制请求频率避免给对方服务器造成压力。
如果是大量文档批量构建知识库,可以把生成好的FAISS索引和文本块持久化保存到本地,下次启动直接加载,不用重复向量化节省时间。
到这里你就已经掌握了从三类最常用数据源搭建RAG的完整流程,没有黑盒框架的遮挡,每一步文本怎么来、怎么切、怎么转成向量都完全可控,后续遇到检索不准的问题,你可以直接从解析、分块、向量化三个环节逐一排查,不用再对着框架的黑盒参数盲目调试。
需要我为你补充多文件批量导入的完整代码吗?这样你可以一次性把整个文件夹的PDF、Word文件全部导入RAG知识库。