当前位置: 首页 > news >正文

文本切块技术(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.xdnf.cn/news/920035.html

相关文章:

  • 运行示例程序和一些基本操作
  • 解决MySQL8.4报错ERROR 1524 (HY000): Plugin ‘mysql_native_password‘ is not loaded
  • Puppeteer API
  • Redis:现代应用开发的高效内存数据存储利器
  • springCloud2025+springBoot3.5.0+Nacos集成redis从nacos拉配置起服务
  • 【JavaWeb】Docker项目部署
  • LabVIEW主轴故障诊断案例
  • WPS中将在线链接转为图片
  • 备份还原打印机驱动
  • Spring——Spring相关类原理与实战
  • 欣佰特科技亮相2025张江具身智能开发者大会:呈现人形机器人全链条解决方案
  • Linux中su与sudo命令的区别:权限管理的关键差异解析
  • 【知识扫盲】分布式系统架构或分布式服务中的管理面,数据面和业务面
  • C#使用MindFusion.Diagramming框架绘制流程图(2):流程图示例
  • Keil开发STM32生成hex文件/bin文件
  • 鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
  • TDengine 支持的平台汇总
  • TCP/IP 与高速网络
  • 量子电路设计:以 Qiskit 为例
  • 使用柏林噪声生成随机地图
  • 金融预测模型开发:数据预处理、机器学习预测与交易策略优化
  • 如何配置 MySQL 允许远程连接
  • <PLC><HMI><威纶通>威纶通HMI与西门子PLC通讯时,如何在触摸屏添加PLC变量?
  • 电子电气架构 ---智能汽车电子电气架构
  • 用队列实现栈
  • NT6打印机共享修复工具Fixprint系统补丁
  • React Hooks 示例项目
  • phosphobot开源程序是控制您的 SO-100 和 SO-101 机器人并训练 VLA AI 机器人开源模型
  • 《探秘跨网段局域网IP广播:解锁网络通信的新姿势》
  • OCR MLLM Evaluation