【LangChain系列】第二篇:文档拆分简介及实践

在上一篇博客中,我们学习了如何使用LangChain的文档加载器将文档加载为标准格式。加载文档后,下一步是将它们拆分为更小的块。这个过程乍一看似乎很简单,但有一些微妙之处和重要的考虑因素会显着影响下游任务的性能和准确性。

一、为什么文档拆分很重要

文档拆分至关重要,因为它可以确保语义相关的内容在同一块中组合在一起。在回答问题或执行依赖于文档中存在的上下文信息的其他任务时,这一点尤为重要。
image.png

考虑以下示例:假设我们有一句关于丰田凯美瑞及其规格的句子。如果我们天真地拆分这个句子,而不考虑上下文,我们最终可能会得到一个包含句子部分的块和另一个包含剩余部分的块。因此,当试图回答有关凯美瑞规格的问题时,我们都不会在任何一个块中获得完整的信息,从而导致答案不正确或不完整。

二、文档拆分在LangChain中是如何工作的?

LangChain中所有文本拆分器的基础是将文本拆分为指定大小的块,相邻块之间有可选的重叠。下图对此进行了说明:
image.png

对应于每个块的大小,可以用字符或标记来衡量。这是在连续块之间共享的文本的一部分,允许跨块维护上下文boundaries.chunk_sizechunk_overlap。

三、文本拆分类型

LangChain提供了几种类型的文本拆分器,每种都有自己的优势和用例。以下是一些最常用的分离器:
image.png

1.CharacterTextSplitter

一个基本的拆分器,它基于单个字符分隔符(如空格或换行符)拆分文本。在处理结构不清晰的文本或想要在特定点拆分文本时,此拆分器非常有用。

2.RecursiveCharacterTextSplitter

用于通用文本拆分,它根据分隔符的层次结构拆分文本,从双换行符开始,然后是单换行符 、空格,最后是单个字符。这种方法旨在通过优先考虑段落和句子等自然边界的拆分来保持文本的结构和连贯性。RecursiveCharacterTextSplitternnn

3.TokenTextSplitter

根据标记计数而不是字符计数拆分文本,因为许多语言模型都具有由标记计数而不是字符计数指定的上下文窗口。标记的长度通常约为四个字符,因此基于标记计数进行拆分可以更好地表示语言模型将如何处理文本。TokenTextSplitter

4.MarkdownHeaderTextSplitter

旨在根据标题结构拆分 Markdown 文档。它将标头元数据保留在生成的块中,从而允许上下文感知拆分和使用文档结构的潜在下游任务。MarkdownHeaderTextSplitter

四、上手实例

让我们探索一些示例,以更好地了解这些文本拆分器的工作原理以及如何有效地使用它们。

1.设置环境

通过导入必要的库并加载 OpenAI API 密钥来设置环境:

import os
from langchain_openai import OpenAI
from dotenv import load_dotenv, find_dotenv

_ = load_dotenv(find_dotenv())

client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY")
)

接下来,我们将导入两个最常用的文本拆分器:

from langchain_text_splitters import (
    CharacterTextSplitter,
    RecursiveCharacterTextSplitter,
)

2.使用CharacterTextSplitter和RecursiveCharacterTextSplitter拆分

让我们从定义一些示例开始,以了解这些分离器的工作原理:

chunk_size = 26
chunk_overlap = 4

r_splitter = RecursiveCharacterTextSplitter(
    chunk_size=chunk_size, chunk_overlap=chunk_overlap
)
c_splitter = CharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)

text1 = "abcdefghijklmnopqrstuvwxyz"
print(r_splitter.split_text(text1))  
# Output: ['abcdefghijklmnopqrstuvwxyz']

text2 = "abcdefghijklmnopqrstuvwxyzabcdefg"
print(r_splitter.split_text(text2))  
# Output: ['abcdefghijklmnopqrstuvwxyz', 'wxyzabcdefg']

text3 = "a b c d e f g h i j k l m n o p q r s t u v w x y z"
print(r_splitter.split_text(text3))  
# Output: ['a b c d e f g h i j k l m', 'l m n o p q r s t u v w x', 'w x y z']
print(c_splitter.split_text(text3))  
# Output: ['a b c d e f g h i j k l m n o p q r s t u v w x y z']

# Set the separator for CharacterTextSplitter
c_splitter = CharacterTextSplitter(
    chunk_size=chunk_size, chunk_overlap=chunk_overlap, separator=" "
)
print(c_splitter.split_text(text3))  
# Output: ['a b c d e f g h i j k l m', 'l m n o p q r s t u v w x', 'w x y z']

这些示例演示了如何根据指定的 和 拆分文本,而如何基于单个字符分隔符(在本例中为空格)拆分文本。

3.真实示例

尝试拆分一些真实世界的例子:

some_text = """When writing documents, writers will use document structure to group content. \
This can convey to the reader, which idea's are related. For example, closely related ideas \
are in sentances. Similar ideas are in paragraphs. Paragraphs form a document. \n\n  \
Paragraphs are often delimited with a carriage return or two carriage returns. \
Carriage returns are the "backslash n" you see embedded in this string. \
Sentences have a period at the end, but also, have a space.\
and words are separated by space."""

c_splitter = CharacterTextSplitter(chunk_size=450, chunk_overlap=0, separator=" ")
r_splitter = RecursiveCharacterTextSplitter(
    chunk_size=450, chunk_overlap=0, separators=["\n\n", "\n", " ", ""]
)

chunks = c_splitter.split_text(some_text)
print("Chunks: ", chunks)
print("Length of chunks: ", len(chunks))
# Chunks:  ['When writing documents, writers will use document structure to group content. This can convey to the reader, which idea's are related. For example, closely related ideas are in sentances. Similar ideas are in paragraphs. Paragraphs form a document. \n\n Paragraphs are often delimited with a carriage return or two carriage returns. Carriage returns are the "backslash n" you see embedded in this string. Sentences have a period at the end, but also,', 'have a space.and words are separated by space.']
# Length of chunks:  2

chunks = r_splitter.split_text(some_text)
print("Chunks: ", chunks)
print("Length of chunks: ", len(chunks))
# Chunks:  ["When writing documents, writers will use document structure to group content. This can convey to the reader, which idea's are related. For example, closely related ideas are in sentances. Similar ideas are in paragraphs. Paragraphs form a document.", 'Paragraphs are often delimited with a carriage return or two carriage returns. Carriage returns are the "backslash n" you see embedded in this string. Sentences have a period at the end, but also, have a space.and words are separated by space.']
# Length of chunks:  2

在此示例中,它基于空格拆分文本,而第一个尝试拆分双换行符,然后是单换行符、空格,最后是单个字符。CharacterTextSplitterRecursiveCharacterTextSplitterCharacterTextSplitterRecursiveCharacterTextSplitter

我们还可以拆分真实世界的文档,例如 PDF 和 Notion 数据库:

from langchain.document_loaders import PyPDFLoader, NotionDirectoryLoader

# Load a PDF document
loader = PyPDFLoader("docs/cs229_lectures/MachineLearning-Lecture01.pdf")
pages = loader.load()

text_splitter = CharacterTextSplitter(
    separator="\n", chunk_size=1000, chunk_overlap=150, length_function=len
)
docs = text_splitter.split_documents(pages)

print("Pages in the original document: ", len(pages))
print("Length of chunks after splitting pages: ", len(docs))
# Pages in the original document:  22
# Length of chunks after splitting pages:  353

此代码使用 加载 PDF 文档,将页面拆分为较小的块,并打印原始页数和生成的块数。PyPDFLoaderCharacterTextSplitter

# Load a Notion database
loader = NotionDirectoryLoader("docs/Notion_DB")
notion_db = loader.load()

docs = text_splitter.split_documents(notion_db)

print("Pages in the original notion document: ", len(notion_db))
print("Length of chunks after splitting pages: ", len(docs))
# Pages in the original notion document:  52
# Length of chunks after splitting pages:  353

类似地,我们可以加载一个 Notion 数据库,将文档拆分为块,并打印原始文档的数量和生成的块。NotionDirectoryLoader

五、Token-based拆分

除了基于字符的拆分之外,LangChain还支持基于令牌的拆分,这在使用具有由令牌计数指定的上下文窗口的语言模型时非常有用:

from langchain.text_splitter import TokenTextSplitter

text_splitter = TokenTextSplitter(chunk_size=1, chunk_overlap=0)
text1 = "foo bar bazzyfoo"
print(text_splitter.split_text(text1))  
# Output: ['foo', ' bar', ' b', 'az', 'zy', 'foo']

text_splitter = TokenTextSplitter(chunk_size=10, chunk_overlap=0)
docs = text_splitter.split_documents(pages)
print(docs[0])  
# Output: Document(page_content='MachineLearning-Lecture01  \n', metadata={'source': 'docs/cs229_lectures/MachineLearning-Lecture01.pdf', 'page': 0})
print(pages[0].metadata)
# Output: {'source': 'docs/cs229_lectures/MachineLearning-Lecture01.pdf', 'page': 0}

在此示例中,我们使用 to 根据令牌计数拆分文本。我们可以调整 and 参数来控制拆分行为。TokenTextSplitterchunk_sizechunk_overlap

六、Context-aware拆分

LangChain还提供了上下文感知拆分的工具,旨在在拆分过程中保留文档结构和语义上下文。它根据文档的标题结构拆分 Markdown 文档,并将标题元数据保留在生成的块中:MarkdownHeaderTextSplitter

from langchain.document_loaders import NotionDirectoryLoader
from langchain.text_splitter import MarkdownHeaderTextSplitter

markdown_document = """# Title\n\n \
## Chapter 1\n\n \
Hi this is Jim\n\n Hi this is Joe\n\n \
### Section \n\n \
Hi this is Lance \n\n 
## Chapter 2\n\n \
Hi this is Molly"""

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

markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
md_header_splits = markdown_splitter.split_text(markdown_document)

print(md_header_splits[0])  
# Output: Document(page_content='Hi this is Jim  \nHi this is Joe', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 1'})
print(md_header_splits[1])  
# Output: Document(page_content='Hi this is Lance', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 1', 'Header 3': 'Section'})

在此示例中,我们定义一个带有标题的 Markdown 文档,并根据标题结构拆分文档。生成的块保留标头元数据,这对于利用文档结构的下游任务非常有用。MarkdownHeaderTextSplitter

我们还可以将此拆分器Notion 数据库:

loader = NotionDirectoryLoader("docs/Notion_DB")
docs = loader.load()
txt = " ".join([d.page_content for d in docs])

headers_to_split_on = [
    ("#", "Header 1"),
    ("##", "Header 2"),
]
markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
md_header_splits = markdown_splitter.split_text(txt)

print(md_header_splits[0])

此代码加载一个 Notion 数据库,将文档内容联接到单个字符串中,拆分字符串,并打印第一个生成的块。MarkdownHeaderTextSplitter

小结

文档拆分是LangChain流水线中的关键步骤,因为它确保语义相关的内容在同一块中组合在一起。LangChain提供了各种文本拆分器,每个拆分器都有自己的优势和用例,允许您根据自己的特定需求选择最合适的拆分器。

无论您是处理通用文本、Markdown 文档、代码片段还是其他类型的内容,LangChain 的文本拆分器都提供了灵活性和自定义选项,可以有效地拆分您的文档。通过了解文档拆分中涉及的细微差别和注意事项,可以优化语言模型和下游任务的性能和准确性。

如何系统的去学习大模型LLM ?

作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料 包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来

所有资料 ⚡️ ,朋友们如果有需要全套 《LLM大模型入门+进阶学习资源包》,扫码获取~

👉CSDN大礼包🎁:全网最全《LLM大模型入门+进阶学习资源包》免费分享(安全链接,放心点击)👈

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

在这里插入图片描述

四、AI大模型商业化落地方案

img

阶段1:AI大模型时代的基础理解

  • 目标:了解AI大模型的基本概念、发展历程和核心原理。
  • 内容
    • L1.1 人工智能简述与大模型起源
    • L1.2 大模型与通用人工智能
    • L1.3 GPT模型的发展历程
    • L1.4 模型工程
      - L1.4.1 知识大模型
      - L1.4.2 生产大模型
      - L1.4.3 模型工程方法论
      - L1.4.4 模型工程实践
    • L1.5 GPT应用案例

阶段2:AI大模型API应用开发工程

  • 目标:掌握AI大模型API的使用和开发,以及相关的编程技能。
  • 内容
    • L2.1 API接口
      - L2.1.1 OpenAI API接口
      - L2.1.2 Python接口接入
      - L2.1.3 BOT工具类框架
      - L2.1.4 代码示例
    • L2.2 Prompt框架
      - L2.2.1 什么是Prompt
      - L2.2.2 Prompt框架应用现状
      - L2.2.3 基于GPTAS的Prompt框架
      - L2.2.4 Prompt框架与Thought
      - L2.2.5 Prompt框架与提示词
    • L2.3 流水线工程
      - L2.3.1 流水线工程的概念
      - L2.3.2 流水线工程的优点
      - L2.3.3 流水线工程的应用
    • L2.4 总结与展望

阶段3:AI大模型应用架构实践

  • 目标:深入理解AI大模型的应用架构,并能够进行私有化部署。
  • 内容
    • L3.1 Agent模型框架
      - L3.1.1 Agent模型框架的设计理念
      - L3.1.2 Agent模型框架的核心组件
      - L3.1.3 Agent模型框架的实现细节
    • L3.2 MetaGPT
      - L3.2.1 MetaGPT的基本概念
      - L3.2.2 MetaGPT的工作原理
      - L3.2.3 MetaGPT的应用场景
    • L3.3 ChatGLM
      - L3.3.1 ChatGLM的特点
      - L3.3.2 ChatGLM的开发环境
      - L3.3.3 ChatGLM的使用示例
    • L3.4 LLAMA
      - L3.4.1 LLAMA的特点
      - L3.4.2 LLAMA的开发环境
      - L3.4.3 LLAMA的使用示例
    • L3.5 其他大模型介绍

阶段4:AI大模型私有化部署

  • 目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。
  • 内容
    • L4.1 模型私有化部署概述
    • L4.2 模型私有化部署的关键技术
    • L4.3 模型私有化部署的实施步骤
    • L4.4 模型私有化部署的应用场景

学习计划:

  • 阶段1:1-2个月,建立AI大模型的基础知识体系。
  • 阶段2:2-3个月,专注于API应用开发能力的提升。
  • 阶段3:3-4个月,深入实践AI大模型的应用架构和私有化部署。
  • 阶段4:4-5个月,专注于高级模型的应用和部署。
这份完整版的所有 ⚡️ 大模型 LLM 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

全套 《LLM大模型入门+进阶学习资源包↓↓↓ 获取~

👉CSDN大礼包🎁:全网最全《LLM大模型入门+进阶学习资源包》免费分享(安全链接,放心点击)👈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/680656.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

qcom 平台系统签名流程

security boot 平台的东东,oem 可定制的功能有限,只能参考平台文档,可以在高通的网站上搜索:Secure Boot Enablement,然后找对应平台的文档xxx-Secure Boot Enablement User Guide, step by step 操作即可 开机校验流…

【人工智能】第五部分:ChatGPT的实际应用案例和未来发展方向

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

【成品设计】基于STM32的体温监控系统的设计与实现

《基于STM32的体温监控系统的设计与实现》 整体功能: 体温监控系统采用STM32F103VET6单片机为主控,在此基础上移植了一款国产嵌入式操作系统RT-thread进行开发设计的。 该系统的主要工作逻辑为:管理员可先将相关人员的指纹、ID等数据录入系…

AC/DC电源模块的效率如何?

BOSHIDA AC/DC电源模块的效率如何? AC/DC电源模块是一种将交流电转换为直流电的装置,常用于电子设备的电源部分。其效率是指输入电功率与输出电功率的比值,通常以百分比表示。AC/DC电源模块的效率主要取决于以下几个因素:开关频…

EE trade:如何在A股市场中有效设定止盈止损点

A股市场充满机遇和风险,很多投资者在这里实现了财富增长,也有投资者在这里遭受损失。如何在波动性较大的市场中,控制风险,保护利润和本金?止盈止损是关键。 什么是止盈止损? 止盈止损是指在交易中,根据预先设定的条…

酱菜产业:传承美味,点亮生活

酱菜,这道深受人们喜爱的传统美食,以其独特的风味和营养价值,点亮了我们的日常生活。酱菜产业作为美食文化的重要组成部分,正以其独特的魅力,吸引着越来越多的消费者。 酱菜产业的赵总说:酱菜的制作过程&am…

深入分析 Flink SQL 工作机制

摘要:本文整理自 Flink Forward 2020 全球在线会议中文精华版,由 Apache Flink PMC 伍翀(云邪)分享,社区志愿者陈婧敏(清樾)整理。旨在帮助大家更好地理解 Flink SQL 引擎的工作原理。文章主要分…

电商API商品数据采集接口||助力电商企业采集商品大数据提高开发效率

提高开发效率:电商API接口允许不同的应用程序之间高效地进行交互,节省了大量的人力物力成本,使得开发者可以将更多时间和精力集中于自身的核心业务。 增加数据安全性:通过对数据进行安全加密,API接口实现了对数据的保护…

java自学阶段二:JavaWeb开发45(git学习)

目录: 学习目标git的使用(工作流程、常用命令、idea集成) 一、学习目标: 了解Git基本概念能够了解git的工作流程能够使用Git常用命令熟悉Git代码托管服务能够使用idea操作git 二、git的使用 1)git的概念&#xff1…

Oracle 19c OCM认证

Oracle OCM介绍 Oracle Certified Master (OCM) -Oracle认证大师,是Oracle认证的最高级别,是对数据库从业人员的技术、知识和操作技能的最高级别的认可,IT界顶级认证之一。Oracle OCM是解决最困难的技术难题和最复杂的系统故障的最佳Oracle专…

凡尔码搭建设备巡检系统数字化管理平台

一、搭建过程概述 利用凡尔码搭建设备巡检的数字化管理平台,首先需要对凡尔码平台有深入的了解,明确其提供的核心功能和特性,以及如何在设备巡检领域发挥其优势。接着,通过系统规划、组件配置、数据录入和表单创建等步骤&#xff…

短剧小程序App系统源码:打造个性化追剧体验

随着数字媒体的迅猛发展,短剧作为一种新兴的娱乐形式,越来越受到广大观众的喜爱。为了满足用户对短剧内容的个性化需求,短剧小程序App系统应运而生。本文将深入探讨短剧App源码的核心功能,以及如何通过多语言支持和国际支付等技术…

形如SyntaxError: EOL while scanning string literal,以红色波浪线形式在Pycharm下出现

背景: 新手在学习Python时可能会出现如下图所示的报错 下面分情况教大家如何解决 过程: 问题概述: 简单来说就是你单引号、双引号、三引号写的时候末尾注意要和前面写的匹配。 具体如下 """ 编辑器报错:Synt…

在Windows中使用svn的命令行

windows下使用svn命令行_svn命令行工具在哪里-CSDN博客 先下载命令行工具 再进行配置 set SVN_CMD_HOMEC:\Users\admin\Desktop\Apache-Subversion-1.14.0\bin(你的安装路径) set path%path%;%SVN_CMD_HOME% svn help查看svn版本 命令行查看svn版本--真实有效_svn 版本查看…

Java Web学习笔记4——HTML、CSS

HTML: HTML:超文本标记语言。 超文本:超越了文本的限制,比普通文本更强大。除了文字信息,还可以定义图片、音频、视频等内容。 标记语言:有标签构成的语言。 HTML标签都是预定义好的,例如&a…

【全开源】小区物业收费管理系统小程序(FastAdmin+UniApp)

便捷生活新选择 一款基于FastAdminUniApp开发的一款物业收费管理小程序。包含房产管理、收费标准、家属管理、抄表管理、在线缴费、业主公告、统计报表、业主投票、可视化大屏等功能。为物业量身打造的小区收费管理系统,贴合物业工作场景,轻松提高物业费…

Python实现PPT表格的编写包含新建修改插图(收藏备用)

自动创建一个ppt文件并创建好表格 代码要用到pptx库 pip install python-pptx 创建含有表格的ppt文件代码: from pptx import Presentation from pptx.util import Inches# 创建一个PPT对象 ppt Presentation()# 添加一个幻灯片 slide ppt.slides.add_slide(p…

【C++】优先级队列介绍与模拟实现

💞💞 前言 hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页&#x…

冒泡函数模拟qsort函数

有关于qsort函数和冒泡函数可以跳转CSDNhttps://mp.csdn.net/mp_blog/creation/editor/139388503 qsort的底层逻辑是这样的 我们冒泡排序模仿qsort必须要针对的是所以说我们要模仿qsort的底层逻辑来写 我们以整型数组来举例 #include <stdio.h> int cmp_int(const vo…

OpenAI的Sam Altman搞核聚变了?!究竟是创新还是疯狂?|TodayAI

据《华尔街日报》报道&#xff0c;西雅图地区的核聚变公司Helion Energy正在与人工智能公司OpenAI洽谈一项重要交易&#xff0c;OpenAI计划“购买大量电力为数据中心提供动力”。这一消息引起了广泛关注。 OpenAI的首席执行官兼联合创始人Sam Altman已向Helion投资了3.75亿美元…