Langchain-数据连接


本文参考自该教程

数据连接组件

  • 文档加载器:从不同的数据源加载文档
  • 文档转换器:拆分文档,将文档转换为问答格式,去除冗余文档,等等
  • 文本嵌入模型:将非结构化文本转换为浮点数数组表现形式,也称为向量
  • 向量存储:存储和搜索嵌入数据(向量)
  • 检索器:提供数据查询的通用接口

数据连接

步骤

  1. 加载文档
  2. 拆分文档
  3. 向量化文档分块
  4. 向量数据存储

加载文档

Langchain 提供了多种文档加载器,用于从不同的数据源加载不同类型的文档。比如,我们可以从本地文件系统加载文档,也可以通过网络加载远程数据。
而目前我只学到了用最基本的 TextLoader 来加载本地文件系统中的文档.

from langchain.document_loaders import TextLoader

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

拆分文档

拆分文档是文档转换中最常见的操作。拆分文档的目的是将文档拆分为更小的文档块,以便更好地利用模型。
Langchain 提供了多种文档拆分器,用于将文档拆分为更小的文档块。

按字符拆分

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

from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(        
    separator = "\n\n",
    chunk_size = 1000,			# 拆分文本块的字符上限
    chunk_overlap  = 200,		# 文本块拆分时留下的缓冲字符,用于帮助AI理解语义。
    length_function = len,		# 长度计算方式,这里用的是字符串长度计算方式
)

split_docs = text_splitter.split_documents(docs)

拆分代码

RecursiveCharacterTextSplitterfrom_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

这里演示的是Python语言。

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"),		# 元组的第一个参数应该要根据 Markdown 语法来进行选择,不能乱写,而第二个就可以乱写了。
    ("##", "这是标题2"),		 # 像这样
    ("###", "超级棒棒糖"),
]

splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
splits = splitter.split_text(markdown_document)

按字符递归拆分

这也是对于普通文本的推荐拆分方式。它通过一组字符作为参数,按顺序尝试使用这些字符进行拆分,直到块的大小足够小为止。默认的字符列表是["\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)

按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)

向量化文档分块

LangchainEmbeddings 类实现与文本嵌入模型进行交互的标准接口。当前市场上有许多嵌入模型提供者(如OpenAI、Cohere、Hugging Face等)。

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

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

向量数据存储

向量数据存储,或成为向量数据库,负责存储文本嵌入的向量表现,并提供向量检索的能力。Langchain 提供了多种开源或商业向量数据存储,包括:Chroma, FAISS, Pinecone等。

本讲以Chroma为例。

存储

Langchain 提供了 Chroma 包装类,封装了chromadb的操作。

在进行以下代码执行前,需要安装 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 = "什么是WTF Langchain?"
docs = db.similarity_search(query)
print(docs[0].page_content)

end

我这里只是将大佬教程做了一个大概的笔记,避免哪天找不到了而已,如果是认真想要学习的话,可以去看大佬教程

posted @ 2023-09-10 11:12  淦丘比  阅读(280)  评论(0)    收藏  举报