文本切块技术(Splitter)

为什么要分块?

将长文本分解成适当大小的片段,以便于嵌入、索引和存储,并提高检索的精确度。

用ChunkViz工具可视化分块

在线使用

ChunkViz

github

https://github.com/gkamradt/ChunkViz

如何确定大模型所能接受的最长上下文

可以从模型card和config文件中得知

文本分块的方法和实现

CharacterTextSplitter - 按固定字符数分块

RecursiveCharacterTextSplitter – 递归分块

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
loader = TextLoader("90-文档-Data/山西文旅/云冈石窟.txt")
documents = loader.load()
# 定义分割符列表,按优先级依次使用
separators = ["\n\n", ".", ",", " "] # . 是句号,, 是逗号, 是空格
# 创建递归分块器,并传入分割符列表
text_splitter = RecursiveCharacterTextSplitter(chunk_size=100,chunk_overlap=10,separators=separators
)
chunks = text_splitter.split_documents(documents)
print("\n=== 文档分块结果 ===")
for i, chunk in enumerate(chunks, 1):print(f"\n--- 第 {i} 个文档块 ---")print(f"内容: {chunk.page_content}")print(f"元数据: {chunk.metadata}")print("-" * 50)

基于特定格式(如python代码格式)分块

from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_text_splitters import Language
separators = RecursiveCharacterTextSplitter.get_separators_for_language(Language.JAVASCRIPT)
print(separators)from langchain_text_splitters import (Language,RecursiveCharacterTextSplitter,
)
GAME_CODE = """
class CombatSystem:def __init__(self):self.health = 100self.stamina = 100self.state = "IDLE"self.attack_patterns = {"NORMAL": 10,"SPECIAL": 30,"ULTIMATE": 50}def update(self, delta_time):self._update_stats(delta_time)self._handle_combat()def _update_stats(self, delta_time):self.stamina = min(100, self.stamina + 5 * delta_time)def _handle_combat(self):if self.state == "ATTACKING":self._execute_attack()def _execute_attack(self):if self.stamina >= self.attack_patterns["SPECIAL"]:damage = 50self.stamina -= self.attack_patterns["SPECIAL"]return damagereturn self.attack_patterns["NORMAL"]
class InventorySystem:def __init__(self):self.items = {}self.capacity = 20self.gold = 0def add_item(self, item_id, quantity):if len(self.items) < self.capacity:if item_id in self.items:self.items[item_id] += quantityelse:self.items[item_id] = quantitydef remove_item(self, item_id, quantity):if item_id in self.items:self.items[item_id] -= quantityif self.items[item_id] <= 0:del self.items[item_id]def get_item_count(self, item_id):return self.items.get(item_id, 0)
class QuestSystem:def __init__(self):self.active_quests = {}self.completed_quests = set()self.quest_log = []def add_quest(self, quest_id, quest_data):if quest_id not in self.active_quests:self.active_quests[quest_id] = quest_dataself.quest_log.append(f"Started quest: {quest_data['name']}")def complete_quest(self, quest_id):if quest_id in self.active_quests:self.completed_quests.add(quest_id)del self.active_quests[quest_id]def get_active_quests(self):return list(self.active_quests.keys())
"""
python_splitter = RecursiveCharacterTextSplitter.from_language(language=Language.PYTHON,  # 指定编程语言为Pythonchunk_size=1000,chunk_overlap=0
)python_docs = python_splitter.create_documents([GAME_CODE])
print("\n=== 代码分块结果 ===")
for i, chunk in enumerate(python_docs, 1):print(f"\n--- 第 {i} 个代码块 ---")print(f"内容:\n{chunk.page_content}")print(f"元数据: {chunk.metadata}")print("-" * 50)

LlamaIndex-语义分块

from llama_index.core import SimpleDirectoryReader
from llama_index.core.node_parser import (SentenceSplitter,SemanticSplitterNodeParser,
)
from llama_index.embeddings.openai import OpenAIEmbedding 
# from llama_index.embeddings.huggingface import HuggingFaceEmbedding 
# embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-zh")
documents = SimpleDirectoryReader(input_files=["90-文档-Data/黑悟空/黑悟空wiki.txt"]).load_data()# 创建语义分块器
splitter = SemanticSplitterNodeParser(buffer_size=3,  # 缓冲区大小breakpoint_percentile_threshold=90, # 断点百分位阈值embed_model=OpenAIEmbedding()     # 使用的嵌入模型
)
# 创建基础句子分块器(作为对照)
base_splitter = SentenceSplitter(# chunk_size=512
)'''
buffer_size:
默认值为1
这个参数控制评估语义相似度时,将多少个句子组合在一起当设置为1时,每个句子会被单独考虑
当设置大于1时,会将多个句子组合在一起进行评估例如,如果设置为3,就会将每3个句子作为一个组来评估语义相似度breakpoint_percentile_threshold:
默认值为95
这个参数控制何时在句子组之间创建分割点,它表示余弦不相似度的百分位数阈值,当句子组之间的不相似度超过这个阈值时,就会创建一个新的节点
数值越小,生成的节点就越多(因为更容易达到分割阈值)
数值越大,生成的节点就越少(因为需要更大的不相似度才会分割)这两个参数共同影响文本的分割效果:
buffer_size 决定了评估语义相似度的粒度
breakpoint_percentile_threshold 决定了分割的严格程度
例如:
如果 buffer_size=2 且 breakpoint_percentile_threshold=90:每2个句子会被组合在一起,当组合之间的不相似度超过90%时就会分割,这会产生相对较多的节点
如果 buffer_size=3 且 breakpoint_percentile_threshold=98:每3个句子会被组合在一起,需要更大的不相似度才会分割,这会产生相对较少的节点
'''# 使用语义分块器对文档进行分块
semantic_nodes = splitter.get_nodes_from_documents(documents)
print("\n=== 语义分块结果 ===")
print(f"语义分块器生成的块数:{len(semantic_nodes)}")
for i, node in enumerate(semantic_nodes, 1):print(f"\n--- 第 {i} 个语义块 ---")print(f"内容:\n{node.text}")print("-" * 50)# 使用基础句子分块器对文档进行分块
base_nodes = base_splitter.get_nodes_from_documents(documents)
print("\n=== 基础句子分块结果 ===")
print(f"基础句子分块器生成的块数:{len(base_nodes)}")
for i, node in enumerate(base_nodes, 1):print(f"\n--- 第 {i} 个句子块 ---")print(f"内容:\n{node.text}")print("-" * 50)

使用Unstructured基于文档结构分块

与分块相关的高级索引技巧 

带滑动窗口的句子切分(Sliding Windows)

上下窗口为3的滑动窗口

分块时混合生成父子文本块(Parent-Child Docs)

通过子文本块检索父文本块

分块时为文本块创建元数据

打关键信息标签

在分块时形成有级别的索引(Summary→Details ) 

从摘要到细节的文档索引

文档→嵌入对象(Document→Embedded Objects) 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++:用 libcurl 发送一封带有附件的邮件

编写mingw C 程序&#xff0c;用 libcurl 发送一封带有附件的邮件 下面是一个使用 MinGW 编译的 C 程序&#xff0c;使用 libcurl 发送带附件的邮件。这个程序完全通过代码实现 SMTP 邮件发送&#xff0c;不依赖外部邮件客户端&#xff1a; // send_email.cpp #include <i…

tensorflow image_dataset_from_directory 训练数据集构建

以数据集 https://www.kaggle.com/datasets/vipoooool/new-plant-diseases-dataset 为例 目录结构 训练图像数据集要求&#xff1a; 主目录下包含多个子目录&#xff0c;每个子目录代表一个类别。每个子目录中存储属于该类别的图像文件。 例如 main_directory/ ...cat/ ...…

遨游Spring AI:第一盘菜Hello World

Spring AI的正式版已经发布了&#xff0c;很显然&#xff0c;接下来我们要做的事情就是写一个Hello World。 总体思路就是在本地搭建一个简单的大模型&#xff0c;然后编写Spring AI代码与模型进行交互。 分五步&#xff1a; 1. 安装Ollama&#xff1b; 2. 安装DeepSeek&…

华为云Flexus+DeepSeek征文|基于华为云Flexus X和DeepSeek-R1打造个人知识库问答系统

目录 前言 1 快速部署&#xff1a;一键搭建Dify平台 1.1 部署流程详解 1.2 初始配置与登录 2 构建专属知识库 2.1 进入知识库模块并创建新库 2.2 选择数据源导入内容 2.3 上传并识别多种文档格式 2.4 文本处理与索引构建 2.5 保存并完成知识库创建 3接入ModelArts S…

Java优化:双重for循环

在工作中&#xff0c;经常性的会出现在两张表中查找相同ID的数据&#xff0c;许多开发者会使用两层for循环嵌套&#xff0c;虽然实现功能没有问题&#xff0c;但是效率极低&#xff0c;一下是一个简单的优化过程&#xff0c;代码耗时凑从26856ms优化到了748ms。 功能场景 有两…

Prompt Tuning:生成的模型文件有什么构成

一、为什么Prompt Tuning会生成模型文件? 1. Prompt Tuning的本质:优化可训练的「提示参数」 核心逻辑:Prompt Tuning(提示调优)是一种轻量级的微调技术,仅优化模型输入层的提示向量(Prompt Embedding)或少量额外参数,而非更新整个预训练模型的权重。生成模型文件的原…

ARM SMMUv3简介(一)

1.概述 SMMU&#xff08;System Memory Management Unit&#xff0c;系统内存管理单元&#xff09;是ARM架构中用于管理设备访问系统内存的硬件模块。SMMU和MMU的功能类似&#xff0c;都是将虚拟地址转换成物理地址&#xff0c;不同的是MMU转换的虚拟地址来自CPU&#xff0c;S…

在 Windows 系统上运行 Docker 容器中的 Ubuntu 镜像并显示 GUI

在 Windows 上安装一个 X Server&#xff08;如 VcXsrv 或 X410&#xff09;&#xff0c;Ubuntu 容器通过网络将图形界面转发到 Windows。 步骤&#xff1a; 安装 X Server&#xff1a; 推荐使用VcXsrv&#xff0c;免费开源。 安装后运行 XLaunch&#xff0c;选择&#xff1…

Vue3学习(4)- computed的使用

1. 简述与使用 作用&#xff1a;computed 用于基于响应式数据派生出新值&#xff0c;其值会自动缓存并在依赖变化时更新。 ​缓存机制​&#xff1a;依赖未变化时直接返回缓存值&#xff0c;避免重复计算&#xff08;通过 _dirty 标志位实现&#xff09;。​响应式更新​&…

【HarmonyOS 5】出行导航开发实践介绍以及详细案例

以下是 ‌HarmonyOS 5‌ 出行导航的核心能力详解&#xff08;无代码版&#xff09;&#xff0c;聚焦智能交互、多端协同与场景化创新&#xff1a; 一、交互革新&#xff1a;从被动响应到主动服务 ‌意图驱动导航‌ ‌自然语义理解‌&#xff1a;用户通过语音指令&#xff08;如…

csrf攻击学习

原理 csrf又称跨站伪造请求攻击&#xff0c;现代网站利用Cookie、Session 或 Token 等机制识别用户身份&#xff0c;一旦用户访问某个网站&#xff0c;浏览器在之后请求会自动带上这些信息来识别用户身份。用户在网站进行请求或者操作时服务器会给出对应的内容&#xff0c;比如…

深入剖析MySQL锁机制,多事务并发场景锁竞争

一、隐藏字段对 InnoDB 的行锁&#xff08;Record Lock&#xff09;与间隙锁&#xff08;Gap Lock&#xff09;的影响 1. 隐藏字段与锁的三大核心影响 类型影响维度描述DB_TRX_IDMVCC 可见性控制决定是否读取当前版本&#xff0c;或在加锁时避开不可见版本&#xff08;影响加锁…

以SMMUv2为例,使用Trace32可视化操作SMMU的常用命令详解

Trace32支持一系列的SMMU命令&#xff0c;可以帮助用户更好地配置、查看和分析SMMU。换句话说&#xff0c;就是让SMMU的配置变得可视化。 在添加SMMU实例之前&#xff0c;需要选择一个CPU来激活该SMMU实例的相关命令。Trace32让SMMU的配置可视化的本质是&#xff0c;操纵CPU读取…

将数据库表导出为C#实体对象

数据库方式 use 数据库;declare TableName sysname 表名 declare Result varchar(max) /// <summary> /// TableName /// </summary> public class TableName {select Result Result /// <summary>/// CONVERT(NVARCHAR(500), ISNULL(ColN…

CSS 预处理器与工具

目录 CSS 预处理器与工具1. Less主要特性 2. Sass/SCSS主要特性 3. Tailwind CSS主要特性 4. 其他工具PostCSSCSS Modules 5. 选择建议 CSS 预处理器与工具 1. Less Less 是一个 CSS 预处理器&#xff0c;它扩展了 CSS 语言&#xff0c;添加了变量、嵌套规则、混合&#xff0…

this.$set() 的用法详解(Vue响应式系统相关)

1. 什么是 this.$set()&#xff1f; this.$set(target, key, value) 是 Vue 2 中提供的一个方法&#xff0c;用于向响应式对象中动态添加属性&#xff0c;确保新加的属性同样是响应式的。 2. 为什么需要它&#xff1f; Vue 2 的响应式系统基于 Object.defineProperty&#…

【HarmonyOS Next之旅】DevEco Studio使用指南(三十)

目录 1 -> 部署云侧工程 2 -> 通过CloudDev面板获取云开发资源支持 3 -> 通用云开发模板 3.1 -> 适用范围 3.2 -> 效果图 4 -> 总结 1 -> 部署云侧工程 可以选择在云函数和云数据库全部开发完成后&#xff0c;将整个云工程资源统一部署到AGC云端。…

如何配置nginx解决前端跨域请求问题

我们以一个简单的例子模拟不同情况下产生的跨域问题以及解决方案。假设在http://127.0.0.1:8000的页面调用接口 fetch(http://127.0.0.1:8003/api/data)常看到的错误“Access to fetch at ‘http://127.0.0.1:8003/api/data’ from origin ‘http://localhost:8000’ has been…

React Hooks 指南:何时使用 useEffect ?

在 React 的函数组件中&#xff0c;useEffect Hook 是一个强大且不可或缺的工具。它允许我们处理副作用 (side effects)——那些在组件渲染之外发生的操作。但是&#xff0c;什么时候才是使用 useEffect 的正确时机呢&#xff1f;让我们深入探讨一下&#xff01; 什么是副作用…

bat批量去掉本文件夹中的文件扩展名

本文本夹内 批量去掉本文件夹中的文件扩展名 假如你有一些文件&#xff0c;你想去掉他们的扩展名 有没有方便的办法呢 今天我们就分享一种办法。 下面&#xff0c;就来看看吧。 首先我们新建一个记事本&#xff0c;把名字改为&#xff0c;批量去掉本文件夹中的文件扩展名.txt 然…