0基础实战langchain系列讲义【2】LangChain 的数据连接

发布时间:2024年01月22日

前言

上一期里学会LangChian 里的 hello world,算是跑通了个pipeline。所以讲道理,我们这期该回到人工智能最重要的血肉基础这一扒,数据部分

1、数据连接定义?

LLM应用往往需要用户特定的数据微调,但这些数据并不属于模型的训练集,例如:私有数据或行业数据等。

LangChain 的数据连接就是解决这些数据与LLM之间连接的,如果没有这些数据连接,只能通过LLM训练学习,这成本非常高,于是langchain的五大组件,就实现这种用户数据的加载、转换、存储和查询:

1 文档加载器:

可以从不同的数据源加载文档,例如pdf、json、Excel等,这在企业落地的时候,提供很大的便利。当然,这也可以线上或本地的!等下会详细讲;

2 文档转换器:

拆分文档,将文档转换为问答格式,去除冗余文档等

3文本嵌入模型:

将非结构化文本转换为浮点数数组表现形式,也称为向量的过程

4 向量存储:

存储和搜索嵌入数据(向量)

5 检索器:

提供数据查询的通用接口

2、数据的加载、拆分过程

LLM应用连接用户数据时,一般会有以下步骤:

加载文档(对应Load)
拆分文档
向量化文档分块
向量数据存储

这样4步,实现通过向量数据的检索器,来查询用户数据。

2.1 TextLoader 加载文档

TextLoader ,是一种最基本的加载器,用来加载本地文件系统中的文档。

from langchain.document_loaders import TextLoader

loader = TextLoader("./README.md")
docs = loader.load()

我们可以通过Document对象的page_content属性来访问文档的原始内容。

2.2 拆分文档

顾名思义,拆分文档的目的就是将文档拆分为更小的文档块。

Langchain 提供了多种文档0拆分器,用于将文档拆分为更小的文档块。每一种拆分器,对应着不同的拆分方法,我们简单罗列以下几种方法

2.2.1 字符拆分

CharacterTextSplitter 是最简单的文档拆分器,它将文档拆分为固定长度的文本块。代码如下:

from langchain.text_splitter import CharacterTextSplittertext_splitter = CharacterTextSplitter(        
    separator = "\n\n",
    chunk_size = 1000,
    chunk_overlap  = 200,
    length_function = len,
)

split_docs = text_splitter.split_documents(docs)
2.2.2 拆分代码

RecursiveCharacterTextSplitter 的 from_language 函数,可以根据编程语言的特性,将代码拆分为合适的文本块。代码如下:

PYTHON_CODE = """
def hello_langchain():
    print("Hello, Langchain!")

#Call the function

hello_langchain()
"""
python_splitter = RecursiveCharacterTextSplitter.from_language(
    language=Language.PYTHON, chunk_size=50, chunk_overlap=0
)
python_docs = python_splitter.create_documents([PYTHON_CODE])
python_docs
2.2.3 Markdown文档拆分

MarkdownHeaderTextSplitter 可以将Markdown文档按照段落结构,基于Markdown语法进行文档分块。代码如下:

from langchain.text_splitter import MarkdownHeaderTextSplitter

markdown_document = "# Chapter 1\n\n    ## Section 1\n\nHi this is the 1st section\n\nWelcome\n\n ### Module 1 \n\n Hi this is the first module \n\n ## Section 2\n\n Hi this is the 2nd section"

headers_to_split_on = [
    ("#", "Header 1"),
    ("##", "Header 2"),
    ("###", "Header 3"),
]

splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
splits = splitter.split_text(markdown_document)
2.2.4 按字符递归拆分

这也是对于普通文本的推荐拆分方式。它通过一组字符作为参数,按顺序尝试使用这些字符进行拆分,直到块的大小足够小为止。默认的字符列表是[“\n\n”, “\n”, " ", “”]。它尽可能地保持段落,句子,单词的完整,因此尽可能地保证语义完整。

from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
    # Set a really small chunk size, just to show.
    chunk_size = 100,
    chunk_overlap  = 20,
    length_function = len,
)
texts = text_splitter.split_documents(docs)
2.2.5 按token拆分

语言模型,例如OpenAI,有token限制。在API调用中,不应超过token限制。看来,在将文本分块时,根据token数来拆分也是不错的主意。有许多令牌化工具,因此当计算文本的token数时,应该使用与语言模型相同的令牌化工具。

注,OpenAI所使用的是tiktoken。

from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
    chunk_size=100, chunk_overlap=0
)
split_docs = text_splitter.split_documents(docs)

3 文本向量化和向量数据库存储查询

3.1 文本向量化分块

好比图像识别或者推荐算法一样,同样文本里也是需要把多维的数据量化,

那接下来我们需要把这些数据在Langchain里面进行向量化,为了做向量化langchain和LLM模型里面都有一个接口,这就是Embeddings类接口。

当前市场上有许多嵌入模型提供者(如OpenAI、Cohere、Hugging Face等等)。

嵌入模型创建文本片段的向量表示。这意味着我们可以在向量空间中处理文本,并进行语义搜索等操作,从而查找在向量空间中最相似的文本片段,而不是整个文档了,提升我们的效率和结果准确度!

当使用OpenAI的文本嵌入模型时,我们使用如下代码来创建文本片段的向量表示:

向量化前!

from langchain.embeddings import OpenAIEmbeddings
embeddings_model = OpenAIEmbeddings(openai_api_key="你的有效openai api key")
embeddings = embeddings_model.embed_documents(
    [
        "hello!",
        "Langchain!",
        "world!"
    ]
)

embeddings
向量化后!

[[0.001767348474591444,
  -0.016549955833298362,
  0.009669921232251705,
  -0.024465152668289573,
  -0.04928377577655549,
  ...],
  [...
  -0.026084684286027195,
  -0.0023797790465254626,
  0.006104789779720747,
  ...]]

3.2 向量化存储、检索

向量数据存储,或成为向量数据库,负责存储文本嵌入的向量表现,并提供向量检索的能力。Langchain 提供了多种开源或商业向量数据存储,包括:Chroma, FAISS, Pinecone等等,我们可以理解为网盘,把数据存到上面去!

本讲以Chroma为例。

存储

在进行以下代码执行前,需要安装Chroma的包:

pip install -q chromadb


from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma

text_splitter=CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
documents = text_splitter.split_documents(docs)
db = Chroma.from_documents(documents, OpenAIEmbeddings())
检索

向量数据库提供的重要接口就是相似性查询。如上述内容提到,文本相似性的衡量,由文本的向量表示的欧几里得或者其他距离来衡量。

向量数据库提供了该接口,用于查询与给定文本最相似的文本。

query = “什么是Langchain?”
docs = db.similarity_search(query)
print(docs[0].page_content)

本地加载代码:

安装langchain

pip install -q langchain==0.0.235 openai

注意:

原项目地址:https://github.com/langchain-ai/langchain

讲义统一使用V0.0.235版本

从数据的接入、数据的分割,到向量的构建、向量的存储、向量的搜索,每一步可供选择的有很多,具体还是要结合实际的业务,当然这也是我们后续学习中需要掌握的!

这里有很多不懂的,可以在群里切磋!

文章来源:https://blog.csdn.net/water20210101/article/details/135735171
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。