【LangChain.js学习】 文档加载(Loader)与文本分割全解析

核心说明

LangChain 提供丰富的文档加载器(Loader),用于将不同格式(CSV/JSON/JSONL/DOCX/TXT)的文件转换为标准化的 Document 对象(包含 pageContent 文本内容 + metadata 元数据),是构建知识库、文本分析的基础。所有加载器均实现 BaseDocumentLoader 抽象类,保证调用方式统一,部分场景需配合文本分割器处理长文本。

一、核心概念:Document 对象

Document 是 LangChain 处理文本的标准化载体,所有加载器最终都会返回 Document[] 数组,结构如下:

typescript 复制代码
interface Document {
  pageContent: string; // 核心文本内容
  metadata: Record<string, any>; // 元数据(如文件路径、行号、格式等)
}

二、各类文档加载实现

1. CSV 文件加载

适用于表格类数据,每行数据会被解析为一个 DocumentpageContent 为行内容,metadata 包含行号、文件路径等信息。

依赖安装

bash 复制代码
pnpm add d3-dsv

示例文件(./data/data.csv)

## 复制代码
name,age
李白,18
白居易,20

加载代码

typescript 复制代码
import { CSVLoader } from "@langchain/community/document_loaders/fs/csv";
​
// 初始化CSV加载器
const loader = new CSVLoader("./data/data.csv");
// 加载并转换为Document数组
const documents = await loader.load();
​
console.log(documents);
/** 输出示例:
[
  {
    pageContent: "name: 李白, age: 18",
    metadata: { line: 1, source: "./data/data.csv" }
  },
  {
    pageContent: "name: 白居易, age: 20",
    metadata: { line: 2, source: "./data/data.csv" }
  }
]
*/

2. JSON 文件加载

JSONLoader 核心能力是提取JSON对象中字符串类型的键值对值,无法解析JSON数组结构,空路径下会逐行扫描文本提取值,仅适用于单JSON对象场景。

示例文件(./data/data.json)

json 复制代码
{ "name": "李白", "like": "唱歌" }

加载代码

typescript 复制代码
import { JSONLoader } from "@langchain/classic/document_loaders/fs/json";
​
const loader = new JSONLoader("./data/data.json", "");
const documents = await loader.load();
​
console.log(documents);
/** 实际运行输出:
[
  Document {
    pageContent: '李白',
    metadata: { source: './data/data.json', line: 1 }
  },
  Document {
    pageContent: '唱歌',
    metadata: { source: './data/data.json', line: 2 }
  }
]
*/

3. JSONL 文件加载(推荐用于JSON数组)

JSONL(每行一个JSON对象)是处理JSON数组的最佳方式,JSONLinesLoader 会逐行解析合法的 JSON 对象,完美实现"一项一个Document"。

示例文件(./data/data.jsonl)

jsonl 复制代码
{"name":"李白","age":18}
{"name":"杜甫","age":20}

加载代码

typescript 复制代码
import { JSONLinesLoader } from "@langchain/classic/document_loaders/fs/json";
​
// 初始化JSONL加载器
const loader = new JSONLinesLoader("./data/data.jsonl", "");
const documents = await loader.load();
​
console.log(documents);
/** 输出示例(每行一个Document):
[
  Document {
    pageContent: '{"name":"李白","age":18}',
    metadata: { line: 1, source: "./data/data.jsonl" }
  },
  Document {
    pageContent: '{"name":"杜甫","age":20}',
    metadata: { line: 2, source: "./data/data.jsonl" }
  }
]
*/

4. DOCX 文件加载

适用于Word文档,会提取文档中的纯文本内容(自动剔除格式标记),默认将整个文档作为一个 Document 返回,长文档可配合文本分割器处理。

加载代码

typescript 复制代码
import { DocxLoader } from "@langchain/community/document_loaders/fs/docx";
​
// 初始化DOCX加载器
const loader = new DocxLoader("./data/data.docx");
const documents = await loader.load();
​
console.log(documents);
/** 输出示例:
[
  Document {
    pageContent: "文档中的纯文本内容,自动去除Word格式标记...",
    metadata: { source: "./data/data.docx" }
  }
]
*/

5. TXT 文件加载与文本分割

纯文本文件加载后,若内容过长(超过大模型上下文窗口),需配合 RecursiveCharacterTextSplitter 分割为小文本块,保证后续处理效率。

示例文件(./data/data.txt)

txt 复制代码
李娟,1979年7月出生于新疆生产建设兵团,籍贯四川乐至,当代女作家,2022年当选新疆作协副主席。作品有散文集《阿勒泰的角落》《我的阿勒泰》《走夜路请放声歌唱》等。

加载与分割代码

typescript 复制代码
import { TextLoader } from "@langchain/classic/document_loaders/fs/text";
import { RecursiveCharacterTextSplitter } from "@langchain/classic/text_splitter";
​
// 1. 加载TXT文件
const loader = new TextLoader("./data/data.txt");
const documents = await loader.load();
​
// 2. 初始化文本分割器
const splitter = new RecursiveCharacterTextSplitter({
  chunkSize: 25, // 每个文本块的最大字符数
  chunkOverlap: 5, // 块之间的重叠字符数(保证上下文连贯)
  separators: [",", "。"], // 中文优先分割符(按语义分割)
});
​
// 3. 分割文档为小文本块
const splitDocuments = await splitter.splitDocuments(documents);
​
console.log(splitDocuments);
/** 输出示例(分割为多个小Document):
[
  Document {
    pageContent: "李娟,1979年7月出生于新疆生产建设兵团",
    metadata: { source: "./data/data.txt" }
  },
  Document {
    pageContent: "兵团,籍贯四川乐至,当代女作家",
    metadata: { source: "./data/data.txt" },
  },
  Document {
    pageContent: "女作家,2022年当选新疆作协副主席。",
    metadata: { source: "./data/data.txt" }
  },
  Document {
    pageContent: "作品有散文集《阿勒泰的角落》《我的阿勒泰》《走夜路请放声歌唱》等。",
    metadata: { source: "./data/data.txt" }
  }
]
*/

三、文本分割的核心意义

  1. 适配大模型上下文窗口:大模型有最大输入长度限制(如4096 tokens),长文本直接传入会被截断,分割后可分批处理;
  2. 提升检索精度:知识库向量检索时,小文本块的语义更聚焦,与查询语句的匹配度更高;
  3. 降低计算成本:小文本块的向量化、检索速度更快,内存占用更低。

四、核心原理与规范

1. 加载器统一规范

所有加载器均实现 BaseDocumentLoader 抽象类,必须提供以下核心方法,保证调用方式统一:

  • load():异步加载文件并返回 Promise<Document[]>
  • loadAndSplit():加载文件后直接调用分割器(可选)。
typescript 复制代码
// 所有加载器的通用调用范式
const loader = new XXXLoader("文件绝对路径");
const documents = await loader.load(); // 基础加载
// 或 加载并直接分割
const splitDocs = await loader.loadAndSplit(splitter);

2. 加载器选型建议(精准版)

文档格式 推荐加载器 核心适用场景 关键注意事项
CSV CSVLoader 表格数据、结构化列表 每行生成一个Document
JSON(单对象) JSONLoader 抽取指定字段值(JSONPath) 空路径会触发文本扫描,结果混乱
JSON(数组) JSONLinesLoader JSON数组、需按对象拆分 需将文件转为JSONL格式(每行一个对象)
DOCX DocxLoader Word文档、富文本格式 仅提取纯文本,剔除格式标记
TXT TextLoader 纯文本、长文本需分割 配合中文分割符提升语义完整性

总结

  1. 所有加载器均实现 BaseDocumentLoader 抽象类,核心调用方式为 loader.load(),返回标准化 Document 数组;
  2. JSONLoader 仅适用于单JSON对象的字段提取,JSON数组优先使用 JSONLinesLoader + JSONL格式;
  3. 处理中文长文本时,需为 RecursiveCharacterTextSplitter 指定中文分割符,避免语义断裂;
  4. 文本分割的核心价值是适配大模型上下文、提升检索精度,需根据实际场景调整 chunkSizechunkOverlap 参数。
相关推荐
蓝冰凌17 小时前
Vue 3 中 defineExpose 的行为【defineExpose暴露ref变量】详解:自动解包、响应性与实际使用
前端·javascript·vue.js
奔跑的呱呱牛17 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js
柳杉18 小时前
从动漫水面到赛博飞船:这位开发者的Three.js作品太惊艳了
前端·javascript·数据可视化
Greg_Zhong18 小时前
前端基础知识实践总结,每日更新一点...
前端·前端基础·每日学习归类
We་ct18 小时前
LeetCode 148. 排序链表:归并排序详解
前端·数据结构·算法·leetcode·链表·typescript·排序算法
IT_陈寒19 小时前
JavaScript开发者必看:5个让你的代码性能翻倍的隐藏技巧
前端·人工智能·后端
还是大剑师兰特19 小时前
Vue3 中 computed(计算属性)完整使用指南
前端·javascript·vue.js
井川不擦19 小时前
前端安全通信方案:RSA + AES 混合加密
前端
孜孜不倦不忘初心19 小时前
Ant Design Vue 表格组件空数据统一处理 踩坑
前端·vue.js·ant design