快速结论:RAGFlow 全文检索连接器把 minimum_should_match 小数比例转成百分比字符串时,用 int() 截断导致阈值比预期少 1%(如 0.29 被转成 “28%”)。优先检查 rag/utils/ 与 memory/utils/ 下六个连接器 search() 方法中的 str(int(fraction * 100)) + “%” 写法,并改为 round() 取整。
适用环境:RAGFlow 源码提交 a39b6ec2e9a840c8cf9c1c8c021ade6a7613be56;影响 ESConnection、OSConnection、OBConnection、InfinityConnection 及其 memory/ 对应实现;不涉及 Docker 镜像方式部署(Issue 通过直接运行连接器复现)。
最快修复方案:暂无确认的一步修复方案(Issue 在关闭时尚未合并补丁);可优先尝试将六个连接器中的 str(int(fraction * 100)) + “%” 替换为 str(round(fraction * 100)) + “%”,这与项目此前 PR #12688 的修复方式一致。
注意事项:该修复属于代码层面的修改,需重新构建或对应环境运行;若通过 Docker 镜像部署需等待官方镜像更新。Issue 明确说明这不是 common/float_utils.py 中 normalize_overlapped_percent 那条路径,不要混淆。
问题场景
RAGFlow 全文搜索路径中,调用方(如 rag/nlp/query.py 的 question() 或 memory/services/query.py)把用户传入的 minimum_should_match 小数阈值传给 MatchTextExpr.extra_options[“minimum_should_match”],最终到达六个全文存储连接器(ESConnection、OSConnection、OBConnection、InfinityConnection 及 memory 版本)时,这些连接器统一用 str(int(fraction * 100)) + “%” 把小数转成百分比字符串。由于绝大多数两位小数在 IEEE-754 中不能精确表示(如 0.29 实际存储为 0.28999999999999998),int() 向零截断后会让查询引擎收到比请求更严格的阈值,并且总是向下取整。
报错原文
[Bug]: minimum_should_match fraction is truncated, not rounded, in every full-text doc-store connector
>>> str(int(0.29 * 100)) + "%"
'28%' # requested 29%
>>> str(int(0.57 * 100)) + "%"
'56%' # requested 57%
>>> str(int(0.58 * 100)) + "%"
'57%' # requested 58%
原因分析
可能原因:六个连接器重复使用了同一段截断表达式 str(int(minimum_should_match * 100)) + “%”。浮点运算中 0.29 * 100 的结果略小于 29(即 28.999…),int() 截断小数部分得到 28。Issue 作者检查了 (0,1) 区间内全部 99 个两位小数,确认多个值因浮点表示误差落在边界上,导致结果总是向下取整而非四舍五入。注意,这是独立于 common/float_utils.py 中 normalize_overlapped_percent 截断的另一条代码路径,后者对应的是 chunk 重叠百分比字段且有 [0,90] 区间限制,与本问题无关。
环境排查
- 确认 RAGFlow 源码 commit ID:a39b6ec2e9a840c8cf9c1c8c021ade6a7613be56(可执行 git checkout 验证)
- 检查 rag/utils/es_conn.py、rag/utils/opensearch_conn.py、rag/utils/ob_conn.py、rag/utils/infinity_conn.py 以及 memory/utils/es_conn.py、memory/utils/infinity_conn.py 中是否存在 str(int(fraction * 100)) + “%”
- 若通过 Docker 部署,需确认镜像构建时间是否包含 fix 提交;Issue 复现方式是直接运行连接器而非 Docker
解决步骤
- 定位六个文件中对应的 search() 方法,找到 minimum_should_match 转百分比字符串的表达式。
- 将 str(int(minimum_should_match * 100)) + “%” 改为 str(round(minimum_should_match * 100)) + “%”(参考此前 PR #12688 对类似问题的处理方式)。
- 如涉及 Infinity、OpenSearch、OceanBase 等不同后端,确认各连接器接受百分比字符串的格式一致。
- 检查 rag/nlp/query.py 中 question() 与 memory/services/query.py 的调用链,确认传入 extra_options[“minimum_should_match”] 的值类型为 float。
- 若同时使用多个全文检索后端(ES/OS/OB/Infinity),需要在这六个文件里全部同步修改,否则行为会不一致。
验证方法
在修改后的环境里执行 Issue 中的复现脚本:python3 -c “for f in (0.29, 0.57, 0.58): print(f, ‘->’, str(round(f * 100)) + ‘%’)”,确认输出应为 29%、57%、58%;再对 rag/utils/es_conn.py 等文件做一次实际的最小实例搜索,用查询日志确认发送给后端的 minimum_should_match 参数值与请求一致,不再比请求阈值少 1%。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


![[BUG] Gemini native provider never appends trailing user turn -> 400 'Requests ending with a model turn are not supported'](https://www.chat-gpts.plus/wp-content/uploads/2026/09/6984-b83b3d42-768x403.jpg)