当前位置:   article > 正文

WTF Langchain极简入门: 03. 数据连接_from langchain.document_loaders import textloader;

from langchain.document_loaders import textloader;

加载文档

langchain提供多种文档加载器,支持多种格式、来源的文件。可以从本地存储系统加载文件,也可以从网上加载远端文件。想了解LangChain所支持的所有文档加载器,请参考Document Loaders

在本系列课程中,我们将使用最基本的TextLoader来加载本地文件系统中的文档。

代码如下:

  1. # 从langchain.document_loader文件中导入文件加载类TextLoder
  2. from langchain.document_loaders import TextLoader
  3. # TextLoader加载"./README.md",实例化loader对象
  4. loader = TextLoader("./README.md")
  5. # loader调用load方法生成一个Document类型的文件doc
  6. doc = loader.load()
  7. docs

使用TextLoader加载"./README.md"文件,调用TextLoader的load函数生成一个Document对象数组。Document是langchain中的文档类,存放原始内容和元数据,还可以通过Document类的content属性访问原内容。

拆分文档

拆分文档是最常见的文档转换操作。拆分文档将文档拆分为更小的文档块,为了更好地利用模型。

在基于长篇文本的问答(QA)系统中, 必须将文本拆分为多个文本块,这样才能在数据搜索中,基于文本相似性匹配到与问题最相近的文本块。这也是常见的AI问答机器人的基本工作原理。

langchain提供多种文档拆分器,将文档拆分为更小的文档块。

按字符拆分

langchain中最基础的文档拆分器——CharacterTextSplitter,它将文档拆分为固定长度文本块。

  1. # 从langchain.text_splitter中导入CharacterTextSplitter类
  2. from langchain.text_splitter import CharacterTextSplitter
  3. # CharacterTextSplitter实例化对象text_splitter
  4. # 参数separator是分割符,chunk_size是切块大小,chunk_overlap是块与块重叠部分
  5. text_splitter = CharacterTextSplitter(
  6. separator = "\n\n",
  7. chunk_size = 1000,
  8. chunk_overlap = 200,
  9. length_function = len,
  10. )
  11. # text_splitter调用split_documents处理docs文件
  12. split_docs = text_splitter.split_documents(docs)
  13. print(len(docs[0].page_content))
  14. for split_doc in split_docs:
  15. print(len(split_doc.page_content))

应该看到下面的输出

3316

996

963

864

913

296

拆分代码

RecursiveCharacterTextSplitter的from_language函数,能够根据编程语言的特性,将代码分为恰当的文本块。

  1. # 写python代码hello_chain
  2. PYTHON_CODE = """
  3. def hello_langchain():
  4. print("Hello, LangChain!")
  5. # Call the function
  6. hello_langchain()
  7. """
  8. # 导入RecursiveCharacterTextSplitter文本分块类
  9. from langchain.text_splitter import RecursiveCharacterTextSplitter,Language
  10. # 实例化python_splitter。
  11. # RecursiveCharacterTextSplitter的from_language方法识别Python代码
  12. python_splitter = RecursiveCharacterTextSplitter.from_language(
  13. language = Language.PYTHON, chunk_size = 50, chunk_overlap = 0,
  14. )
  15. # create_documents对PYTHON_CODE切块
  16. python_docs = python_splitter.create_documents([PYTHON_CODE])
  17. python_docs

应该看到下面这个输出

[Document(page_content='def hello_langchain():', metadata={}), Document(page_content='print("Hello, LangChain!")', metadata={}),

Document(page_content='# Call the function\nhello_langchain()', metadata={})]

Markdown文件拆分

MarkdownHeaderTextSplitter能够将Markdown文件按照段落结构,基于Markdowm语法进行文本拆分。代码如下

  1. # 从langchain.text_splitter导入MarkdownHeaderTextSplitter类
  2. from langchain.text_splitter import MarkdownHeaderTextSplitter
  3. # 设置mark_document文件
  4. 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"
  5. # 设置切分参数
  6. headers_to_split_on = [("#", "Header 1"),("##", "Header 2"),("###", "Header 3")]
  7. # MarkdownHeaderTextSplitter类实例化splitter对象
  8. splitter = MarkdownHeaderTextSplitter(headers_to_split_on = headers_to_split_on)
  9. # splitter调用split_text方法切分Markdown文件,生成splits
  10. splits = splitter.split_text(markdown_document)
  11. # 显示splits
  12. splits

应该能看到下面这个输出

[Document(page_content='Hi this is the 1st section \nWelcome', metadata={'Header 1': 'Chapter 1', 'Header 2': 'Section 1'}), Document(page_content='Hi this is the first module', metadata={'Header 1': 'Chapter 1', 'Header 2': 'Section 1', 'Header 3': 'Module 1'}), Document(page_content='Hi this is the 2nd section', metadata={'Header 1': 'Chapter 1', 'Header 2': 'Section 2'})]

按字符递归拆分

这是常见的一种拆分方式,使用拆分符号不断拆分文本,尽量使文本尺寸减小。默认的参数是["\n\n","\n",","],它尽可能保证语义的完整性,保持段落、句子、单词的完整。

  1. # 导入RecursiveCharacterTextSplitter类
  2. from langchain.text_splitter import RecursiveCharacterTextSplitter
  3. # RecursiveCharacterTextSplitter实例化text_splitter对象
  4. # 设置初始化参数
  5. text_splitter = RecursiveCharacterTextSplitter(
  6. # Set a really small chunk size, just to show.
  7. chunk_size = 100,
  8. chunk_overlap = 20,
  9. length_function = len,
  10. )
  11. # text_splitter切分器调用split_documents方法切分docs文件
  12. doc = text_splitter.split_documents(docs)
  13. doc

按token拆分

一些语言模型,在API的使用过程中,交互时都有token数的限制。可见,拆分文本时,按照token数目拆分也是不错的方法。目前有许多token化工具,在统计文本token数时,请使用对应的token化工具。

注:OpenAI所使用的是tiktoken

  1. from langchain.text_splitter import CharacterTextSplitter
  2. text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
  3. chunk_size = 100, chunk_overlap = 20)
  4. doc = text_splitter.split_documents(docs)
  5. doc

向量化文档

langchain框架中的embeddings类,是与文本嵌入模型的进行交互地标准接口。当前有许多文本嵌入模型,如如OpenAI、Cohere、Hugging Face等,本文选用的是OpenAI的嵌入模型,也可以使用其他的模型。

嵌入模型对文本进行向量化,这种转化能够在向量空间中处理文本,通过向量空间的相似性,进行文本语义的搜索。

注:文本的相似性常由其向量表示的欧几里得距离来衡量,也称第二范式。对于n维的两个向量a,b,欧几里得距离可通过以下公式计算:

我们使用如下代码来创建文本片段的向量表示:

  1. # 导入OpenAIEmbeddings类
  2. from langchain.embeddings import OpenAIEmbeddings
  3. # 实例化embeddings_model对象
  4. embeddings_model = OpenAIEmbeddings(openai_api_key = "您的openai_api_key")
  5. # embeddings_model调用embed_documents方法对文本向量化
  6. embeddings = embeddings_model.embed_documents(
  7. ["你好",
  8. "Langchain",
  9. "你真棒"
  10. ])
  11. embeddings

您应该看到类似的输出

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

向量数据存储

langchain支持多种向量存储,如Chroma, FAISS, Pinecone等。本文以Chroma为例

langchain框架提供Chroma包装类,封装了chromadb的操作。

需要先安装Chroma

pip install -q chromadb

接下来进行数据存储

  1. from langchain.document_loaders import TextLoader
  2. from langchain.text_splitter import CharacterTextSplitter
  3. from langchain.embeddings import OpenAIEmbeddings
  4. from langchain.vectorstores import Chroma
  5. # 下载README.md
  6. !wget https://raw.githubusercontent.com/WTFAcademy/WTF-Langchain/main/01_Hello_Langchain/README.md
  7. # TextLoader实例化对象loader,加载README.md生成docs文件
  8. loader = TextLoader("./README.md")
  9. docs = loader.load()
  10. # 切分docs文件为documents
  11. text_splitter = CharacterTextSplitter(
  12. chunk_size = 1000, chunk_overlap = 0)
  13. documents = text_splitter.split_documents(docs)
  14. # 实例化嵌入模型
  15. embedding_model = OpenAIEmbeddings(openai_api_key = "您的openai_api_key")
  16. # 存储向量化文本
  17. db = Chroma.from_documents(documents, embedding_model)
  18. db

检索

向量数据库最常用来查询给定文本的相似文本,通过similarity_search方法来获取。

  1. query = " 什么是 WTF langchain"
  2. docs = db.similarity_search(query)
  3. docs
  4. docs = db.similarity_search_with_score(query)
  5. docs

总结:

本文我们学习了Langchain的数据连接部分

1.数据的加载

2.数据的切分

3.数据的嵌入向量化

4.数据的向量化存储以及查询

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/357395
推荐阅读
相关标签
  

闽ICP备14008679号