Appearance
3.2.4 长文档、FAQ、表格、代码文档的切块策略有什么不同?
先给结论:不同类型数据的知识边界不同,所以切块策略也不应该统一。
如果你把长文档、FAQ、表格、代码文档都按同一种方式切,系统通常很快就会暴露边界问题。
为什么不同文档类型必须区别对待
因为它们真正承载语义的方式不一样。
有的主要靠:
- 段落和小节
有的主要靠:
- 问答对
有的主要靠:
- 行列关系
有的主要靠:
- 文件、函数、调用上下文
所以切块时真正应该优先保留的“知识边界”,本来就不一样。
长文档更适合怎么切
长文档最常见的问题是:
- 主题多
- 层级深
- 一个问题往往只命中其中一小节
所以长文档切块时,通常更应该优先保留:
- 标题层级
- 小节边界
- 段落完整性
更稳的思路通常是:
- 先按章节或小节切
- 再在过长的小节内部继续细分
- 必要时再补适量 overlap
长文档最怕的不是“切得不够碎”,而是“切完以后失去了章节结构”。
FAQ 更适合怎么切
FAQ 的知识边界通常非常明确:一问一答本身就是天然 chunk。
所以 FAQ 更适合优先按:
- 单个问答对
- 题目 + 答案
来切。
这类内容最不适合的,反而往往是粗暴按固定长度切。因为那样很容易把:
- 问题和答案拆开
- 一个完整 FAQ 拆成几块
- 多个问答混在一起
FAQ 切块时,最重要的不是 token 均匀,而是“一个问答对尽量完整”。
表格更适合怎么切
表格最麻烦,因为它的语义通常不只在单元格文本里,而在:
- 表头
- 行列关系
- 单位
- 统计口径
所以表格通常不太适合直接按普通段落切块。
更现实的做法往往是:
- 先恢复结构
- 再决定是按表、按行、按区域切
- 或者干脆不走普通文本检索,而改成结构化查询
如果表格已经很规则、问题也主要围绕单行记录,那可以考虑按行或按记录组织。
如果表格更像统计表或复杂汇总表,很多时候更应该先做结构化抽取,而不是直接按文本切。
代码文档更适合怎么切
代码文档和普通文档最大的不同,是它更依赖上下文关系。
比如一段说明文是否有意义,往往要结合:
- 它对应哪个文件
- 它描述哪个函数或模块
- 它和 README、配置、接口文档是什么关系
所以代码文档切块时,通常更适合优先保留:
- 文件边界
- 函数或类边界
- 注释与代码的对应关系
- 路径和模块信息
如果只是把代码和文档都按固定长度切开,最容易出现的问题就是:
- 函数签名和解释分开
- 配置说明和配置项分开
- 同一个模块的前后文丢失
一个更直观的对比
可以先粗略记成这样:
- 长文档:优先保留章节和段落边界
- FAQ:优先保留单个问答对完整性
- 表格:优先保留表头、行列关系和结构语义
- 代码文档:优先保留文件、函数、模块和说明之间的关系
这就是它们最核心的差别。
一个最小示意
python
chunking_strategy = {
"long_doc": "按标题和小节切,过长再细分",
"faq": "按单个问答对切",
"table": "先恢复结构,再按表或记录处理",
"code_doc": "按文件、函数、类或模块边界切",
}这个示意虽然简单,但它体现了一个非常重要的原则:
切块策略首先是“文档类型判断”,然后才是“参数调节”。
最常见的误区
1. 用一套 splitter 处理所有数据
这通常是最省事的做法,但也往往是最早暴露边界问题的做法。
2. 只看字符数,不看知识边界
字符数只是一种实现手段,不是知识边界本身。
3. 把表格和代码文档也当普通自然语言处理
这些内容往往最依赖结构关系,硬按普通段落切,后面很容易失真。
一句话总结
长文档、FAQ、表格、代码文档的切块策略不同,本质上不是因为它们格式不同,而是因为它们真正承载语义的边界不同。切块时最应该优先保留的,不是统一长度,而是这些数据原本最重要的知识边界。