4

使用langchain的Document loaders加载外部数据

 1 year ago
source link: http://www.flydean.com/009-langchain-retrieval-document-loaders/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

LangChain为开发人员提供了多种文档加载器,LangChain中的文档加载器都在langchain.document_loaders中,langchain把所有要加载的文档都看做是一个Document。

你可以通过langchain来加载txt文件,pdf文件,csv文件或者html文件等等。

Document

Document是langchain对要加载文档的抽象。我们看下他的定义:

class Document(Serializable):
    """Class for storing a piece of text and associated metadata."""

    page_content: str
    """String text."""
    metadata: dict = Field(default_factory=dict)
    """Arbitrary metadata about the page content (e.g., source, relationships to other
        documents, etc.).
    """

    @property
    def lc_serializable(self) -> bool:
        """Return whether or not the class is serializable."""
        return True

这段代码定义了一个 Document 类,该类用于表示文本文档及其元数据。文档的文本内容存储在 page_content 属性中,元数据信息存储在 metadata 属性中, metadata是一个字典,表示存放多种元数据。

此外,这个类还具有一个名为 lc_serializable 的属性,该属性返回 True,表示这个类是可序列化的。

可序列化通常指的是可以将类的实例转换为一种格式(例如JSON)以进行数据存储或传输。

BaseLoader

langchain中的基础loader类叫做BaseLoader,BaseLoader定义了三个方法:

def load(self) -> List[Document]:

def load_and_split(
        self, text_splitter: Optional[TextSplitter] = None
    ) -> List[Document]:

def lazy_load(
        self,
    ) -> Iterator[Document]:

分别是加载,加载然后分割和最后的懒加载。

BaseLoader只是一个抽象类,所有的方法都是在子类中实现的。langchain提供了多种loader供我们使用。

因为loader太多了,大家有需要的可以自行查阅langchain的文档。

这里我们挑几个有代表性的,使用比较多的loader给大家介绍。

TextLoader

TextLoader是最简单的loader了。 他就是把要加载的文档看做是一个text。

看一下他的具体实现:

    def load(self) -> List[Document]:
        """Load from file path."""
        text = ""
        try:
            with open(self.file_path, encoding=self.encoding) as f:
                text = f.read()
        except UnicodeDecodeError as e:
            if self.autodetect_encoding:
                detected_encodings = detect_file_encodings(self.file_path)
                for encoding in detected_encodings:
                    logger.debug(f"Trying encoding: {encoding.encoding}")
                    try:
                        with open(self.file_path, encoding=encoding.encoding) as f:
                            text = f.read()
                        break
                    except UnicodeDecodeError:
                        continue
            else:
                raise RuntimeError(f"Error loading {self.file_path}") from e
        except Exception as e:
            raise RuntimeError(f"Error loading {self.file_path}") from e

        metadata = {"source": self.file_path}
        return [Document(page_content=text, metadata=metadata)]

load方法很简单,首先使用默认的encoding来加载文档,如果出现UnicodeDecodeError,则尝试用其他的编码方式进行读取。

最后把读取到的文件内容,和生成的元数据传入到一个Document对象中返回。

下面是一个使用的例子,非常简单:

from langchain.document_loaders import TextLoader

loader = TextLoader("./index.html")
loader.load()

CSVLoader

CSV的全称是comma-separated values,csv文件是一种我们在日常工作中经常会用到的一种文件格式。

看一下csv文件的简单加载:

from langchain.document_loaders.csv_loader import CSVLoader


loader = CSVLoader(file_path='./index.csv')
data = loader.load()

当然csv文件可能并不是以默认的逗号作为分隔符的,所以我们可以使用一种更加复杂的加载方式如下:

loader = CSVLoader(file_path='./index.csv', csv_args={
    'delimiter': ',',
    'quotechar': '"',
    'fieldnames': ['姓名', '年龄', '班级']
})

data = loader.load()

默认情况下Document里面的元数据的source属性是csv文件的路径,你也可以通过传入source_column来改变这一行为:

loader = CSVLoader(file_path='./index.csv', source_column="班级")

data = loader.load()

HTML loader

HTML也是我们经常会用到的数据有,如果我们只想获取html中的具体内容的话,可以使用UnstructuredHTMLLoader:

from langchain.document_loaders import UnstructuredHTMLLoader

loader = UnstructuredHTMLLoader("index.html")

data = loader.load()

这个loader会把html中的具体内容转换成为document中的page_content。

langchain还提供了一个BSHTMLLoader的加载器。

这个加载器会额外获取html的title字段,将其放在Document的元数据中的title里面:

from langchain.document_loaders import BSHTMLLoader

loader = BSHTMLLoader("index.html")
data = loader.load()
data

JSONLoader

JSON也是一种非常常见的数据格式。在Langchain中,提供了JSONLoader为我们使用。

因为JSON相对而言比较复杂一点,所以这里langchain解析的时候实际上使用的是jq这个python包来实现的。

所以,如果你需要使用JSONLoader,必须安装jq先。

我们看下他的具体使用:

from langchain.document_loaders import JSONLoader

import json
from pathlib import Path
from pprint import pprint


file_path='./index.json'
data = json.loads(Path(file_path).read_text())

这里我们读取了一个json文件, 他的内容可能是这样的:

{'name': 'jack', 'age': 10, 'books': {'bookName': 'book A', 'author': 'author'}}

假如我们只想获取json中books相关的信息,那么可以这样使用JSONLoader:

loader = JSONLoader(
    file_path='./index.json',
    jq_schema='.books',
    text_content=False)

data = loader.load()

我们可以得到下面的内容:

[Document(page_content='{"bookName": "book A", "author": "author"}', metadata={'source': '/index.json', 'seq_num': 1})]

这里我们可能需要注意传入的jq_schema,不同的schema需要不同的格式,下面是几个jq_schema的例子:

JSON        -> [{"text": ...}, {"text": ...}, {"text": ...}]
jq_schema   -> ".[].text"

JSON        -> {"key": [{"text": ...}, {"text": ...}, {"text": ...}]}
jq_schema   -> ".key[].text"

JSON        -> ["...", "...", "..."]
jq_schema   -> ".[]"

UnstructuredMarkdownLoader

Markdown是一种非常常见的文档文件,这种文档文件可以方便的生成带样式的页面,深受广大程序员的喜爱。

langchain提供了UnstructuredMarkdownLoader来加载markdown文件:

from langchain.document_loaders import UnstructuredMarkdownLoader

markdown_path = "./index.md"
loader = UnstructuredMarkdownLoader(markdown_path)

data = loader.load()

默认情况下UnstructuredMarkdownLoader会把从markdown文件中解析出来的各个模块合并在一起,放入Document的page_content中。

但是有些情况下,我们希望保留各个模块,并不想对内容进行合并,这样的话,我们可以给UnstructuredMarkdownLoader传入一个mode参数,这样就会被对内容进行合并了:

loader = UnstructuredMarkdownLoader(markdown_path, mode="elements")

data = loader.load()

data[0]

PyPDFLoader

pdf是一种我们在日常工作中经常会使用到的一种文本结构。他的全称叫做Portable Document Format (PDF),是Adobe公司在1992开发的一种文件格式。

如果你的pdf在本地,那么可以使用langchain提供的PyPDFLoader来加载pdf文档。

from langchain.document_loaders import PyPDFLoader

loader = PyPDFLoader("files/mypdf.pdf")
pages = loader.load_and_split()

最后得到的pages是pdf中的页面,你可以通过pages的下标来获取不同页面的数据。

如果pdf中包含图片,你还可以通过安装rapidocr-onnxruntime包来讲图片转换成文字:

pip install rapidocr-onnxruntime

loader = PyPDFLoader("files/mypdf.pdf", extract_images=True)
pages = loader.load()
pages[4].page_content

这里面我们需要给PyPDFLoader传入多一个参数:extract_images。

当然,还有其他很多种类的pdfloader,比如MathpixPDFLoader,UnstructuredPDFLoader.

如果你想获取远程的pdf,可以使用OnlinePDFLoader.

有了这么多文档加载器之后,从外部文件读取数据就不再是一个梦想了。

</div


Recommend

  • 45

    README.md

  • 9
    • fredlyu.github.io 3 years ago
    • Cache

    Unity之动态加载播放外部mp3音频

    Unity之动态加载播放外部mp3音频 发表于 2020-05-16...

  • 7

    一日一技:在LangChain中使用Azure OpenAI Embedding服务 2023-05-13 70 847 3 分钟 如果大家深入使用过ChatGPT的API,或者用过听说过AutoGPT,那么可能会知道,它...

  • 13

    使用大语言模型集成工具 LangChain 创建自己的论文汇总和查询工具 作者:佚名 2023-05-19 15:58:52 开发 Langchain可以帮助开发人员构...

  • 8

    在之前的文章中,我们提到了可以在跟大模型交互的时候,给大模型提供一些具体的例子内容,方便大模型从这些内容中获取想要的答案。这种方便的机制在langchain中叫做FewShotPromptTemplate。 如果例子内容少的话,其实无所谓,我们可以把所有的例子都发送给大...

  • 16

    article 使用 wechaty langchain 部署私...

  • 15
    • www.flydean.com 2 years ago
    • Cache

    langchain中的LLM模型使用介绍

    构建在大语言模型基础上的应用通常有两种,第一种叫做text completion,也就是一问一答的模式,输入是text,输出也是text。这种模型下应用并不会记忆之前的问题内容,每一个问题都是最新的。通常用来做知识库。 还有一种是类似聊天机器人这种会话模式,也叫Cha...

  • 8

    之前我们介绍了LLM模式,这种模式是就是文本输入,然后文本输出。 chat models是基于LLM模式的更加高级的模式。他的输入和输出是格式化的chat messages。 一起来看看如何在langchain中使用caht models吧。 chat models...

  • 8

    之前我们介绍了LLM模式,这种模式是就是文本输入,然后文本输出。 chat models是基于LLM模式的更加高级的模式。他的输入和输出是格式化的chat messages。 一起来看看如何在langchain中使用caht models吧。 chat models...

  • 9
    • www.flydean.com 1 year ago
    • Cache

    如何在langchain中使用外部数据

    在大型语言模型(LLM)领域,越来越多的应用需要生成用户特定的数据,这些数据通常超出了模型的训练数据范围。 因为大模型在训练的过程中,因为受到训练数据的影响,可能并没没有用户所需要的数据,所以可能会导致大语言模型在某些特定数据上的行为缺失。...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK