Retrieval
许多LLM申请需要用户的特定数据,这些数据不属于模型训练集的一部分,实现这一目标的主要方法是RAG(检索增强生成),在这个过程中,将检索外部数据,然后在执行生成步骤时将其传递给LLM。
LangChain 提供了 RAG 应用程序的所有构建模块 - 从简单到复杂。文档的这一部分涵盖了与检索步骤相关的所有内容 - 例如数据的获取。这包含了几个关键模块:
Documents loaders
- 文档加载器
文档加载器提供了一种“load”方法,用于从配置的源将数据加载为文档。还可以选择实现”lazy load“,以便将数据延迟加载到内存中。
最简单的加载程序将文件作为文本读入,并将其全部放入一个文档中。
from langchain_community.document_loaders import TextLoaderloader = TextLoader("./index.md")
loader.load()
-
CSV
-
comma-separated values(CSV)文件是使用逗号分隔值的分隔文本文件,文件的每一行都是一条数据记录,每条记录由一个或多个字段组成,以逗号分隔。
-
加载每个文档一行的 CSV 数据
from langchain_community.document_loaders.csv_loader import CSVLoaderloader = CSVLoader(file_path='./example_data/mlb_teams_2012.csv') data = loader.load()
-
Customizing the CSV parsing and loading(自定义 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()
-
-
File Directory
- 如何加载目录中的所有文档
在底层,默认情况下使用UnstructedLoader
from langchain_community.document_loaders import DirectoryLoader
可以使用
glob
参数来控制加载哪些文件,这里它不会加载.rst
、.html
文件loader = DirectoryLoader('../', glob="**/*.md") docs = loader.load()
-
Show a progress bar(显示进度条)
要显示进度条,请安装
tqdm
库(例如pip install tqdm
),并将show_progress
参数设置为 True。loader = DirectoryLoader('../', glob="**/*.md", show_progress=True) docs = loader.load()
-
Use multithreading(使用多线程)
默认情况下,加载发生在一个线程。要使用多个线程,将
use_multithreading
标志设置为 true。loader = DirectoryLoader('../', glob="**/*.md", use_multithreading=True) docs = loader.load()
-
Change loader class(更改加载类)
默认情况下,这使用
UnstructedLoader
类。from langchain_community.document_loaders import TextLoaderloader = DirectoryLoader('../', glob="**/*.md", loader_cls=TextLoader) docs = loader.load()
如果需要加载Python源代码文件,使用
PythonLoader
。from langchain_community.document_loaders import PythonLoaderloader = DirectoryLoader('../../../../../', glob="**/*.py", loader_cls=PythonLoader) docs = loader.load()
-
Auto-detect file encodings with TextLoader(使用 TextLoader 自动检测文件编码)
-
Default Behavior
loader.load()
loading()
函数失败,会显示一条信息显示哪个文件解码失败在
TextLoader
的默认行为下,任何文档加载失败都会导致整个加载过程失败,并且不会再加载任何文档。 -
Silent fail
可以将参数silent_errors传递给
DirectoryLoader
来跳过无法加载的文件并继续加载过程。loader = DirectoryLoader(path, glob="**/*.txt", loader_cls=TextLoader, silent_errors=True) docs = loader.load()
doc_sources = [doc.metadata['source'] for doc in docs] doc_sources
-
Auto detect encodings
还可以通过将
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()
doc_sources = [doc.metadata['source'] for doc in docs] doc_sources
-
-
HTML
from langchain_community.document_loaders import UnstructuredHTMLLoaderloader = UnstructuredHTMLLoader("example_data/fake-content.html") data = loader.load()
-
使用 BeautifulSoup4 加载 HTML
将HTML中的文本提取到
page_content
中,并将页面标题作为title
提取到metadata
中from langchain_community.document_loaders import BSHTMLLoaderloader = BSHTMLLoader("example_data/fake-content.html") data = loader.load()
-
-
JSON
JSON(JavaScript Object Notation)是一种开放标准文件格式和数据交换格式,它使用人类可读的文本来存储和传输由属性值对和数组组成的数据对象。
JSON Lines是一种文件格式,其中每一行都是有效的JSON值。
JSONLoader
使用指定的jq
架构来解析 JSON 文件。pip install jq
from langchain_community.document_loaders import JSONLoaderimport json from pathlib import Path from pprint import pprintfile_path='./example_data/facebook_chat.json' data = json.loads(Path(file_path).read_text())
-
使用
JSONLoader
如果想要提取JSON数据的messages键中的内容字段下的值
-
JSON file
loader = JSONLoader(file_path='./example_data/facebook_chat.json',jq_schema='.messages[].content',text_content=False)data = loader.load()
-
JSON Lines file
如果要从 JSON Lines 文件加载文档,请传递
json_lines=True
并指定jq_schema
以从单个 JSON 对象中提取 page_content。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 file with jq schema
content_key
(带有jq
架构content_key
的 JSON 文件)要使用
jq
架构中的content_key
从 JSON 文件加载文档,要设置is_content_key_jq_parsable=True
,确保content_key
兼容并且可以使用jq
模式进行解析。loader = JSONLoader(file_path=file_path,jq_schema=".data[]",content_key=".attributes.message",is_content_key_jq_parsable=True, )data = loader.load()
-
-
提取元数据(Extracting metadata)
前面示例中,并没有收集元数据,我们设法直接在架构中指定可以从中提取
page_content
值的位置。.messages[].content
在当前示例中,我们必须告诉加载器迭代消息字段中的记录。
jq_schema
必须是:.messages[]
这允许我们将记录(dict)传递到必须实现的
metadata_func
中。metadata_func
负责识别记录中的哪些信息应包含在最终 Document 对象中存储的元数据中。此外,还要在加载器中通过
content_key
参数显式指定需要从中提取page_content
值的记录中的键。# Define the metadata extraction function. def metadata_func(record: dict, metadata: dict) -> dict:metadata["sender_name"] = record.get("sender_name")metadata["timestamp_ms"] = record.get("timestamp_ms")return metadataloader = JSONLoader(file_path='./example_data/facebook_chat.json',jq_schema='.messages[]',content_key="content",metadata_func=metadata_func )data = loader.load()
-
metadata_func
metadata_func
接受JSONLoader
生成的默认元数据,这允许用户完全控制元数据的格式。例如,默认元数据包含
source
和seq_num
键。但是,JSON 数据也可能包含这些键。然后,用户可以利用metadata_func
重命名默认键并使用JSON 数据中的键。下面的示例展示了如何修改源以仅包含相对于 langchain 目录的文件源信息:
# Define the metadata extraction function. def metadata_func(record: dict, metadata: dict) -> dict:metadata["sender_name"] = record.get("sender_name")metadata["timestamp_ms"] = record.get("timestamp_ms")if "source" in metadata:source = metadata["source"].split("/")source = source[source.index("langchain"):]metadata["source"] = "/".join(source)return metadataloader = JSONLoader(file_path='./example_data/facebook_chat.json',jq_schema='.messages[]',content_key="content",metadata_func=metadata_func )data = loader.load()
-
具有
jq
模式的常见 JSON 结构下面的列表提供了对可能的
jq_schema
的引用,用户可以使用它根据结构从 JSON 数据中提取内容。JSON -> [{"text": ...}, {"text": ...}, {"text": ...}] jq_schema -> ".[].text"JSON -> {"key": [{"text": ...}, {"text": ...}, {"text": ...}]} jq_schema -> ".key[].text"JSON -> ["...", "...", "..."] jq_schema -> ".[]"
-
-
Markdown
from langchain_community.document_loaders import UnstructuredMarkdownLoadermarkdown_path = "../../../../../README.md" loader = UnstructuredMarkdownLoader(markdown_path) data = loader.load()
-
Retain Elements
在底层,非结构化为不同的文本块创建不同的“元素”。默认情况下,我们将它们组合在一起,但可以通过指定 mode=“elements” 轻松保持这种分离。
loader = UnstructuredMarkdownLoader(markdown_path, mode="elements") data = loader.load()
-
-
PDF
-
PyPDF
使用 pypdf 将 PDF 加载到文档数组中,其中每个文档包含页面内容和带有页码的元数据。
pip install pypdffrom langchain_community.document_loaders import PyPDFLoaderloader = PyPDFLoader("example_data/layout-parser-paper.pdf") pages = loader.load_and_split()
这种方法的优点是可以使用页码检索文档。
from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddingsfaiss_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])
-
提取图像(Extracting images)
使用
rapidocr-onnxruntime
包可以将图像提取为文本:pip install rapidocr-onnxruntimeloader = 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")
-
Unstructured
from langchain_community.document_loaders import UnstructuredPDFLoader loader = UnstructuredPDFLoader("example_data/layout-parser-paper.pdf")
-
Retain Elements
loader = UnstructuredPDFLoader("example_data/layout-parser-paper.pdf", mode="elements")
-
使用非结构化获取远程 PDF
将在线 PDF 加载为我们可以在下游使用的文档格式
其他 PDF 加载器也可用于获取远程 PDF,但
OnlinePDFLoader
是一个遗留函数,专门与UnstructedPDFLoader
配合使用。from langchain_community.document_loaders import OnlinePDFLoader loader = OnlinePDFLoader("https://arxiv.org/pdf/2302.03803.pdf")
-
-
PyPDFium2
from langchain_community.document_loaders import PyPDFium2Loader loader = PyPDFium2Loader("example_data/layout-parser-paper.pdf")
-
PDFMiner
from langchain_community.document_loaders import PDFMinerLoader loader = PDFMinerLoader("example_data/layout-parser-paper.pdf")
-
使用 PDFMiner 生成 HTML 文本
这有助于将文本在语义上分块为多个部分,因为输出的 html 内容可以通过 BeautifulSoup 进行解析,以获得有关字体大小、页码、PDF 页眉/页脚等的更结构化和丰富的信息。
-
-
PyMuPDF
最快的 PDF 解析选项,包含有关 PDF 及其页面的详细元数据,并且每页返回一个文档。
from langchain_community.document_loaders import PyMuPDFLoader loader = PyMuPDFLoader("example_data/layout-parser-paper.pdf")
此外,您可以在加载调用中将 PyMuPDF 文档中的任何选项作为关键字参数传递,并将其传递给 get_text() 调用。
-
PyPDF Directory
从目录加载 PDF
from langchain_community.document_loaders import PyPDFDirectoryLoaderloader = PyPDFDirectoryLoader("example_data/")
-
PDFPlumber
与 PyMuPDF 一样,输出文档包含有关 PDF 及其页面的详细元数据,并每页返回一个文档。
from langchain_community.document_loaders import PDFPlumberLoader loader = PDFPlumberLoader("example_data/layout-parser-paper.pdf")
-
AmazonTextractPDFParser
AmazonTextractPDFLoader
调用Amazon Textract Service
将 PDF 转换为文档结构。该加载程序目前执行纯 OCR,并根据需求计划提供更多功能,例如布局支持。支持最多 3000 页和 512 MB 大小的单页和多页文档。
-