news 2026/7/31 1:45:21

LangChain 入门实战(六):企业知识库预处理全流程实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangChain 入门实战(六):企业知识库预处理全流程实战

1. 本章目标

企业知识库资料存放在各类文件:产品说明书、员工手册、售后规则、技术文档、FAQ。使用大模型加载私有资料两大核心步骤:读取文件 → 切分文档

学习完成后掌握:

  1. 理解 LangChain Document 对象
  2. 加载 TXT、Markdown 文件
  3. 加载文本型 PDF 文件
  4. 理解长文档切分的必要性
  5. 使用 RecursiveCharacterTextSplitter
  6. 合理配置 chunk_size、chunk_overlap
  7. 保留来源、页码等元数据 metadata
  8. 实现企业知识库文档预处理完整案例

2. 文档处理标准流程

plaintext

TXT / MD / PDF 文件 ↓ Document Loader(文档加载器) ↓ Document 列表 ↓ Text Splitter(文本切分器) ↓ 小型 Document 文档块 chunk ↓ Embedding 向量化 → 向量数据库

本章范围:文件 → Document → 文档块 下一章:文档块向量化、存入向量数据库

3. 安装依赖

bash

运行

pip install langchain-community langchain-text-splitters pypdf # 清华镜像加速 pip install langchain-community langchain-text-splitters pypdf -i https://pypi.tuna.tsinghua.edu.cn/simple

表格

依赖作用
langchain-community提供各类文档加载器
langchain-text-splitters文本切分工具
pypdf解析文本型 PDF

本章无需调用大模型,不会消耗 API 额度

4. Document 文档对象

LangChain 使用Document统一封装文本数据。两个核心属性:

  1. page_content:文档正文内容
  2. metadata:元数据(字典格式,描述数据的数据)

示例代码:01_document_basic.py

python

运行

from langchain_core.documents import Document document = Document( page_content="公司所有正式员工每年享有 5 天带薪年假。", metadata={ "source": "员工手册.md", "category": "考勤制度", } ) print(document.page_content) print(document.metadata)

常用元数据字段:文件路径、文件名、PDF 页码、文档分类、chunk_id、文本起始位置。作用:问答时展示资料来源;支持向量库进行条件过滤筛选。

5. 文件加载实战

5.1 TextLoader 加载 TXT

目录结构

plaintext

chapter06/ ├── data/ │ └── employee_handbook.txt └── 02_load_text.py

python

运行

from langchain_community.document_loaders import TextLoader loader = TextLoader( file_path="data/employee_handbook.txt", encoding="utf-8", ) documents = loader.load() print(f"文档数量:{len(documents)}") print(f"文档内容:\n{documents[0].page_content}") print(f"元数据:{documents[0].metadata}")

重点:

  • load()返回Document 列表,单个文件同样返回列表
  • encoding="utf-8"解决 Windows 环境中文乱码

5.2 TextLoader 加载 Markdown

md 文件可直接使用 TextLoader03_load_markdown.py

python

运行

from langchain_community.document_loaders import TextLoader loader = TextLoader( file_path="data/refund_policy.md", encoding="utf-8" ) documents = loader.load() print("文档数量:" + str(len(documents))) print(documents[0].page_content) print(documents[0].metadata)

5.3 PyPDFLoader 加载 PDF

⚠️ 仅支持可复制文字的文本 PDF;扫描图片版 PDF 需要 OCR 识别04_load_pdf.py

python

运行

from langchain_community.document_loaders import PyPDFLoader loader = PyPDFLoader( file_path="data/XX销售有限公司员工守则.pdf" ) documents = loader.load() print("文档数量:" + str(len(documents))) PDF 每一页自动生成一个独立 Document for document in documents: print(document.page_content[-20:]) print(document.metadata) print("当前页码:", document.metadata['page'])

注意:metadata 中page页码从 0 开始计数

6. 为什么需要切分长文档

超长文档直接存入向量库存在诸多问题:

  1. 文本长度超出大模型上下文窗口限制
  2. 全文参与向量化与检索,Token 成本高
  3. 用户仅询问局部信息,大量无关文本造成干扰
  4. 向量相似度检索难以精准定位片段

解决方案:将大文档切分成多个语义相对独立的小块(chunk)

7. RecursiveCharacterTextSplitter 递归文本切分器

中文知识库首选切分器。分隔符优先级:["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""]

切分逻辑:优先按段落切割;段落过长则逐级降级,依次使用换行、句号、逗号,最后强制切割,最大限度保证语句完整。

核心参数

  1. chunk_size:单个文档块最大长度(默认按字符统计)
  2. chunk_overlap:相邻文档块重叠字符数量

重叠作用:避免完整语句被一刀切断,保留上下文关联

重叠不宜过大:会产生大量重复文本,增加存储压力与重复检索结果。推荐初始参数:chunk_size=300chunk_overlap=50

两个核心方法

  1. split_text(text)接收普通字符串,返回字符串列表,丢失元数据,仅用于测试
  2. split_documents(documents)接收 Document 列表,返回 Document 列表,保留元数据,正式项目使用

案例 1:切分普通文本 05_split_text.py

python

运行

from langchain_text_splitters import RecursiveCharacterTextSplitter text = """ 员工考勤制度 工作时间为周一至周五,每天 9:00 至 18:00。 员工每月可以申请两次补卡。超过两次后,需要部门负责人审批。 员工请假制度 请假一天以内由直属负责人审批。 请假超过一天,需要部门负责人审批。 病假需要提供医院开具的有效证明。 员工年假制度 正式员工每年享有 5 天带薪年假。 工作满三年后,每年享有 10 天带薪年假。 """ splitter = RecursiveCharacterTextSplitter( chunk_size=300, chunk_overlap=50, separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""] ) chunks = splitter.split_text(text) print(len(chunks)) for index, chunk in enumerate(chunks, start=1): print("*" * 40) print(f"第{index}个文件块的内容:") print(chunk)

补充:enumerate(对象, start=1)同时获取序号与内容,start 自定义起始编号

案例 2:切分 Document,保留元数据 06_split_documents.py

python

运行

from langchain_community.document_loaders import PyPDFLoader from langchain_core.documents import Document from langchain_text_splitters import RecursiveCharacterTextSplitter loader = PyPDFLoader( file_path="data/XX销售有限公司员工守则.pdf" ) documents = loader.load() print("原始文档数量:", len(documents)) splitter = RecursiveCharacterTextSplitter( chunk_size=200, chunk_overlap=30, add_start_index=True, separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""] ) chunks = splitter.split_documents(documents) print("切分后文档数量:", len(chunks)) for index, chunk in enumerate(chunks, start=1): print(isinstance(chunk, Document)) print(f"第{index}文档预览:") print(chunk.page_content[:20]) print(chunk.metadata)

add_start_index=True:自动在元数据中增加文本在原始文档内的起始位置

8. 企业综合案例:批量知识库预处理

需求

  1. 递归扫描知识库文件夹,读取所有文件
  2. 根据文件后缀自动选择对应加载器(txt/md/pdf)
  3. 统一追加自定义元数据
  4. 批量切分文档,产出可直接存入向量库的 chunk

前置知识点

  1. 列表 / 集合 / 字典推导式

python

运行

# 列表推导式 even = [i for i in range(1,11) if i%2==0] # 集合推导式(自动去重) set_data = {x for x in [1,2,2,3]} # 字典推导式 square_dict = {i:i*i for i in range(1,6)}
  1. pathlib 文件路径操作
  • rglob("*"):递归遍历当前目录 + 所有子文件夹
  • glob("*"):仅遍历当前文件夹,不进入子目录
  • .suffix文件后缀;.name完整文件名;.stem不带后缀文件名
  1. append vs extend
  • append():将对象整体作为 1 个元素加入列表
  • extend():遍历可迭代对象,逐个追加内部元素

document_processor.py 完整代码

python

运行

from pathlib import Path from langchain_community.document_loaders import TextLoader, PyPDFLoader from langchain_core.documents import Document from langchain_text_splitters import RecursiveCharacterTextSplitter def split_documents(documents: list[Document]) -> list[Document]: splitter = RecursiveCharacterTextSplitter( chunk_size=200, chunk_overlap=30, add_start_index=True, separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""] ) chunks = splitter.split_documents(documents) for index, chunk in enumerate(chunks, start=1): chunk.metadata['chunk_id'] = index return chunks def load_knowledge_base(root_dir: Path) -> list[Document]: all_documents = [] for f in root_dir.rglob("*"): if f.is_dir(): continue file_suffix = f.suffix.lower() file_path = str(f) docs = [] if file_suffix in ['.txt', '.md']: loader = TextLoader( file_path=file_path, encoding="utf-8" ) docs = loader.load() elif file_suffix == '.pdf': loader = PyPDFLoader(file_path=file_path) docs = loader.load() # 统一追加自定义元数据 for document in docs: document.metadata["file_name"] = f.name document.metadata["file_type"] = file_suffix all_documents.extend(docs) return all_documents def main(): kb_path = Path("knowledge_base") documents = load_knowledge_base(kb_path) print("原始文档数量:", len(documents)) chunks = split_documents(documents) print("切分后文档块数量:", len(chunks)) for chunk in chunks: print("~" * 30) metadata = chunk.metadata print(f"chunk_id:{metadata['chunk_id']}") print(f"来源文件:{metadata['file_name']}") print(f"内容预览:{chunk.page_content[:30]}") if name == 'main': main()

运行命令

bash

运行

python document_processor.py

9. 切分参数选型参考

表格

文档类型配置思路
FAQ 问答文档chunk_size 偏小,保证单条问答完整不拆分
员工制度、规范文档chunk_size 200 ~ 350
产品操作手册块尺寸适当放大,避免操作步骤被切断
技术文档尽量保留标题和对应正文,chunk 偏大

调优判断标准:语义完整、标题不与正文分离、操作步骤不截断、无大量重复 chunk,最终依靠检索效果验证参数。

10. 常见问题

  1. chunk_size 统计字符还是 token?默认按照字符长度len()计算;需要精确按 token 切割使用TokenTextSplitter(进阶)

  2. chunk_overlap 设置越大越好?不是,推荐取值为 chunk_size 的 10% ~ 20%

  3. PDF 提取空白、乱码?文件为扫描图片 PDF、加密 PDF、特殊字体 PDF;本章加载器仅支持原生文本 PDF

  4. 为什么不能直接把完整文档交给模型?超长文本超出上下文限制、token 成本高、检索精准度差;RAG 标准流程必须分块

  5. load() 和 lazy_load()

  • load():一次性全部加载到内存,适合小型知识库
  • lazy_load():迭代器懒加载,节省内存,适合海量文件场景

11. 本章核心总结

  1. Document = page_content(正文) + metadata(元数据)
  2. TextLoader 加载 txt/md;PyPDFLoader 加载文本 PDF
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/31 1:44:38

go2rtc架构深度解析:现代流媒体协议转换引擎的技术实现

go2rtc架构深度解析:现代流媒体协议转换引擎的技术实现 【免费下载链接】go2rtc Ultimate camera streaming application 项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc 在物联网和智能家居快速发展的今天,摄像头流媒体服务面临着前所…

作者头像 李华
网站建设 2026/7/31 1:43:04

基于51单片机的密码锁系统设计:从Proteus仿真到普中开发板实战

1. 项目缘起:从“锁”到“系统”的工程思维跃迁几年前,我还在大学实验室里捣鼓那些最基础的51单片机实验,流水灯、数码管、按键扫描,总觉得这些零散的知识点离一个“完整的产品”还很遥远。直到有一次,导师布置了一个“…

作者头像 李华
网站建设 2026/7/31 1:40:08

基于微信小程序的校园社交平台的设计与实现

校园社交平台的现状与需求随着移动互联网技术的快速发展,社交平台已成为大学生日常生活的重要组成部分。传统社交平台如微信、QQ等虽然功能丰富,但缺乏针对校园场景的垂直化设计,无法完全满足学生在学习、生活、社交等方面的个性化需求。大学…

作者头像 李华
网站建设 2026/7/31 1:39:27

办公用Agent工具:提升工作效率的智能助手

随着人工智能技术的发展,办公用Agent工具正在重新定义知识工作者的日常工作流程。这类工具能够理解自然语言任务,自动处理重复性工作,辅助完成信息搜集、文档生成、数据分析等复杂任务,帮助团队聚焦高价值创造环节。沿着 From AI …

作者头像 李华
网站建设 2026/7/31 1:39:12

OpenCV LUT查找表:图像处理性能优化的核心技术与实战指南

1. 项目概述:为什么LUT是图像处理的“快捷键”?在C和OpenCV的图像处理世界里,我们经常需要对图像的像素值进行批量、快速的变换。比如,你想把一张照片的整体亮度调高,或者给视频加上一个复古的胶片滤镜。最直接的想法可…

作者头像 李华