掌柜智库项目 Day 04|文档切割节点 node_document_split
围绕 node_document_split 节点,梳理目标 chunk 数据结构、节点作用与参数、四大切割原则与项目切割参数,并拆解语义切割的实现步骤。
本篇要点
- 明确入库目标:
list[dict]形式的 chunk 列表与它要携带的字段 - 说清
node_document_split的作用、输入与输出(暂时不含item_name和向量化) - 掌握四大切割原则与项目切割参数
CHUNK_MAX_SIZE / CHUNK_SIZE / CHUNK_OVERLAP / CHUNK_MIN - 拆解步骤一:参数校验与数据清洗
load_markdown_content - 拆解步骤二:按
#标题语义切割split_document
内容回顾
1、上一天主题(Day03)
- 实现了图片处理节点
node_md_img:scan_images取图片上下文 → 视觉模型summarize_images识别 → 上传 MinIO 并替换 md 内容 scan_images会为每张图片生成(图片名, 图片地址, (上文 100 字, 下文 100 字))作为识别上下文- 图片处理后由
变为,图片得以参与内容回答,且客户端任何位置都能访问 - MinIO 侧完成了 docker 部署、可视化操作、桶权限 policy 修改与 Python 增删查,并封装为
MinioGateway - 模型侧封装了
LLMProvider,提供chat(mode_name, json_mode)与vision_chat()
今天内容
1、node_document_split 节点
1.1 存储向量数据库回顾(目标结构)
向量库最终存的是 document -> list[chunk],每个 chunk 是一个 dict:
1 | document -> list[chunk] -> chunk : dict { |
也就是:
1 | list[dict] = {content, title, file_title, parent_title, part} -> chunks -> chunks |
注意: file_title、item_name、稠密与稀疏向量在当前阶段是”拿不到”的,需要在后续节点中补全。
1.2 节点说明
- 作用:获取没有
item_name和向量化的切块列表chunks - 参数:
- 使用:
md_content、file_title、md_path - 响应:
chunks: list[dict],字段为content、title、file_title、parent_title、part
- 使用:
1.3 切割原则和切割参数说明
四大切割原则:
- 保证语义优先
例如 md → 按标题切,表格 → 按 sheet 切,ppt → 按页切 …… - 长度可控(真实开发中要动态调整)
- 考虑嵌入式模型:至多不超过 70%,
bge-m3为8192 token - 考虑重排序模型:
bge-reranker-large为512 - 一些规律指标:
500 - 1200 token之间
- 考虑嵌入式模型:至多不超过 70%,
- 边界清晰、有合理的重叠
- 边界清晰,不能跨域语义
- 在同一个语义下,二次切块的时候应该有合理的 overlap
- 可追溯
除了切块内容,应该携带关键的筛选数据,例如title、file_title、item_name、parent_title、part……
面试题:你的切块是多长?为什么?
答:600。核心原因是根据项目测评系统反复调试,
600时召回率和准确率更高;同时要考虑模型的问题(嵌入式模型、重排序模型的大小),并结合不同文档的切割思路和经验。
项目切割参数:
1 | # 文本切块最大长度:单个文本块最多包含 1000 字符(防止过长导致向量失真) |
整体切割流程:
1 | 根据标题切割 -> 语义 -> 大于 600 -> 递归切割器切割 -> 600 [400 300] |
目标: 600 左右 → 减少碎块(提高召回率)→ 避免过大 1000(提高准确率)。
1.4 步骤分析
4.4.1 参数获取和校验
1 | md_content, file_title = load_markdown_content(state) |
- 获取三个参数
md_content、file_title、md_path md_content非空校验 → 若为空 → 用md_path校验并读取file_title非空校验 → 若为空 → 用md_path校验并取stem→ 取不到则给默认值- 统一换行符号(数据清洗):
md_content中的\n\r、\r→ 统一为\n→ 写回state[md_content] - 返回
md_content、file_title
4.4.2 按照语义切割(#…)
1 | split_document(md_content, file_title) -> list[dict{title, content, file_title}] |
准备数据:
1 | chunks # 结果列表 |
处理流程:
1 | # 对 md_content 进行分行处理 |
后续步骤(留到下一次):
- 4.4.3 进行精细切割:长 → 切短(带 overlap)| 短 → 合并 → 保证边界清晰
- 4.4.4 补充相关属性:
parent_title、part……
注意: 4.4.3 与 4.4.4 属于下一次课的内容,本次只完成到按标题语义切割并产出
chunks。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 𝐺ℎ𝑎𝑜 の 𝐵𝑙𝑜𝑔!
评论
