![](/contact/xiaochengxu.jpg)
![](/contact/xiaohongshu.jpg)
构建 LLM 应用为什么需要文本加载器,langchain 中如何使用文本加载器?
使用文档加载器将源中的数据加载为Document,Document
是一段文本和关联的元数据。例如,有用于加载简单 .txt
文件、加载任何网页的文本内容,甚至用于加载 YouTube 视频的转录的文档加载器。
文档加载器提供了加载方法,用于从配置的源中将数据作为文档加载器。他们还可以选择实现“延迟加载”, 以延迟将数据加载到内存中。
加载txt文档
from langchain_community.document_loaders import TextLoader
loader = TextLoader("./index.md")
loader.load()
response:
[
Document(page_content='---\nsidebar_position: 0\n---\n# Document loaders\n\nUse document loaders to load data from a source as `Document`\'s. A `Document` is a piece of text\nand associated metadata. For example, there are document loaders for loading a simple `.txt` file, for loading the text\ncontents of any web page, or even for loading a transcript of a YouTube video.\n\nEvery document loader exposes two methods:\n1. "Load": load documents from the configured source\n2. "Load and split": load documents from the configured source and split them using the passed in text splitter\n\nThey optionally implement:\n\n3. "Lazy load": load documents into memory lazily\n', metadata={'source': '../docs/docs/modules/data_connection/document_loaders/index.md'})
]
CSV
逗号分隔值 (CSV) 文件是使用逗号分隔值的分隔文本文件。文件的每一行都是一条数据记录。每条记录由一个或多个字段组成,用逗号分隔。
加载每个文档一行的 CSV 数据
from langchain_community.document_loaders.csv_loader import CSVLoader
loader = CSVLoader(file_path='./example_data/mlb_teams_2012.csv')
data = loader.load()
Response:
print(data)
[Document(page_content='Team: Nationals\n"Payroll (millions)": 81.34\n"Wins": 98', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 0}, lookup_index=0), Document(page_content='Team: Reds\n"Payroll (millions)": 82.20\n"Wins": 97', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 1}, lookup_index=0), Document(page_content='Team: Yankees\n"Payroll (millions)": 197.96\n"Wins": 95', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 2}, lookup_index=0), Document(page_content='Team: Giants\n"Payroll (millions)": 117.62\n"Wins": 94', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 3}, lookup_index=0), Document(page_content='Team: Braves\n"Payroll (millions)": 83.31\n"Wins": 94', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 4}, lookup_index=0), Document(page_content='Team: Athletics\n"Payroll (millions)": 55.37\n"Wins": 94', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 5}, lookup_index=0), Document(page_content='Team: Rangers\n"Payroll (millions)": 120.51\n"Wins": 93', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 6}, lookup_index=0), Document(page_content='Team: Orioles\n"Payroll (millions)": 81.43\n"Wins": 93', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 7}, lookup_index=0), Document(page_content='Team: Rays\n"Payroll (millions)": 64.17\n"Wins": 90', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 8}, lookup_index=0), Document(page_content='Team: Angels\n"Payroll (millions)": 154.49\n"Wins": 89', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 9}, lookup_index=0), Document(page_content='Team: Tigers\n"Payroll (millions)": 132.30\n"Wins": 88', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 10}, lookup_index=0), Document(page_content='Team: Cardinals\n"Payroll (millions)": 110.30\n"Wins": 88', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 11}, lookup_index=0), Document(page_content='Team: Dodgers\n"Payroll (millions)": 95.14\n"Wins": 86', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 12}, lookup_index=0), Document(page_content='Team: White Sox\n"Payroll (millions)": 96.92\n"Wins": 85', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 13}, lookup_index=0), Document(page_content='Team: Brewers\n"Payroll (millions)": 97.65\n"Wins": 83', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 14}, lookup_index=0), Document(page_content='Team: Phillies\n"Payroll (millions)": 174.54\n"Wins": 81', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 15}, lookup_index=0), Document(page_content='Team: Diamondbacks\n"Payroll (millions)": 74.28\n"Wins": 81', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 16}, lookup_index=0), Document(page_content='Team: Pirates\n"Payroll (millions)": 63.43\n"Wins": 79', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 17}, lookup_index=0), Document(page_content='Team: Padres\n"Payroll (millions)": 55.24\n"Wins": 76', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 18}, lookup_index=0), Document(page_content='Team: Mariners\n"Payroll (millions)": 81.97\n"Wins": 75', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 19}, lookup_index=0), Document(page_content='Team: Mets\n"Payroll (millions)": 93.35\n"Wins": 74', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 20}, lookup_index=0), Document(page_content='Team: Blue Jays\n"Payroll (millions)": 75.48\n"Wins": 73', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 21}, lookup_index=0), Document(page_content='Team: Royals\n"Payroll (millions)": 60.91\n"Wins": 72', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 22}, lookup_index=0), Document(page_content='Team: Marlins\n"Payroll (millions)": 118.07\n"Wins": 69', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 23}, lookup_index=0), Document(page_content='Team: Red Sox\n"Payroll (millions)": 173.18\n"Wins": 69', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 24}, lookup_index=0), Document(page_content='Team: Indians\n"Payroll (millions)": 78.43\n"Wins": 68', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 25}, lookup_index=0), Document(page_content='Team: Twins\n"Payroll (millions)": 94.08\n"Wins": 66', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 26}, lookup_index=0), Document(page_content='Team: Rockies\n"Payroll (millions)": 78.06\n"Wins": 64', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 27}, lookup_index=0), Document(page_content='Team: Cubs\n"Payroll (millions)": 88.19\n"Wins": 61', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 28}, lookup_index=0), Document(page_content='Team: Astros\n"Payroll (millions)": 60.65\n"Wins": 55', lookup_str='', metadata={'source': './example_data/mlb_teams_2012.csv', 'row': 29}, lookup_index=0)]
自定义 CSV 解析和加载
有关支持哪些 csv 参数的更多信息,请参阅 csv 模块文档
loader = CSVLoader(file_path='./example_data/mlb_teams_2012.csv', csv_args={
'delimiter': ',',
'quotechar': '"',
'fieldnames': ['MLB Team', 'Payroll in millions', 'Wins']
})
data = loader.load()
指定用于标识文档源的列
使用该 source_column
参数指定从每一行创建的文档的源。否则 file_path
,将用作从 CSV 文件创建的所有文档的源。
当使用从 CSV 文件加载的文档时,这很有用,因为链使用源来回答问题。
loader = CSVLoader(file_path='./example_data/mlb_teams_2012.csv', source_column="Team")
data = loader.load()
文件目录加载器
DirectoryLoader
加载目录中的所有文档
from langchain_community.document_loaders import DirectoryLoader
loader = DirectoryLoader('../', glob="**/*.md")
docs = loader.load()
我们可以使用该 glob
参数来控制要加载的文件。请注意,这里它不会加载 .rst
文件或 .html
文件。
显示加载进度条
默认情况下,不会显示文档加载的进度,如果要显示文档加载的进度条,需要安装tqdm
,pip install tqdm
,并将 show_progress
参数设置为 True
。
loader = DirectoryLoader('../', glob='**/*.md', show_progress=True)
docs = loader.load()
Requirement already satisfied: tqdm in /Users/jon/.pyenv/versions/3.9.16/envs/microbiome-app/lib/python3.9/site-packages (4.65.0)
0it [00:00, ?it/s]
使用多线程加载文档
默认情况下,加载文档是单线程的,我们可以使用多线程加载文档提升文档的加载速度,为了利用多线程,我们可以设置use_multithreading=True
来使用多线程加载器。
loader = DirectoryLoader('../', glob="**/*.md", use_multithreading=True)
docs = loader.load()
更改加载程序类
默认情况下会加载器使用UnstructuredLoader
类,但是我们也可以很轻松的修改文档加载器的类型.
from langchain_community.document_loaders import TextLoader
loader = DirectoryLoader('../', glob='**/*.md', loader_cls=TextLoader)
docs = loader.load()
如果需要加载Python
代码,我们使用PythonLoader
from langchain_community.document_loaders import PythonLoader
loader = DirectoryLoader('../../../../../', glob="**/*.py", loader_cls=PythonLoader)
docs = loader.load()
文件编码
如果我们加载的目录中文档有多种不同的编码方式,我们在执行load()
函数的时候回失败,并显示一条有用的消息,指示哪个文件 example-non-utf8.txt
解码失败。
在默认情况下 TextLoader
,任何未能加载任何文档都将使整个加载过程失败,并且不会加载任何文档。如果要解决部分失败的情况,我们可以使用一下方法:
1、可以将参数silent_errors
传递 DirectoryLoader
,跳过无法加载的文档,并继续执行加载过程。
loader = DirectoryLoader(path, glob="**/*.txt", loader_cls=TextLoader, silent_errors=True)
docs = loader.load()
2、我们可以配置文档加载器自动检测编码
我们还可以通过将autodetect_encoding
传递给加载器类来要求 TextLoader
在失败之前自动检测文件编码。
text_loader_kwargs={'autodetect_encoding': True}
loader = DirectoryLoader(path, glob="**/*.txt", loader_cls=TextLoader, loader_kwargs=text_loader_kwargs)
docs = loader.load()
HTML loader
我们可以按以下方式去加载一个HTML
网页文档
from langchain_community.document_loaders import UnstructuredHTMLLoader
loader = UnstructuredHTMLLoader("example_data/fake-content.html")
data = loader.load()
使用 BeautifulSoup4 加载 HTML
我们还可以使用 BeautifulSoup4
BSHTMLLoader
.这会将 HTML 中的文本提取到 page_content
中,并将页面标题提取为 title
metadata
from langchain_community.document_loaders import BSHTMLLoader
loader = BSHTMLLoader("example_data/fake-content.html")
data = loader.load()
JSON格式
文档连接:https://python.langchain.com/docs/modules/data_connection/document_loaders/json
JSON(JavaScript 对象表示法)是一种开放的标准文件格式和数据交换格式,它使用人类可读的文本来存储和传输由属性值对和数组(或其他可序列化值)组成的数据对象。JSON 行是一种文件格式,其中每行都是一个有效的 JSON 值。
JSONLoader
使用指定的 jq 模式来解析 JSON 文件。它使用 jq
python 包。
#!pip install jq
from langchain_community.document_loaders import JSONLoader
import json
from pathlib import Path
from pprint import pprint
file_path='./example_data/facebook_chat.json'
data = json.loads(Path(file_path).read_text())
如果我们需要提取 json
数据中某个字段的数据,可以通过下面的示例轻松提取,JSONLoader
loader = JSONLoader(
file_path='',
file_path='./example_data/facebook_chat.json',
jq_schema='.messages[].content',
text_content=False,
)
data = loader.load()
JSON 行文件
如果要从 JSON 行文件加载文档,请传递 json_lines=True
并指定 jq_schema
page_content
从单个 JSON 对象中提取。
file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())
loader = JSONLoader(
file_path='./example_data/facebook_chat_messages.jsonl',
jq_schema='.content',
text_content=False,
json_lines=True)
data = loader.load()
设置 jq_schema='.'
另一个选项并提供 content_key
:
loader = JSONLoader(
file_path='./example_data/facebook_chat_messages.jsonl',
jq_schema='.',
content_key='sender_name',
json_lines=True)
data = loader.load()
JSON 中提取元数据
通常,我们希望将JSON
文件中可用的元数据包含在我们从内容创建的文档中,
加载Markdown
Markdown 是一种轻量级标记语言,用于使用纯文本编辑器创建格式化文本。
# !pip install unstructured > /dev/null
from langchain_community.document_loaders import UnstructuredMarkdownLoader
markdown_path = "../../../../../README.md"
loader = UnstructuredMarkdownLoader(markdown_path)
data = loader.load()
Unstructured 为不同的文本块创建不同的“元素”。默认情况下,我们将这些组合在一起,但可以通过指定 mode="elements"
来轻松保持这种分离。
loader = UnstructuredMarkdownLoader(markdown_path, mode="elements")
data = loader.load()
加载PDF
文档:https://python.langchain.com/docs/modules/data_connection/document_loaders/pdf
使用 PyPDF
使用 pypdf
将 PDF 加载到文档数组中,其中每个文档都包含页面内容和带有 page
编号的元数据。
pip install pypdf
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("example_data/layout-parser-paper.pdf")
pages = loader.load_and_split()
这种方法的一个优点是可以使用页码检索文档。
我们想要使用 OpenAIEmbeddings
,所以我们必须获得 OpenAI API 密钥。
import os
import getpass
os.environ['OPENAI_API_KEY'] = getpass.getpass('OpenAI API Key:')
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
faiss_index = FAISS.from_documents(pages, OpenAIEmbeddings())
docs = faiss_index.similarity_search("How will the community be engaged?", k=2)
for doc in docs:
print(str(doc.metadata["page"]) + ":", doc.page_content[:300])
提取PDF中的图像
使用该 rapidocr-onnxruntime
包,我们也可以将图像提取为文本:
pip install rapidocr-onnxruntime
loader = PyPDFLoader("https://arxiv.org/pdf/2103.15348.pdf", extract_images=True)
pages = loader.load()
pages[4].page_content
使用MathPix
from langchain_community.document_loaders import MathpixPDFLoader
loader = MathpixPDFLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
使用非结构化
from langchain_community.document_loaders import UnstructuredPDFLoader
loader = UnstructuredPDFLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
保留元素
UnstructuredPDFLoader
为不同的文本块创建不同的“元素“,默认情况下,我们将这些组合在一起,但您可以通过指定 mode="elements"
来轻松保持这种分离。
loader = UnstructuredPDFLoader("example_data/layout-parser-paper.pdf", mode="elements")
data = loader.load()
使用非结构化方式获取远程 PDF
很多时候我们需要读取远程网络的pdf文件并解析以加载到我们下游使用的文档格式,所有其他 PDF 加载器也可用于获取远程 PDF,但这是 OnlinePDFLoader
旧功能,专门用于 UnstructuredPDFLoader
. // todo
from langchain_community.document_loaders import OnlinePDFLoader
loader = OnlinePDFLoader("https://arxiv.org/pdf/2302.03803.pdf")
data = loader.load()
使用 PyPDFium2
from langchain_community.document_loaders import PyPDFium2Loader
loader = PyPDFium2Loader("example_data/layout-parser-paper.pdf")
data = loader.load()
使用 PDFMiner
from langchain_community.document_loaders import PDFMinerLoader
loader = PDFMinerLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
使用 PDFMiner 生成 HTML 文本
使用 PDFMiner 生成 HTML 文本有助于在语义上将文本分块。可以通过解析输出html
内容BeautifulSoup
来获取有关字体大小、页码、PDF 页眉/页脚等的更结构化和丰富的信息。
from langchain_community.document_loaders import PDFMinerPDFasHTMLLoader
loader = PDFMinerPDFasHTMLLoader("example_data/layout-parser-paper.pdf")
data = loader.load()[0] # entire PDF is loaded as a single Document
from bs4 import BeautifulSoup
soup = BeautifulSoup(data.page_content,'html.parser')
content = soup.find_all('div')
Note: PDF解析详细可以参考文档部分:
类似的帖子
![](/contact/xiaochengxu.jpg)
![](/contact/xiaohongshu.jpg)