快速结论:在 Dify 自托管源码环境中使用文本分段(如知识库文档处理)时,若把非 ASCII 字符(中文句号「。」、重音字符、emoji 等)设为固定分隔符,分隔符会被 codec 错误解码成乱码,导致固定分隔符分段失效。优先排查分隔符的编码处理逻辑,而非分段参数本身。
适用环境:Dify 1.18.0(当前 main,commit 741699a0);Self Hosted(源码部署)。Issue 未提供操作系统、Python、CUDA、显卡等环境信息。
最快修复方案:暂无确认的一步修复方案。Issue 已定位到 FixedRecursiveCharacterTextSplitter.__init__ 中对分隔符无条件执行 unicode_escape 解码的问题,但讨论链中未给出已验证的修复代码或补丁版本。
注意事项:该缺陷只影响固定分隔符那一轮分段,不代表分段全部失效——超过 chunk_size 的文本仍会走递归回退逻辑,而回退的分隔符列表中含未修改的「。」,所以较长文档可能掩盖此问题。修复时不能简单地“遇到非 ASCII 就跳过解码”,否则混有转义序列的分隔符(如 Unicode 字符与 \n\n 混用)中的转义部分将无法解码。
问题场景
在 Dify 自托管(源码部署)环境中处理文档分段时,通过 FixedRecursiveCharacterTextSplitter 指定固定分隔符进行切分。当固定分隔符为非 ASCII 字符时(例如类默认分隔符之一「。」),split_text() 无法按该分隔符切分,短文档原样返回为单个 chunk,且没有任何警告。
报错原文
Bug: FixedRecursiveCharacterTextSplitter corrupts non-ASCII separators via unicode_escape decoding
>>> import codecs
>>> codecs.decode("。", "unicode_escape")
'ã\x80\x82'
sp = FixedRecursiveCharacterTextSplitter(fixed_separator="。", chunk_size=50, chunk_overlap=5)
sp.split_text("这是第一句。这是第二句。这是第三句。")
# ['这是第一句。这是第二句。这是第三句。'] -> 1 chunk, nothing split
原因分析
最可能的原因是构造函数对用户传入的固定分隔符无条件执行了以下解码:
self._fixed_separator = codecs.decode(fixed_separator, "unicode_escape")
该设计的目的是把 UI 中输入的字面量 \n\n 转成真正的换行符,但 unicode_escape 会把输入当作 latin-1 字节流解释,因此所有非 ASCII 字符都会被破坏成乱码(如「。」变成 ã\x80\x82)。乱码分隔符永远不会与原文匹配,导致固定分隔符这一轮切分静默失效。
需要注意的范围边界:这只是破坏了固定分隔符那一轮切分,并没有关闭全部切分。超过 chunk_size 的未匹配文本仍会进入递归回退逻辑,而回退使用的分隔符列表中含未修改的「。」,因此较长文档仍可能被切分,从而掩盖该缺陷;示例中的短文本低于阈值,回退从未触发,所以整体只返回一个 chunk。
环境排查
- 确认 Dify 版本是否为 1.18.0 或当前 main(commit 741699a0),以及是否属于 Self Hosted(源码)部署。
- 确认出问题的分段组件是否为
core/rag/splitter/fixed_text_splitter.py中的FixedRecursiveCharacterTextSplitter。 - 确认传入的
fixed_separator是否为非 ASCII 字符(CJK、带重音字母、emoji 等)。 - 确认测试文本长度是否低于
chunk_size,以排除递归回退逻辑掩盖问题的影响。 - Issue 未提供 Python、CUDA、PyTorch、显卡、依赖版本等信息,无需据此判断。
解决步骤
- 在出现问题的环境中复现:以
fixed_separator="。"、较小的chunk_size切分一段短中文文本,确认返回为单个 chunk,与 Issue 现象一致。 - 检查分隔符解码点:定位
FixedRecursiveCharacterTextSplitter.__init__中的codecs.decode(fixed_separator, "unicode_escape"),确认非 ASCII 分隔符是否经此处理后变成乱码(可直接用codecs.decode("。", "unicode_escape")对比结果)。 - 在修复前规避:可优先尝试改用 ASCII 分隔符进行固定切分,或依赖递归回退逻辑处理较长的非英语文本,避免固定分隔符这一轮被破坏。
- 若需自行打补丁:可优先尝试让解码逻辑区分 ASCII 与带转义序列的输入,既保留 Unicode 字符原样,又对嵌入的
\n\n等转义进行处理;注意不要让“遇到非 ASCII 就跳过解码”的写法,导致混合分隔符中的转义部分漏解码。 - 修复后补充回归测试:保留低于
chunk_size阈值的短文本用例并断言精确的预期分块,而不是只检查最大 chunk 长度;同时覆盖字面量重音/emoji 分隔符、字面量\n\n,以及 Unicode 与转义序列混用的分隔符。
验证方法
对低于 chunk_size 的短文本使用 fixed_separator="。" 切分,应返回按句号分隔的多个 chunk(而不是单个整体 chunk),且分块内容与预期完全一致;同时确认 fixed_separator="\\n\\n" 仍按两个换行符正常切分,非 ASCII 分隔符未被转成乱码。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


