LangChain核心模块 Retrieval——文档加载器

Retrieval

​ 许多LLM申请需要用户的特定数据,这些数据不属于模型训练集的一部分,实现这一目标的主要方法是RAG(检索增强生成),在这个过程中,将检索外部数据,然后在执行生成步骤时将其传递给LLM。

​ LangChain 提供了 RAG 应用程序的所有构建模块 - 从简单到复杂。文档的这一部分涵盖了与检索步骤相关的所有内容 - 例如数据的获取。这包含了几个关键模块:

在这里插入图片描述

Documents loaders

  • 文档加载器

文档加载器提供了一种“load”方法,用于从配置的源将数据加载为文档。还可以选择实现”lazy load“,以便将数据延迟加载到内存中。

最简单的加载程序将文件作为文本读入,并将其全部放入一个文档中。

from langchain_community.document_loaders import TextLoader

loader = TextLoader("./index.md")
loader.load()
  1. CSV

    • comma-separated values(CSV)文件是使用逗号分隔值的分隔文本文件,文件的每一行都是一条数据记录,每条记录由一个或多个字段组成,以逗号分隔。

    • 加载每个文档一行的 CSV 数据

      from langchain_community.document_loaders.csv_loader import CSVLoader
      
      
      loader = 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()
      
  2. 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 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()
      
    • 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
        
  3. HTML

    from langchain_community.document_loaders import UnstructuredHTMLLoader
    
    loader = UnstructuredHTMLLoader("example_data/fake-content.html")
    data = loader.load()
    
    • 使用 BeautifulSoup4 加载 HTML

      将HTML中的文本提取到page_content中,并将页面标题作为title提取到metadata

      from langchain_community.document_loaders import BSHTMLLoader
      
      loader = BSHTMLLoader("example_data/fake-content.html")
      data = loader.load()
      
  4. JSON

    JSON(JavaScript Object Notation)是一种开放标准文件格式和数据交换格式,它使用人类可读的文本来存储和传输由属性值对和数组组成的数据对象。

    JSON Lines是一种文件格式,其中每一行都是有效的JSON值。

    JSONLoader 使用指定的 jq 架构来解析 JSON 文件。

    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())
    
    • 使用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 metadata
      
      
      loader = 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 生成的默认元数据,这允许用户完全控制元数据的格式。

      例如,默认元数据包含sourceseq_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 metadata
      
      
      loader = 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   -> ".[]"
      
  5. Markdown

    from langchain_community.document_loaders import UnstructuredMarkdownLoader
    
    markdown_path = "../../../../../README.md"
    loader = UnstructuredMarkdownLoader(markdown_path)
    data = loader.load()
    
    • Retain Elements

      在底层,非结构化为不同的文本块创建不同的“元素”。默认情况下,我们将它们组合在一起,但可以通过指定 mode=“elements” 轻松保持这种分离。

      loader = UnstructuredMarkdownLoader(markdown_path, mode="elements")
      data = loader.load()
      
  6. PDF

    • PyPDF

      使用 pypdf 将 PDF 加载到文档数组中,其中每个文档包含页面内容和带有页码的元数据。

      pip install pypdf
      
      from langchain_community.document_loaders import PyPDFLoader
      
      loader = PyPDFLoader("example_data/layout-parser-paper.pdf")
      pages = loader.load_and_split()
      

      这种方法的优点是可以使用页码检索文档。

      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])
      
      • 提取图像(Extracting images)

        使用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")
      
    • 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 PyPDFDirectoryLoader
      
      loader = 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 大小的单页和多页文档。

  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值