Dify工作流中变量取不到值的主因是作用域混淆:Global变量(如用$context.set()写入或Output配置)全局可读写,适合跨节点传递;Local变量仅限本节点生命周期,无法被下游访问。关键判断依据是“是否需下游使用”。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

在Dify工作流中配置变量时,若未明确区分作用域类型,常导致前序节点设置的值在后续节点中取不到、报undefined或流程中断——这不是代码写错了,而是变量根本没被放进正确的作用域里。
理解Global与Local变量的本质区别
Global变量在整个工作流生命周期内都可被任意节点读写,适合存API密钥、环境标识、用户会话ID等跨节点强依赖数据;Local变量只存在于定义它的那个节点内部,节点执行结束即销毁,无法被其他节点访问。
关键判断依据:【变量是否需要被下游节点使用】。如果需要,必须用Global方式写入;如果只是临时计算中间结果(比如字符串拼接、数组过滤),Local完全够用且更安全。
Local变量不会出现在节点输出面板里,Global变量则会在所有节点的“输入变量”下拉列表中自动出现。
在Node中声明Global变量的两种可靠写法
方法一:使用$context.set()写入全局上下文
在任意节点的代码块(如Python/JavaScript节点)中,执行$context.set("order_status", "paid")。这一步会把order_status注入全局上下文,后续所有节点均可通过$context.get("order_status")读取。
注意:$context.set()必须在节点执行逻辑中调用,不能写在注释里或条件分支外层未执行路径上。
方法二:在节点配置页显式定义Output Variables
进入节点右侧面板→点击“Outputs”→添加新字段→Name填user_id,Type选string,Value填{{input.user_id}}或{{step.auth.output.uid}}。这样Dify会自动将该字段注册为Global变量,并暴露给下游节点。
【Value字段必须填写有效表达式,空值或语法错误会导致整个节点输出为空对象】
Local变量的典型误用场景与修正
第一步:识别风险代码
在JavaScript节点中写了let temp_token = generateToken(); console.log(temp_token); 但没用$context.set()保存。此时temp_token是纯Local变量,生命周期仅限当前节点执行栈,下一节点绝对无法获取。
第二步:判断是否真需传递
如果temp_token只用于本节点内调用一次接口,且响应结果已通过return { token: temp_token }输出,则无需升为Global;如果下游节点要拿它做鉴权校验,就必须升级。
第三步:升级为Global的最小改动
在return前加一行:$context.set("api_token", temp_token); 后续节点即可用$context.get("api_token")安全读取。不建议改用var或全局声明,Dify不识别window/this上的挂载。
验证变量是否真正生效的实操检查点
在目标节点中插入一个Debug节点,内容写:console.log("user_id:", $context.get("user_id"), "type:", typeof $context.get("user_id"));
运行工作流后查看日志输出。若显示undefined或type为string但值为空,说明写入失败或key名大小写不一致。
常见坑:【Global变量名区分大小写,且不能含空格或中文】,例如$context.set("User_ID", "123")和$context.get("user_id")完全不匹配。











