![[Bug]: Stopword removal is ineffective in `SemanticDoubleMergingSplitterNodeParser`](https://www.chat-gpts.plus/wp-content/uploads/2026/07/22166-88c4a5ce.jpg)
[Bug]: Stopword removal is ineffective in `SemanticDoubleMergingSplitterNodeParser`
快速结论:在 LlamaIndex 使用 SemanticDoubleMergingSplitterNodeParser 并启用了 SpaCy 后端的停用词过滤功能时,_clean_text_advanced 方法因分词逻辑错误导致停用词无法被移除。优先排查是否使用了默认的 punkt_tokenizer 进行单词级分词。
问题场景
用户在 LlamaIndex 0.14.23 版本中,使用 SemanticDoubleMergingSplitterNodeParser 文本分割器,期望通过 _clean_text_advanced 方法去除停用词,但发现停用词(如 “this”, “is”, “a”, “the”, “and”)完全没有被过滤。
报错原文
# 运行测试脚本后,原始文本与清洗后文本完全一致,停用词未被移除
# Expected: "test text containing stopwords like" (stopwords removed)
# Actual : "this is a test text containing some stopwords like the and a" (no change)
# 核心判断逻辑:
# tokens = globals_helper.punkt_tokenizer.tokenize(text)
# 由于标点符号预先被移除,句子分词器将整个文本当作一个句子返回,导致停用词检查失效。
原因分析
可能原因:在 _clean_text_advanced 方法中,代码先使用 text.translate(str.maketrans("", "", string.punctuation)) 移除所有标点符号,然后使用 globals_helper.punkt_tokenizer(NLTK 的 Punkt 句子分词器)对文本进行分词。由于标点符号已被全部移除,Punkt 分词器失去了句子边界的判断依据,将整个文本块视为一个单一的“句子”。因此,停用词检查 w not in self.language_config.stopwords 是在整个文本字符串(而非单个单词)上进行的,导致单个停用词永远不会被过滤。
环境排查
- LlamaIndex 版本(已知问题影响 0.14.23)
SemanticDoubleMergingSplitterNodeParser实例化时的参数(明确使用 SpaCy 后端)- 停用词列表
self.language_config.stopwords内容 globals_helper.punkt_tokenizer的实际类型(应确认是句子分词器)
解决步骤
- 确认问题:运行 Issue 中提供的测试脚本,查看清洗后的文本是否与原始文本一致(停用词未被移除)。
- 定位代码:检查
llama-index-core/llama_index/core/node_parser/text/semantic_double_merging_splitter.py中的_clean_text_advanced方法(约第388-398行)。 - 修正分词逻辑:将句子分词替换为单词级别分词。可优先尝试以下修复方式:
# 原错误逻辑 tokens = globals_helper.punkt_tokenizer.tokenize(text) # 建议修复:使用 str.split() 进行单词分词(标点符号已移除且文本已小写化) tokens = text.split() filtered_words = [w for w in tokens if w not in self.language_config.stopwords]修改后,重新运行测试脚本确认停用词被正确移除。
- 注意:此修复方案为基于 Issue 讨论的建议,尚未经过官方合入确认。如无官方修复版本,可自行在源码中应用上述变更。
验证方法
运行 Issue 中提供的 Python 测试脚本。如果修复成功,cleaned_text 应输出 "test text containing stopwords like" 而非原始文本,且 assert 语句不会抛出 AssertionError。


![[BUG] CrewAI 1.4.1 hangs after successful kickoff_for_each() crew execution and never terminates](https://www.chat-gpts.plus/wp-content/uploads/2026/07/3871-4af0404f-768x403.jpg)
