文本切分策略
文本片段切分策略
相关源文件
本章引用的主要源码文件:
docs/FileProcessingPipeline-zh.mddocs/FileProcessingPipeline.mddocs/LightRAGSidecarFormat.mddocs/ParagraphSemanticChunking-zh.mddocs/ParagraphSemanticChunking.mddocs/ParserDebugCLI.mdlightrag/addon_params.pylightrag/chunker/__init__.pylightrag/chunker/paragraph_semantic.pylightrag/chunker/recursive_character.pylightrag/chunker/semantic_vector.pylightrag/chunker/token_size.pytests/test_chunk_options_persistence.pytests/test_chunking.pytests/test_paragraph_semantic_merge_and_fallback.pytests/test_paragraph_semantic_split_long_block.pytests/test_paragraph_semantic_table_split.py
LightRAG 采用多策略的片段切分架构,旨在平衡语义完整性与 Token 约束。自 v1.5.0 版本起,系统已从全局固定大小的切分方式,转变为由 process_options 标志驱动的按文档策略模型。
概述与片段切分器模块
片段切分器模块支持四种主要策略,每种策略针对不同的文档结构和计算资源进行了优化。策略的选择通常由 LIGHTRAG_PARSER 环境变量或文件名提示(例如 document.[-P].docx)控制 docs/FileProcessingPipeline.md:52-60。
策略对比
| 标志 | 策略 | 主要机制 | 最佳适用场景 |
|---|---|---|---|
| F | 固定切分(旧版) | 基于字符在固定 Token 间隔处进行切分 lightrag/chunker/token_size.py:1-10 | 纯文本、日志、简单文件。 |
| R | 递归切分 | 分隔符级联(段落 → 换行 → 标点 → 空格) lightrag/chunker/recursive_character.py:1-15 | Markdown、代码、非结构化散文。 |
| V | 语义向量切分 | 基于句子级嵌入向量相似度的断点检测 lightrag/chunker/semantic_vector.py:1-20 | 主题变化的散文。 |
| P | 段落语义切分 | 感知标题结构 + 感知表格行边界 lightrag/chunker/paragraph_semantic.py:1-15 | 包含复杂表格和层级结构的 DOCX 文件。 |
来源: lightrag/chunker/__init__.py:1-48, docs/FileProcessingPipeline.md:121-128, docs/ParagraphSemanticChunking.md:18-30
片段切分器契约与数据流
LightRAG 维护两套并行的 API 契约,以在支持高级文件处理的同时确保向后兼容性。
1. 旧版契约
当 process_options 未指定策略时(例如直接调用 ainsert)会调用此契约。它使用 chunking_by_token_size 函数,该函数接受 6 个位置参数 lightrag/chunker/__init__.py:5-16。
2. 文件-片段切分器契约
当 _PipelineMixin 显式选择策略时会调用此契约。它使用标准化的关键字参数签名:(tokenizer, content, chunk_token_size, *, **strategy_kwargs) lightrag/chunker/__init__.py:18-26。
代码实体空间:片段切分分发
下图展示了配置如何从环境变量流向具体的片段切分器实现。
来源: lightrag/chunker/__init__.py:1-48, tests/test_chunk_options_persistence.py:1-19, lightrag/addon_params.py:41-57
段落语义切分(P)算法
段落语义切分 策略是 LightRAG 中最先进的片段切分器,专为通过 native 解析引擎处理的结构化 DOCX 文件而设计。它使用一个 .blocks.jsonl 侧车文件 lightrag/chunker/paragraph_semantic.py:1-13。
管线阶段
- 阶段 A(初始切分): 在解析期间执行。文档按标题切分为"内容块"
lightrag/chunker/paragraph_semantic.py:15-17。 - 阶段 B(表格重新切分): 超过
TABLE_MAX_TOKENS的表格在行边界处进行切分(JSON/HTML)。片段被分配角色:first(首部)、middle(中部)或last(尾部),以保持与周围文本的上下文关联lightrag/chunker/paragraph_semantic.py:18-27。 - 阶段 C(长块重新切分): 超过
target_max的块使用"锚点"(短段落,≤ 100 个字符)进行切分。如果没有锚点,则回退到递归字符切分lightrag/chunker/paragraph_semantic.py:28-34。 - 阶段 D(层级合并): 过小的块与相同或更浅标题级别的相邻块合并。最后的"尾部吸收"过程会消除小的尾部片段
lightrag/chunker/paragraph_semantic.py:35-39。
动态阈值
P 策略中的阈值会随用户配置的 chunk_token_size(N)线性缩放 lightrag/chunker/paragraph_semantic.py:58-80:
| 参数 | 比例 | 用途 |
|---|---|---|
target_ideal | 0.75 * N | 合并块的目标大小。 |
table_max | 0.625 * N | 触发表格切分的阈值。 |
table_ideal | 0.375 * N | 表格片段的目标大小。 |
small_tail | 0.125 * N | 最终片段吸收的阈值。 |
自然语言空间到代码实体空间:P 策略
此图将文档结构元素映射到 P 策略中使用的内部类和逻辑。
来源: lightrag/chunker/paragraph_semantic.py:15-39, docs/ParagraphSemanticChunking.md:124-138, lightrag/chunker/paragraph_semantic.py:129-135
策略详情
递归字符切分(R)
使用 LangChain 的 RecursiveCharacterTextSplitter。它会尝试按分隔符列表(默认:["\n\n", "\n", " ", ""])进行切分,直到片段大小符合 chunk_token_size 的要求 lightrag/chunker/recursive_character.py:1-25。它支持 chunk_overlap_token_size 以保持连续性 tests/test_chunking.py:203-210。
语义向量切分(V)
使用嵌入向量相似度来检测主题变化。它计算相邻句子嵌入向量之间的余弦距离。断点由阈值类型决定:percentile(百分位数)、standard_deviation(标准差)、interquartile(四分位距)或 gradient(梯度) lightrag/chunker/semantic_vector.py:1-30。
固定 Token 切分(F)
最简单的策略。它在字符边界处(例如 \n\n)切分文本,但如果单个字符分隔的段落超过限制,则会回退到硬性 Token 计数切分 lightrag/chunker/token_size.py:1-15。
来源: lightrag/chunker/__init__.py:28-43, tests/test_chunk_options_persistence.py:154-162, tests/test_chunking.py:181-200