核心说明
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 文件加载
适用于表格类数据,每行数据会被解析为一个 Document,pageContent 为行内容,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" }
}
]
*/
三、文本分割的核心意义
- 适配大模型上下文窗口:大模型有最大输入长度限制(如4096 tokens),长文本直接传入会被截断,分割后可分批处理;
- 提升检索精度:知识库向量检索时,小文本块的语义更聚焦,与查询语句的匹配度更高;
- 降低计算成本:小文本块的向量化、检索速度更快,内存占用更低。
四、核心原理与规范
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 | 纯文本、长文本需分割 | 配合中文分割符提升语义完整性 |
总结
- 所有加载器均实现
BaseDocumentLoader抽象类,核心调用方式为loader.load(),返回标准化Document数组; JSONLoader仅适用于单JSON对象的字段提取,JSON数组优先使用JSONLinesLoader+ JSONL格式;- 处理中文长文本时,需为
RecursiveCharacterTextSplitter指定中文分割符,避免语义断裂; - 文本分割的核心价值是适配大模型上下文、提升检索精度,需根据实际场景调整
chunkSize和chunkOverlap参数。