很多人在用 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 | - | 嵌入模型,创建知识库时设置 |
separator |
string | ### |
父子分段之间的分隔符标识 |
这里我要特别提醒一个容易踩坑的地方:parent_mode 的 full-doc 模式下,max_parent_chunk_length 其实不会生效,父段落就是整篇文档。只有 parent_mode 设为 paragraph,系统才会按段落切分父段落,并用 max_parent_chunk_length 控制每个父段落的长度上限。
2.4 知识库级别的设置与文档级别的设置
还有一个概念容易混淆:知识库创建时的分段设置和单篇文档上传时的分段设置,是两层不同的逻辑。
知识库创建时,你可以设置默认的分段模式、嵌入模型、检索设置。这是“知识库级”的配置,后续上传的文档默认继承这些配置。
单篇文档通过 API 上传时,你可以在请求体里覆盖部分设置,比如 doc_form、doc_metadata 里的父子分段规则。这是“文档级”的配置。
但要注意,文档级的 doc_form 和知识库级的不一致时,可能出现行为不一致。比如知识库是 text_model,你上传文档时强传 hierarchical_model,系统可能会创建成功,但是后续页面上的“分段预览”可能显示异常,或者检索表现不符合预期。我建议保持两者一致:创建知识库时就按项目需求定好 hierarchical_model,然后在文档上传时统一沿用。
3. 实操:把上传文档设置为父子模式
3.1 准备环境与获取 API Key
开始之前,你需要准备好三样东西:
- 一个 Dify 环境(社区版 1.10 及以上版本均可,我测试用的是 1.16 版本)。
- 一个已经创建好的知识库(dataset),并且拿到它的 ID。
- 一个 API Key,在知识库的“API 访问”页面生成。
获取知识库 ID 的方法很简单:进入知识库页面,打开浏览器开发者工具(F12),切到 Network 面板,刷新页面,随便点一个请求,在 URL 里能看到类似 /datasets/1234567890abcdef/documents 这样的路径,中间那串就是 dataset_id。或者更直接一点,通过 API 调用 GET /datasets 也能查到所有知识库的 ID。
API Key 的生成方式:进入知识库页面,点“API 访问”,然后点击“创建密钥”,复制生成的 dataset-xxx 开头的密钥。这个密钥作为请求头 Authorization: Bearer <API_KEY> 传入。
3.2 方式一:通过文件上传接口实现
这是最常用的方式,因为我们日常处理的大多数是 PDF、Word 这类文件。用 curl 的话,请求是这样的:
bash复制curl --location --request POST 'http://<your-dify-host>/v1/datasets/<dataset_id>/documents/create_by_file' \
--header 'Authorization: Bearer <your-api-key>' \
--form 'data={
"name": "产品操作手册",
"indexing_technique": "high_quality",
"doc_form": "hierarchical_model",
"doc_metadata": {
"child_rule": {
"max_child_chunk_length": 256
},
"parent_rule": {
"max_parent_chunk_length": 2000,
"separator": "\\n\\n"
},
"parent_mode": "paragraph",
"child_mode": "custom"
},
"process_rule": {
"mode": "custom",
"rules": {
"pre_processing_rules": [
{"id": "remove_extra_spaces", "enabled": true},
{"id": "remove_urls_emails", "enabled": false}
],
"segmentation": {
"separator": "\\n",
"max_tokens": 512
}
}
}
}' \
--form 'file=@/path/to/your/document.pdf'
有几个细节我得特别说明:
data字段是一个 JSON 字符串,不是 JSON 对象,这是 multipart 表单的要求。indexing_technique必须是high_quality,也就是高质量索引模式(向量索引)。父子模式依赖向量检索,economical(经济模式)不支持父子分段。file字段用@指向本地文件路径,--form会自动处理文件上传。- 如果
process_rule里设置了自定义分段规则,这里的segmentation是文档预处理阶段的分段(切分父段落的规则),不要和doc_metadata里的child_rule混淆。
3.3 方式二:通过文本内容接口实现
如果文档内容在程序里,不想先存成文件,走 create_by_text 接口更合适:
bash复制curl --location --request POST 'http://<your-dify-host>/v1/datasets/<dataset_id>/documents/create_by_text' \
--header 'Authorization: Bearer <your-api-key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "制度文件-2025版",
"text": "第一章 总则\\n第一条 为了规范公司内部管理...",
"indexing_technique": "high_quality",
"doc_form": "hierarchical_model",
"doc_metadata": {
"parent_mode": "paragraph",
"parent_rule": {
"max_parent_chunk_length": 2000,
"separator": "\\n\\n"
},
"child_mode": "custom",
"child_rule": {
"max_child_chunk_length": 256
}
},
"process_rule": {
"mode": "custom",
"rules": {
"pre_processing_rules": [],
"segmentation": {
"separator": "\\n",
"max_tokens": 512
}
}
}
}'
这个接口里,text 字段直接放文档正文内容。需要注意:文本里的换行符 \n 在 JSON 里要写成 \\n,不然传输过程中换行符就可能丢失,导致分段规则里的 separator 匹配不上,整个文档变成一个超级大段落,父子分段就形同虚设。
3.4 用 Python 脚本封装批量上传
在实际项目中,往往不是只传一两篇文档,而是要批量上传。我一般用 Python 配合 requests 库封装一个函数,方便复用:
python复制import requests
import json
def upload_document_as_parent_child(
base_url: str,
api_key: str,
dataset_id: str,
file_path: str,
doc_name: str,
max_parent_length: int = 2000,
max_child_length: int = 256
):
url = f"{base_url}/v1/datasets/{dataset_id}/documents/create_by_file"
headers = {
"Authorization": f"Bearer {api_key}"
}
data = {
"name": doc_name,
"indexing_technique": "high_quality",
"doc_form": "hierarchical_model",
"doc_metadata": {
"parent_mode": "paragraph",
"parent_rule": {
"max_parent_chunk_length": max_parent_length,
"separator": "\\n\\n"
},
"child_mode": "custom",
"child_rule": {
"max_child_chunk_length": max_child_length,
"separator": "\\n"
}
},
"process_rule": {
"mode": "custom",
"rules": {
"pre_processing_rules": [],
"segmentation": {
"separator": "\\n",
"max_tokens": max_parent_length
}
}
}
}
with open(file_path, "rb") as f:
files = {
"data": (None, json.dumps(data), "application/json"),
"file": (file_path, f, "application/octet-stream")
}
resp = requests.post(url, headers=headers, files=files)
if resp.status_code == 200 or resp.status_code == 201:
return resp.json()
else:
raise RuntimeError(f"Upload failed: {resp.status_code} {resp.text}")
if __name__ == "__main__":
result = upload_document_as_parent_child(
base_url="http://localhost",
api_key="dataset-xxx",
dataset_id="your-dataset-id",
file_path="./docs/manual.pdf",
doc_name="操作手册_v2"
)
print(result)
这里有个细节是整个批量上传最容易出问题的地方:requests 库的 files 参数里,data 字段要用 json.dumps(data) 转成字符串,同时显式声明 Content-Type 为 application/json,不然 Dify 后端解析 multipart 表单时可能把 data 当成普通字符串,导致请求体解析失败。
3.5 如何确认文档真的进入了父子模式
上传成功后,怎么确认 Dify 真的按父子模式处理了这篇文档?有几种验证方式:
-
查看文档详情:调用
GET /datasets/{dataset_id}/documents/{document_id},返回体里的doc_form字段会标明是hierarchical_model还是text_model。注意,在 Dify 的某些版本里,这个字段可能叫doc_form也可能在segment相关数据中体现,具体以你的版本返回字段为准。 -
查看分段列表:调用
GET /datasets/{dataset_id}/segments?document_id={document_id},返回的分段数据里,父子模式的子分段会在父子关系统计上体现,一般在知识库界面可以看到“N 个父段落 / M 个子分段”这种结构。 -
界面验证:进入知识库“文档”页面,点击文档名进入详情,在“分段”页签下,切片列表里如果能看到父子层级的展示,说明设置成功。
我用的是 1.16 社区版,界面上父子模式的分段列表会显示父段落的分隔线,子分段以缩进方式展示,一眼就能识别出来。
4. 父子模式参数调优:我踩过的几个坑
4.1 max_child_chunk_length 不是越大越好
子分段要负责“精准检索”,所以它的长度控制很关键。如果子分段太长,语义就复杂了,检索时容易和其他内容混淆;如果太短,子分段就变成了无意义的关键词碎片,向量化后丢失上下文信息。
我实测下来,中文场景下子分段 200~300 是甜点区间。Dify 的 token 计算方式对不同模型有差异,我用的是 OpenAI 的 text-embedding-3-small,256 是比较稳妥的值。如果你的知识库主要吃英文内容,可以适当放宽到 400 左右,因为英文的 token 密度比中文高。
4.2 max_parent_chunk_length 影响“上下文完整度”
父段落的长度决定了最终给大模型的上下文有多完整。设太短,父段落也切得碎,那父子模式的优势就没了;设太长,一个父段落几千 token,检索结果可能输出超出模型上下文窗口,或者大模型被大量无关信息干扰。
我的经验是:父段落设置为子段落长度的 5~8 倍比较合理。子分段 256,父分段 1280~2048。如果你的文档本身段落意识很强,比如合同条款、论文摘要,可以把父段落进一步缩短到 1000 左右,让每个父段落语义更聚焦。
4.3 分隔符 separator 的优先级
doc_metadata.parent_rule.separator 这个参数控制父段落的切分标识。Dify 在切分父段落时,如果文档里有 separator 指定的分隔符,会优先按分隔符切分;如果没有找到分隔符,再按 max_parent_chunk_length 硬切。
所以分隔符的选择直接决定你的分段质量。我测试过两种常见配置:
"separator": "\\n\\n":按空行切分,适合段落结构清晰的 Markdown、富文本文档。"separator": "\\n":按换行切分,适合每行就是一个逻辑单元的文档,比如代码文件、配置清单。
如果你不确定文档的分隔符是什么,先 cat 或者用 Python 读一下文档内容,看看实际的分隔符长什么样,再决定配置。别想当然。我曾经把一篇 PDF 转出来的文本直接用 \n\n 切分,结果发现 PDF 转出来的文本全是单换行 \n,导致 \n\n 压根匹配不上,整篇文档变成几个巨型段落,检索效果惨不忍睹。
4.4 嵌入模型的选择影响分段效果
父子分段模式下,子分段做向量化时用的嵌入模型也要选好。Dify 支持多种嵌入模型,不同模型的向量维度、语义理解能力差异很大,直接决定“父子分段”是否真的比“固定分段”效果更好。
我对比过 text-embedding-3-small 和 text-embedding-3-large,在长文档知识库场景下,large 的检索准确率明显更高,但向量化耗时也高,成本也翻倍。如果你的知识库文档量在几千篇以内,优先用 large;如果超过几万篇,考虑成本和性能平衡,用 small 或者国产嵌入模型(比如 BGE 系列)也是可行方案。
4.5 process_rule.segmentation.max_tokens 和 parent_rule 的关系
这个点非常容易踩坑。很多人在 API 请求里把 process_rule.segmentation.max_tokens 设成了子分段的长度,结果文档切出来的效果不是预期的父子结构。
我解释一下这两个参数的分工:
process_rule.segmentation属于文档预处理的“粗分段”规则,决定了文档切割成最原始的块时用什么策略。在父子模式下,它是切分父段落的基础规则。doc_metadata.parent_rule是父子分段规则,决定了父段落如何进一步组织成父-子两级结构。
换句话说,process_rule.segmentation.max_tokens 是“一把粗剪”,doc_metadata.parent_rule.max_parent_chunk_length 是“精细雕刻”。如果 process_rule.segmentation.max_tokens 设得比 parent_rule.max_parent_chunk_length 还小,那么文档会被切得比父段落还碎,父段落就失去意义了。
实际推荐做法:process_rule.segmentation.max_tokens 设置成和 parent_rule.max_parent_chunk_length 相同,或者略大一些(1.2 倍左右),让父段落有足够空间。
5. 常见问题与排查技巧实录
5.1 上传成功但文档显示“处理失败”
这个问题的主要表现是:API 返回了上传成功,但知识库文档列表里,这篇文档的状态一直是“处理失败”或者“索引中”卡住不动。
排查思路:
- 先看 Dify 容器日志,执行
docker logs <dify-api容器名>查看报错信息。最常见的是嵌入模型调用失败,API Key 无权限或额度不足。 - 检查
indexing_technique是否传了high_quality。如果误传economical,父子模式不生效,部分版本甚至会直接处理失败。 - 检查文档格式。某些扫描版 PDF 没有任何文本层,Dify 的文档解析器提取不到内容,处理自然失败。这种文档需要先用 OCR 工具或其他工具转成可复制的文本。
5.2 父子模式没有按预期生效
如果你确认 API 上传成功、文档状态正常,但检索效果和固定分段没区别,大概率是 doc_form 没有真正传进去。
我记得有一次排查一个线上问题,知识库在页面里明明选了父子模式,但通过 API 批量上传的文档全部变成了 fixed 分段。后来我抓包检查,发现是我在 Python 脚本里把 doc_form 拼进了嵌套的 data 结构里,导致 multipart 表单的 data 字段解析后没有 doc_form 键。Dify 的 API 对缺失的 doc_form 不会报错,因为后面文档级处理逻辑里,缺少这个字段就默认走知识库级配置,而知识库级配置恰好是 fixed 的分段模式,所以表现就是“好像没生效”。
另一个原因:文档解析后的内容长度小于父子模式的最小分段要求,比如一篇文档只有几十个 token,Dify 可能不会把它拆成父子结构,直接按单块处理。这种情况不用太纠结,因为这么短的文档用父子模式也没意义。
5.3 检索时父子上下文没有一起返回
正常父子模式的行为是:命中子分段时,系统应该同时返回父分段。但如果你配置了父子模式,却只看到子分段的内容,没有父段落,问题可能出在 Dify 版本上。
社区版的父子模式能力不同版本差异很大。我最初用的是 1.10 版本,父子分段功能还很基础,检索 API 返回的 segment 里没有明显区分父段落和子段落。升级到 1.16 之后,API 返回内容里才明确区分了两个层级。所以如果你的 Dify 版本比较旧,建议先升级到 1.14 以上再排查这个问题。
提示:Dify 社区版 1.10 之后多租户、知识库流水线等 feature 都有更新,但父子模式的检索能力优化主要集中在中后期版本,有条件的话保持版本在 1.14 以上能少踩很多坑。
5.4 分段预览和实际效果不一致
在知识库界面预览分段时,看到的分段规则和 API 请求里的不太一样?这是正常的。因为界面预览显示的是知识库默认的分段规则,而 API 上传时覆盖了文档级的分段规则。Dify 的界面不会主动展示每篇文档内部的覆盖参数,只有在“分段”页签下才能看到文档实际的分段结果。
所以不要拿“界面预览的分段数量”去验证 API 上传是否成功,直接看文档详情里的分段列表最靠谱。
5.5 批量上传慢,如何处理
大批量上传时,Dify 对每篇文档都要做解析、切分、向量化三步操作,尤其是向量化阶段,调用嵌入模型接口有网络延迟,几百篇文档可能要跑几十分钟。
我的处理方式是:
- 控制并发:不要在脚本里开 100 个线程同时打 API,Dify 容器性能和嵌入模型 API 限流都可能扛不住。一般控制在 3~5 个并发比较稳。
- 分批上传:每批 50 篇左右,批次之间间隔几秒。
- 异步索引:如果 Dify 版本支持异步索引(新版有这个能力),可以先只上传文档元数据,返回后再异步处理索引。这样上传接口响应很快,但要注意后续轮询文档索引状态。
python复制import time
from concurrent.futures import ThreadPoolExecutor, as_completed
def batch_upload(doc_list, max_workers=4):
results = []
with ThreadPoolExecutor(max_workers=max_workers) as executor:
future_map = {executor.submit(upload_document_as_parent_child, **doc): doc for doc in doc_list}
for future in as_completed(future_map):
try:
result = future.result()
results.append(result)
except Exception as e:
print(f"Upload failed: {future_map[future]['name']}, error: {e}")
time.sleep(0.5)
return results
5.6 API 鉴权失败或返回 401
检查 API Key 是否以 Bearer 方式传入,以及知识库 ID 是否属于这个 API Key 对应的知识库。在 Dify 的“API 访问”页面,每个知识库的 API Key 是独立的,不能跨知识库使用。我用过一个项目的 Key 去访问另一个项目的知识库,调试了半天才发现是 Key 用错了。
6. 补充几个实战技巧
6.1 通过 API 统一设置模板,提高团队复用度
如果团队里有多个人都要上传文档,建议把父子分段的参数做成一份 JSON 模板,统一维护:
json复制{
"doc_form": "hierarchical_model",
"doc_metadata": {
"parent_mode": "paragraph",
"parent_rule": {
"max_parent_chunk_length": 1600,
"separator": "\\n\\n"
},
"child_mode": "custom",
"child_rule": {
"max_child_chunk_length": 256,
"separator": "\\n"
}
},
"process_rule": {
"mode": "custom",
"rules": {
"pre_processing_rules": [
{"id": "remove_extra_spaces", "enabled": true},
{"id": "remove_urls_emails", "enabled": false}
],
"segmentation": {
"separator": "\\n",
"max_tokens": 1600
}
}
}
}
这个模板的意思很明确:文档先按换行分块,父段落块的上限是 1600 token,子分段 256 token,父子段落之间用 \n\n 分隔。日常使用中,我一般先拿一两篇代表性文档跑一下,看分段结果,再微调参数,确定后固化下来。
6.2 多模态文件的处理注意事项
Dify 对 PDF、DOCX、Markdown、HTML 等格式的解析能力不同。PDF 的排版信息(表格、多栏)转换后往往丢失结构,父子模式的段落识别会更困难。
建议在上传前先做预处理:把 PDF 转成 Markdown 或者纯文本格式。我常用的工具是 pypdf、pdfplumber 或者把 PDF 通过 Dify 自带的解析服务处理。如果你觉得转换结果不理想,也可以先用 Dify 界面手动上传一篇,观察分段效果,再决定是否用 API 批量处理。
6.3 如何用 API 更新已上传文档的分段模式
这是一个很常见的需求:文档已经传上去了,发现当时用的固定分段,想改成父子模式,怎么办?
说实话,Dify 目前没有提供“直接修改已有文档分段模式”的 API。doc_form 只在上传文档时生效,文档处理完成后不能动态修改。你想实现这个需求,只能删掉旧文档,用新的 doc_form 参数重新上传。
删除文档的接口是 DELETE /datasets/{dataset_id}/documents/{document_id},删除后重新走上传流程。如果你要处理多篇旧文档,建议写个脚本批量识别旧文档 ID,然后统一重新上传。
6.4 检索时如何指定检索策略
关于检索设置也提一句:Dify 知识库的检索设置里,有“向量检索”、“全文检索”、“混合检索”三种策略,父子分段模式一般配合“混合检索”效果最好。因为混合检索既走向量相似度,又走全文关键词匹配,对长文档知识库里的专业术语、人名、编号类问题补充效果非常明显。
通过 API 上传文档时,你不需要关注检索策略,检索策略在知识库设置里配。但如果你想在应用侧精细化控制检索方式,可以在工作流或应用的知识库节点里设置 retrieval_mode 参数。
7. 最后一次验证:从 API 到应用联调
配置好父子分段,文档索引完成后,最后一步是在应用里验证检索效果。我一般这样操作:
- 在工作流或聊天应用里添加知识库节点,选择刚才配置好的知识库。
- 设置检索模式为“混合检索”,
rerank开启并用合适的 Rerank 模型(比如rerank-v3.5),可以进一步提升父子分段召回后的排序质量。 - 用几个针对长上下文的问题测试,比如:
- 文档里跨章节才能回答的问题——“如果设备在零下 20 度环境下无法启动,应该参考哪个章节的故障排除步骤?”
- 需要精确定位的问题——“签署合同后几天内需要交付首付款?”
- 观察知识库节点返回的内容:如果命中的是子分段,但同时附带了父段落上下文,说明链路已经通了。
从上传文档、设置父子分段、创建索引到应用侧验证,整个链路走通后,知识库的检索质量会有一个可感知的提升。尤其那种“懂一点但经常记不全”的回答,在父子模式下改善非常明显。
我个人的体会是,Dify 的父子分段模式是一个性价比极高的功能,不用改模型、不用加提示词,只靠数据组织方式的调整就能让知识问答效果上一个大台阶。但这个功能的价值完全取决于你愿不愿意花时间理解分段参数、跑测试、调细节。用 API 的方式操作,一旦把参数模板固化下来,批量处理文档的效率远比界面手动配置高得多。希望这篇内容能帮你少走弯路,把知识库的底座打牢。
