问题描述
在 Docker 自部署的 Dify v1.13.0 中,知识检索节点的元数据过滤功能存在以下异常:
-
将过滤值设为常量:正常过滤,结果符合预期 -
将过滤值设为变量(引用其他节点的输出):过滤完全失效,结果不对
在 v1.11.4 版本中该功能一切正常,升级到 v1.13.0 后出现此问题。
根本原因(源码分析)
通过分析 v1.13.0 源码,v1.13.0 对知识检索节点进行了重构,代码从旧路径:
Code
api/core/workflow/nodes/knowledge_retrieval/
迁移到新路径:
Code
api/dify_graph/nodes/knowledge_retrieval/
问题出在 _extract_variable_selector_to_variable_mapping 方法,该方法的作用是告诉图引擎"本节点依赖哪些上游变量",引擎会据此提前将变量值注入 variable_pool(变量池)。
但新版代码中,这个方法只注册了查询变量,完全遗漏了元数据过滤条件中的变量引用:
Python
# api/dify_graph/nodes/knowledge_retrieval/knowledge_retrieval_node.py
@classmethod
def _extract_variable_selector_to_variable_mapping(cls, *, graph_config, node_id, node_data):
typed_node_data = KnowledgeRetrievalNodeData.model_validate(node_data)
variable_mapping = {}
if typed_node_data.query_variable_selector:
variable_mapping[node_id + ".query"] = typed_node_data.query_variable_selector
if typed_node_data.query_attachment_selector:
variable_mapping[node_id + ".queryAttachment"] = typed_node_data.query_attachment_selector
# ❌ 这里完全没有处理 metadata_filtering_conditions 里的变量引用!
return variable_mapping
由此导致运行时执行 _resolve_metadata_filtering_conditions() 时,调用 variable_pool.convert_template("{{#node_id.var#}}") 在变量池中找不到对应变量,过滤条件失效。
而常量之所以正常,是因为常量值(如 "abc")在 convert_template 时模板中没有 {{#...#}} 占位符,直接原样返回,完全不依赖变量池。
执行流程对比
| 常量 | 变量 | |
|---|---|---|
| 存储格式 | "abc" |
"{{#start.my_var#}}" |
| 是否依赖变量池 | 否,直接使用 | 是,运行时查池取值 |
| 是否需要预注册 | 否 | 是,必须在 _extract_variable_selector_to_variable_mapping 中注册 |
| v1.13.0 结果 |
修复建议
在 _extract_variable_selector_to_variable_mapping 方法中,补充对 metadata_filtering_conditions 里变量引用的注册逻辑,解析每个 condition.value 中的 {{#...#}} 模板,将对应变量加入 variable_mapping。
环境信息
-
Dify 版本:v1.13.0(Docker 自部署)
-
问题版本对比:v1.11.4 正常,v1.13.0 异常
-
问题路径:
api/dify_graph/nodes/knowledge_retrieval/knowledge_retrieval_node.py
希望官方能尽快修复,感谢!