很多人在用 Dify 搭建知识库应用时,最容易忽略的一个细节就是分段模式。默认情况下,上传文档后系统会用“固定分段”切分文本,检索时直接拿分片去匹配向量,再把命中的分片丢给大模型。这套方案在小文档、短文本场景下还算够用,一旦遇到长文档——比如产品手册、论文、合同、操作指南——问题就出来了:匹配到的分片内容太碎,上下文不连贯,大模型读着读着就跑偏了。
Dify 的知识库其实还内置了“父子分段模式”,子分段负责精准检索,父分段负责提供完整上下文,两者配合起来效果明显更好。但坑在于,社区版界面里创建知识库时选了“父子模式”之后,上传单个文档时通过 API 怎么指定父子分段参数,很多教程都没写清楚。这篇文章就围绕这个需求,完整拆解一下怎么通过 Dify 知识库 API 把上传文档的分段模式设置成父子模式,包括接口设计原理、参数含义、实际调用示例和踩坑记录,适合正在用 Dify 做知识库、想提升检索质量、又不想被界面操作限制的开发者和实施人员参考。
1. 先搞懂“父子模式”到底解决什么问题
1.1 固定分段模式的短板
在配置 API 之前,得先把父子分段的原理理解透,否则参数设置就是瞎填。Dify 的固定分段模式(Fixed Segment)逻辑很简单:文档上传后,按固定字符数(默认 500 个 token,可以自己改)把文本切成若干块,每块作为一个独立单元做向量化。检索时,系统算每个块和用户问题的相似度,返回最相近的 N 个块。
这个流程有两个很现实的毛病。第一,分块边界不按语义走,经常把一句话、一个表格、一段逻辑切得七零八落——比如一段讲“如何配置环境变量”的内容,可能被切成两块,一块讲“如何配置环境”,一块讲“变量”,检索时谁都不完整。第二,大模型拿到的上下文太窄,固定分段模式下,命中的块只有几百 token,如果问题需要跨段落理解,模型只能靠猜。
1.2 父子分段模式的工作机制
父子分段(Parent-Child Chunking)的思路是:让“小分块”负责检索,“大分块”负责理解。
具体来说,文档上传后,系统会先把文档切成较大的“父段落”(Parent Chunk),每个父段落再切成若干较小的“子分段”(Child Chunk)。向量索引只建立在子分段上,检索时命中的是子分段;但把结果返回给大模型时,Dify 会把命中子分段对应的父分段一起拿出来,作为完整上下文提交给模型。这样既保证了检索的精准度——子分段语义单一,向量匹配更准;又保证了大模型的上下文完整性——父分段保留了完整的逻辑结构。
我举个例子你就明白了。假设文档里有这样一段话:
系统升级前,请先备份数据库。备份命令为 mysqldump -u root -p mydb > backup.sql。备份完成后,再执行 upgrade.sh 脚本完成升级,升级期间服务会短暂不可用。
在固定分段模式下,这段话可能被切到两个块里,用户问“升级前要做什么”,系统可能只命中“备份命令为 mysqldump..."这个块,模型以为用户只需要备份命令,完全不知道升级期间服务不可用这回事。在父子模式下,这段话整体是父段落,内部按语义切成子分段,用户问“升级前要做什么”时,命中了“升级前请先备份数据库”这个子分段,返回给模型时,系统把整个父段落都带上,模型就能完整回答升级前、升级中、升级后的注意事项。
1.3 父子模式的适用场景
不是所有文档都适合父子模式。我做过的项目里,适合用父子模式的场景有这些:
- 产品使用手册、操作指南:这类文档逻辑层层嵌套,“注意事项”“操作步骤”经常跨段,父子模式能保住上下文。
- 合同、法律条文:条款之间有引用关系,单独看一条容易断章取义,父段落刚好能保留条款全貌。
- 技术文档、API 文档:说明文字和代码示例经常交替出现,固定分段会把代码和说明拆散。
- 学术论文、研究报告:段落长、术语多,父子模式对长尾提问的容错更高。
反过来,如果你的文档很短(比如每条内容就一两句话的问答对),父子模式反而没必要,固定分段就够用,还能省一点存储和检索开销。所以选哪种模式,本质上是“检索准确率”和“上下文完整性”之间做权衡。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动手前需要理解的知识库 API 与数据结构
2.1 和分段模式相关的核心字段
Dify 的知识库 API 里,和分段模式强相关的是 doc_form 这个字段。这个字段在创建知识库时就会确定,取值有两个:
text_model:对应界面里的“通用”分段模式,也就是固定分段。hierarchical_model:对应界面里的“父子”分段模式。
你通过 API 上传文档时,可以在请求体里带 doc_form 字段,指定这篇文档走哪种分段模式。如果你用的是 hierarchical_model,还可以额外传 doc_metadata 字段,里面放父子分段的详细参数。
这里有个关键点:doc_form 不是在每次上传文档时临时决定的,它在创建知识库时被设定为默认值。 如果你在知识库创建时选择了 hierarchical_model,那么后续通过 API 上传文档时,即使不传 doc_form,系统也会默认用父子模式处理。如果知识库是 text_model,你上传文档时传了 hierarchical_model,Dify 会根据请求体里的参数覆盖默认值,但有一些参数和行为可能会受到知识库级别的限制,这块后面会细说。
2.2 上传文档的两个 API 入口
Dify 知识库支持两种方式上传文档:
- 文本内容直接创建:
POST /datasets/{dataset_id}/documents/create_by_text,直接把文本内容放在请求体里,适合程序自动生成的文本、爬虫抓取的内容。 - 文件上传:
POST /datasets/{dataset_id}/documents/create_by_file,表单形式上传文件,适合 PDF、Word、Markdown 等文件类型的文档。
两种方式都支持 doc_form 参数,但参数位置不一样。create_by_text 的 doc_form 是 JSON 请求体的一个字段;create_by_file 的 doc_form 是表单的一个字段。
2.3 父子模式的分段参数有哪些
当 doc_form 设置为 hierarchical_model 后,你可以在 doc_metadata 里配置父子分段的规则。Dify 目前支持的父子分段参数主要是这几个:
| 参数名 | 类型 | 默认值 | 含义 |
|---|---|---|---|
parent_mode |
string | full-doc |
父分段的切分方式,目前主要是 full-doc(整个文档作为一个父段落)和 paragraph(按段落切分父段落) |
parent_rule |
object | - | 父分段的规则配置,包含 max_parent_chunk_length(父段落的最大长度)等 |
child_mode |
string | custom |
子分段的切分方式,通常为 custom |
child_rule |
object | - | 子分段的规则配置,包含 max_child_chunk_length(子分段的最大长度)等 |
embedding_model |
string | - | 嵌入模型,创建知识库时设置 |
| `separ |
