[Bug]: rag/res/term.freq is loaded by term_weight but not shipped — every lowercase Latin token gets the same IDF

当你在 RAGFlow 中启用权重计算(term_weight)并处理英文、葡萄牙语、西班牙语、法语等拉丁字母语言时,启动日志出现 Load term.freq FAIL! ,且检索排序出现“停用词和内容词权重几乎相同”的异常,优先排查 rag/res/term.freq 是否存在、你的 RAGFl

快速结论:当你在 RAGFlow 中启用权重计算(term_weight)并处理英文、葡萄牙语、西班牙语、法语等拉丁字母语言时,启动日志出现 Load term.freq FAIL!,且检索排序出现“停用词和内容词权重几乎相同”的异常,优先排查 rag/res/term.freq 是否存在、你的 RAGFlow 版本是否低于 v0.27.1。

适用环境:Issue 中确认的信息为:RAGFlow v0.26.4 可复现;受影响代码路径包括 Python 的 rag/nlp/term_weight.py 与 Go 的 internal/service/nlp/term_weight.go;修复出现在 v0.27.1 与 v0.27.2(v0.27.0 尚未包含该修复)。Issue 未提供操作系统、Python、CUDA、显卡或依赖版本信息。

最快修复方案:升级到 v0.27.1 或 v0.27.2。该版本合入了 #18470,rag/nlp/term_weight.pydf() 在显式字典与 tokenizer 词频都未命中时,会先调用 _alphabetic_oov_frequency() 进行有界 OOV 估算,而不是直接回落到常量 3

注意事项:升级后 rag/res/term.freq 仍然不会随包发布,Issue 未提供该词典资源;修复只是替换了缺失文件时的退化逻辑,因此它不是“加载到词典”的方案。另外 Load term.freq FAIL! 日志本身在修复后可能仍会出现,判断修复是否生效应基于排序结果而非该告警是否消失。

问题场景

用户运行 RAGFlow,使用其中的 term_weight 组件对全文查询做词项权重计算(term^weight 形式的 per-term boost),或使用记忆搜索(memory search)与数据集检索(dataset retrieval)时触发该问题。典型场景是查询英文或多语言拉丁字母文本,例如 what was the largest supplier of hospital equipment in Salvador,结果中停用词与内容词权重无法区分。

报错原文

[Bug]: rag/res/term.freq is loaded by term_weight but not shipped — every lowercase Latin token gets the same IDF
Load term.freq FAIL!

原因分析

最可能的原因是:rag/nlp/term_weight.py__init__ 中尝试加载 rag/res/term.freq 以构建 document-frequency 表,但该文件并未包含在仓库中,构建过程也不会生成它。于是加载始终失败,self.df 保持为空。

df() 回退逻辑中,凡是命中 letter_pattern 的小写拉丁字母 token 都会返回 300,导致承载 70% 权重的 idf2 退化为常量;而 freq() 对 tokenizer trie 中未收录的 token 使用同样的 return 300 回退,因此 idf1 对这类语言也一并塌缩。此外 ner()postag() 对非 CJK token 均返回 1,因此没有其他因子能区分这些词的稀有度。仓库中 rag/res/ 只包含 ner.jsonsynonym.jsondeepdoc/,由于 ner.json 能正常加载,可以排除打包或权限问题。

Issue 中提到同类问题也存在于 Go 实现 internal/service/nlp/term_weight.go,因此仅修 Python 会导致两种检索实现行为不一致。

环境排查

  • 确认 RAGFlow 版本是否为 v0.26.4,或是否处于未包含 #18470 的版本区间(例如 v0.27.0)。
  • 检查 rag/res/ 目录下是否存在 term.freq;Issue 确认该文件不在仓库中,Dockerfile 也不会下载。
  • 确认 rag/res/ner.json 是否能正常加载,用于排除打包或文件权限问题。
  • 若自行维护 Python/Go 双实现,需检查两边的 df() 回退逻辑是否一致。
  • Issue 未提供操作系统、Python、CUDA、PyTorch、显卡或依赖版本信息,暂不需要作为排查项。

解决步骤

  1. 先用最小复现脚本确认现象,运行如下代码,观察 len(d.df) 是否为 0,以及各 token 权重是否塌缩成相同值:
    from rag.nlp.term_weight import Dealer
    d = Dealer()
    print(len(d.df))
    for t, w in sorted(d.weights(["what was the largest supplier of hospital equipment in Salvador"],
                                 preprocess=True), key=lambda x: -x[1]):
        print(f"{t:<14} {w:.4f}")
  2. 如确认 len(d.df) == 0,将 RAGFlow 升级到 v0.27.1 或 v0.27.2(含 #18470,合并于 2026-08-19)。
  3. 若使用 Go 侧 NLP 实现,确认对应的 internal/service/nlp/term_weight.go 也包含 #18470 中的对齐修复,避免 Python 与 Go 行为不一致。
  4. 如同时使用非 UTF-8 环境,可一并确认 #18467(合并于 2026-08-27)是否已合入,该 PR 将 term-weight 资源按 UTF-8 加载。
  5. 如需在自有环境中补充词频资源,可优先尝试提供制表符分隔的 termdocument_frequency 格式的 term.freqload_dict 所期望的格式);Issue 中仅作为建议提出,未见官方随包发布该资源的确认。

验证方法

在 v0.27.1 或 v0.27.2 上重跑上述复现脚本,确认修复后 df() 对字母类 OOV token 使用有界估算:三字母及以内保持原来的频率 300,此后每两个字母估算减半,下限为 10。Issue 中的修复说明提到应覆盖报告的排序关系 was < largest < supplier < equipment,即停用词权重应低于内容词。另外可验证:若将来存在 term.freq 条目,显式字典条目仍应优先于该回退估算。

注意:rag/res/term.freq 仍不会随包发布,因此不应以该文件是否存在、或 Load term.freq FAIL! 是否消失作为判断修复成功的依据。

参考来源

infiniflow/ragflow #18414

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 25256

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注