AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


Dify多参数混合条件判断的使用心得
发布日期:2024-09-24 10:06:38 浏览次数: 1514



首先我得说明一下本文提到的多参数条件判断指的是什么,为了方便大家理解,我举例说明:

当我们有两个关联的参数需要判断,假设参数有A和B.

其中A参数共计有10个值需要处理,B参数有20个值要处理。

此时,对于dify工作流开发者而言,这是一个非常头疼的事,我相信大多数开发者跟我一样,乍一看,完了,这可能要写200个对应的分支工作流。

不要觉得这两个参数的取值范围够大了,如果是企业级项目,这根本不算大的,那如果是5个参数呢?那你岂不是写分支工作流要写疯了???


多参条件判断的原则


本节我提到的原则,纯属个人观点哈,因为我在 处理这种情况的时候, 发现遵循这个原则,可以一定程度上大幅缩减分支工作流的数量,并且带来一定的可拓展性,也方便维护。


我先说下我的心得,主要有关联性的两点:


  1. 将多参判断,整体改造成单一参数判断,我喜欢称之为“降维判断”;

  2. 为保障工作流稳定性,多参处理环节,推荐使用串联模式,尽可能避免采用并行模式。


还是拿上面那个例子来说,当我们有两个参数需要关联起来判断时,如果不降低判断维度,你就得写200个分支工作流,这怎么可能呢?哪有那么多时间去写如此多的分支。

降维的主要特点,就是先判断一个,过滤掉干扰项目,保留跟参数B有必要关联的分支,然后再判断参数B,再次过滤干扰项目,最后再把两个参数有强关联的项目对应起来。

我知道说起来可能很绕,我拿自己的案例给大家说明一下:

我现在正在用dify做一个类似slg的文字游戏,后续也有想法改造成网游文字游戏。我在设计过程中,就遇到了这么一个问题:受dify当前能力的限制,文字游戏,主要又是靠玩家输入的指令触发工作流的,那么我就必须要设计一套符合游戏玩法的指令集,这个指令集也是用dify实现的。

此时,根据我对游戏玩法的规划,我希望工作流能检测用户的输入与玩家npc状态是否匹配,最终确定用户的指令是否能在当前游戏地图场景下,触发一个正确的分支工作流。

此时,我就要面对两个最核心的参数:用户输入(A)、玩家状态(B)。

参数A是玩家输入的,但是我其实并不知道玩家在真实使用的环境下,它到底会输入什么,所以我必须要检测输入的内容能否跟我预设的指令集对应。只有对应上了,后续工作流才可以继续判断,以此类推。

参数A按照规划,其取值范围对应指令集中的22个值,参数B要对应预设的6个值。




如果不考虑降维,工作流起码得长这样,条件判断套条件判断的模式,并且此时,两个条件判断还不能并行,不然就不符合我对游戏玩家的规划逻辑了。面对这种情况,我一开始头都大了,想得过于复杂,把自己给绕进去了。

于是我就仔细研究了一下dify的条件判断节点,如果这个判断,只要需要判断一个参数就好了,那岂不是不用这么疯狂嵌套了,并且还不影响我后续对指令集的扩充。

于是,骚操作就来了。


先预设一个指令集到会话变量中,使用array[object]类型,第一步检测用户的输入,是否与指令集匹配,如果不匹配,直接回复指令错误的引导。如果匹配,继续判断。

与项目某个状态值是否一致,如果一致,就返回需要触发的指令ID,如果不一致,就回复不一致。

然后用条件判断节点为每一个事件ID写一套相应的工作流即可。



于是,工作流就变成了如上图所示。


因为参数B其实好判断,但是参数A的影响因素太多,不可控性太高了,必须用过滤给他安排上,先把不符合条件的全部过滤掉,再把符合条件的找出来跟参数B对比,得出一个条件交叉的新参数,这个新参数,就是我们最终要重点设计的分支工作流的唯一凭证。这就变成了单参数的条件判断了,此时,我想怎么维护就怎么维护,无论两个参数的取值范围有多大,我都不需要大规模改动工作流,也同样适配。


这里用到的重点能力,就是dify的会话变量。首先我按照游戏的规划,预设了一个指令集commands array[object],然后玩家状态预设了一个变量player_hub array[object]


虽然我这个游戏工作流并没有开发完,我还是愿意给大家分享一下:


commands array[object]

[{"id":1,"text":"返回基地"},{"id":2,"text":"进入星区"},{"id":3,"text":"进入星云"},{"id":4,"text":"商城"},{"id":5,"text":"活动"},{"id":6,"text":"开始战斗"},{"id":7,"text":"撤退"},{"id":8,"text":"修改战斗位"},{"id":9,"text":"改造战舰"},{"id":10,"text":"修改阵型"},{"id":11,"text":"新增战舰"},{"id":12,"text":"下架战舰"},{"id":13,"text":"查看战舰"},{"id":14,"text":"升级武器"},{"id":15,"text":"升级防御"},{"id":16,"text":"购买商品"},{"id":17,"text":"销售战利品"},{"id":18,"text":"活动商品"},{"id":19,"text":"活动规则"},{"id":20,"text":"兑换商品"},{"id":21,"text":"搜索敌人"},{"id":22,"text":"帮助"}]

看到这个ID了吗,这是预设的,每一个ID对于的事件,其实就是最终要做的分支工作流。


player_hub array[object]

[{"id":1,"des":"基地"},{"id":2,"des":"星区"},{"id":3,"des":"星云"},{"id":4,"des":"编辑舰队"},{"id":5,"des":"商城"},{"id":6,"des":"活动"}]

这个变量表示玩家当前所在的地图场景。因为按照我的游戏规划,玩家处于不同地图时候,虽然很多功能都是通用的,但是部分地图对某些功能要有限制作用。


下面是工作流某些关键节点的设计:



import jsondef main(arg1: int, arg2: str, command: list) -> dict:# 将 command_ids 转换为字典,以便快速查找command_ids = {item["text"]: item["id"] for item in command}actions = {1: {"返回基地": (1, "你已进入基地", command_ids["返回基地"]),"进入星区": (1, "你已进入星区", command_ids["进入星区"]),"进入星云": (1, "你已进入星云", command_ids["进入星云"]),"商城": (1, "你已进入商城", command_ids["商城"]),"活动": (1, "你已进入活动", command_ids["活动"]),"开始战斗": (0, "请先输入指令:搜索敌人", command_ids["开始战斗"]),"撤退": (0, "请先输入指令:搜索敌人", command_ids["撤退"]),"修改战斗位": (0, "请先输入指令:编辑舰队", command_ids["修改战斗位"]),"改造战舰": (0, "请先输入指令:编辑舰队", command_ids["改造战舰"]),"修改阵型": (0, "请先输入指令:编辑舰队", command_ids["修改阵型"]),"新增战舰": (0, "请先输入指令:编辑舰队", command_ids["新增战舰"]),"下架战舰": (0, "请先输入指令:编辑舰队", command_ids["下架战舰"]),"查看战舰": (0, "请先输入指令:编辑舰队", command_ids["查看战舰"]),"升级武器": (0, "请先输入指令:编辑舰队", command_ids["升级武器"]),"升级防御": (0, "请先输入指令:编辑舰队", command_ids["升级防御"]),"购买商品": (0, "请先输入指令:商城", command_ids["购买商品"]),"销售战利品": (0, "请先输入指令:商城", command_ids["销售战利品"]),"活动商品": (0, "请先输入指令:活动", command_ids["活动商品"]),"活动规则": (0, "请先输入指令:活动", command_ids["活动规则"]),"兑换商品": (0, "请先输入指令:活动", command_ids["兑换商品"]),"搜索敌人": (1, "你当前在基地中,不能直接搜索敌人,请进入星云或者星区", command_ids["搜索敌人"]),"帮助": (1, "正在为你展开帮助菜单", command_ids["帮助"])},2: {"返回基地": (1, "你已进入基地", command_ids["返回基地"]),"进入星区": (1, "你已进入星区", command_ids["进入星区"]),"进入星云": (1, "你已进入星云", command_ids["进入星云"]),"商城": (1, "你已进入商城", command_ids["商城"]),"活动": (1, "你已进入活动", command_ids["活动"]),"开始战斗": (0, "请先输入指令:搜索敌人", command_ids["开始战斗"]),"撤退": (0, "请先输入指令:搜索敌人", command_ids["撤退"]),"修改战斗位": (0, "请先输入指令:编辑舰队", command_ids["修改战斗位"]),"改造战舰": (0, "请先输入指令:编辑舰队", command_ids["改造战舰"]),"修改阵型": (0, "请先输入指令:编辑舰队", command_ids["修改阵型"]),"新增战舰": (0, "请先输入指令:编辑舰队", command_ids["新增战舰"]),"下架战舰": (0, "请先输入指令:编辑舰队", command_ids["下架战舰"]),"查看战舰": (0, "请先输入指令:编辑舰队", command_ids["查看战舰"]),"升级武器": (0, "请先输入指令:编辑舰队", command_ids["升级武器"]),"升级防御": (0, "请先输入指令:编辑舰队", command_ids["升级防御"]),"购买商品": (0, "请先输入指令:商城", command_ids["购买商品"]),"销售战利品": (0, "请先输入指令:商城", command_ids["销售战利品"]),"活动商品": (0, "请先输入指令:活动", command_ids["活动商品"]),"活动规则": (0, "请先输入指令:活动", command_ids["活动规则"]),"兑换商品": (0, "请先输入指令:活动", command_ids["兑换商品"]),"搜索敌人": (1, "雷达已开启,正在搜索附近敌人", command_ids["搜索敌人"]),"帮助": (1, "正在为你展开帮助菜单", command_ids["帮助"])},3: {"返回基地": (1, "你已进入基地", command_ids["返回基地"]),"进入星区": (1, "你已进入星区", command_ids["进入星区"]),"进入星云": (1, "你已进入星云", command_ids["进入星云"]),"商城": (1, "你已进入商城", command_ids["商城"]),"活动": (1, "你已进入活动", command_ids["活动"]),"开始战斗": (0, "请先输入指令:搜索敌人", command_ids["开始战斗"]),"撤退": (0, "请先输入指令:搜索敌人", command_ids["撤退"]),"修改战斗位": (0, "请先输入指令:编辑舰队", command_ids["修改战斗位"]),"改造战舰": (0, "请先输入指令:编辑舰队", command_ids["改造战舰"]),"修改阵型": (0, "请先输入指令:编辑舰队", command_ids["修改阵型"]),"新增战舰": (0, "请先输入指令:编辑舰队", command_ids["新增战舰"]),"下架战舰": (0, "请先输入指令:编辑舰队", command_ids["下架战舰"]),"查看战舰": (0, "请先输入指令:编辑舰队", command_ids["查看战舰"]),"升级武器": (0, "请先输入指令:编辑舰队", command_ids["升级武器"]),"升级防御": (0, "请先输入指令:编辑舰队", command_ids["升级防御"]),"购买商品": (0, "请先输入指令:商城", command_ids["购买商品"]),"销售战利品": (0, "请先输入指令:商城", command_ids["销售战利品"]),"活动商品": (0, "请先输入指令:活动", command_ids["活动商品"]),"活动规则": (0, "请先输入指令:活动", command_ids["活动规则"]),"兑换商品": (0, "请先输入指令:活动", command_ids["兑换商品"]),'搜索敌人':(1,'雷达已开启,正在搜索附近敌人',command_ids['搜索敌人']),'帮助':(1,'正在为你展开帮助菜单',command_ids['帮助'])},4: {'返回基地':(1,'你已进入基地',command_ids['返回基地']),'进入星区':(1,'你已进入星区',command_ids['进入星区']),'进入星云':(1,'你已进入星云',command_ids['进入星云']),'商城':(1,'你已进入商城',command_ids['商城']),'活动':(1,'你已进入活动',command_ids['活动']),'开始战斗':(0,'请先输入指令:搜索敌人',command_ids['开始战斗']),'撤退':(0,'请先输入指令:搜索敌人',command_ids['撤退']),'修改战斗位':(1,'正在为你启动舰队编辑功能',command_ids['修改战斗位']),'改造战舰':(1,'正在为你启动舰队编辑功能',command_ids['改造战舰']),'修改阵型':(1,'正在为你启动舰队编辑功能',command_ids['修改阵型']),'新增战舰':(1,'正在为你启动舰队编辑功能',command_ids['新增战舰']),'下架战舰':(1,'正在为你启动舰队编辑功能',command_ids['下架战舰']),'查看战舰':(1,'正在为你启动舰队编辑功能',command_ids['查看战舰']),'升级武器':(1,'正在为你启动舰队编辑功能',command_ids['升级武器']),'升级防御':(1,'正在为你启动舰队编辑功能',command_ids['升级防御']),'购买商品':(0,'请先输入指令:商城',command_ids['购买商品']),'销售战利品':(0,'请先输入指令:商城',command_ids['销售战利品']),'活动商品':(0,'请先输入指令:活动',command_ids['活动商品']),'活动规则':(0,'请先输入指令:活动',command_ids['活动规则']),'兑换商品':(0,'请先输入指令:活动',command_ids['兑换商品']),'搜索敌人':(1,'雷达已开启,正在搜索附近敌人',command_ids['搜索敌人']),'帮助':(1,'正在为你展开帮助菜单',command_ids['帮助'])},5: { '返回基地':(1,'你已进入基地',command_ids['返回基地']), '进入星区':(1,'你已进入星区',command_ids['进入星区']), '进入星云':(1,'你已进入星云',command_ids['进入星云']), '商城':(1,'你已进入商城',command_ids['商城']), '活动':(1,'你已进入活动',command_ids['活动']), '开始战斗':(0,'请先输入指令:搜索敌人',command_ids['开始战斗']), '撤退':(0,'请先输入指令:搜索敌人',command_ids['撤退']), '修改战斗位':(0,'请先输入指令:编辑舰队',command_ids['修改战斗位']), '改造战舰':(0,'请先输入指令:编辑舰队',command_ids['改造战舰']), '修改阵型':(0,'请先输入指令:编辑舰队',command_ids['修改阵型']), '新增战舰':(0,'请先输入指令:编辑舰队',command_ids['新增战舰']), '下架战舰':(0,'请先输入指令:编辑舰队',command_ids['下架战舰']), '查看战舰':(0,'请先输入指令:编辑舰队',command_ids['查看战舰']), '升级武器':(0,'请先输入指令:编辑舰队',command_ids['升级武器']), '升级防御':(0,'请先输入指令:编辑舰队',command_ids['升级防御']), '购买商品':(1,'商品列表已获取',command_ids['购买商品']), '销售战利品':(0,'战利品正在盘点,将开启自动结算功能',command_ids['销售战利品']), '活动商品':(0,'请先输入指令:活动',command_ids['活动商品']), '活动规则':(0,'请先输入指令:活动',command_ids['活动规则']), '兑换商品':(0,'请先输入指令:活动',command_ids['兑换商品']), '搜索敌人':(0,'你当前在商城中,不能直接搜索敌人,请进入星云或者星区',command_ids['搜索敌人']), '帮助':(1,'正在为你展开帮助菜单',command_ids['帮助']) }, 6: { '返回基地':(1,'你已进入基地',command_ids['返回基地']), '进入星区':(1,'你已进入星区',command_ids['进入星区']), '进入星云':(1,'你已进入星云',command_ids['进入星云']), '商城':(1,'你已进入商城',command_ids['商城']), '活动':(1,'你已进入活动',command_ids['活动']), '开始战斗':(0,'请先输入指令:搜索敌人',command_ids['开始战斗']), '撤退':(0,'请先输入指令:搜索敌人',command_ids['撤退']), '修改战斗位':(0,'请先输入指令:编辑舰队',command_ids['修改战斗位']), '改造战舰':(0,'请先输入指令:编辑舰队',command_ids['改造战舰']), '修改阵型':(0,'请先输入指令:编辑舰队',command_ids['修改阵型']), '新增战舰':(0,'请先输入指令:编辑舰队',command_ids['新增战舰']), '下架战舰':(0,'请先输入指令:编辑舰队',command_ids['下架战舰']), '查看战舰':(0,'请先输入指令:编辑舰队',command_ids['查看战舰']), '升级武器':(0,'请先输入指令:编辑舰队',command_ids['升级武器']), '升级防御':(0,'请先输入指令:编辑舰队',command_ids['升级防御']), '购买商品':(0,'请先输入指令:商城',command_ids['购买商品']), '销售战利品':(0,'请先输入指令:商城',command_ids['销售战利品']), '活动商品':(1,'斥候已打听到血鸦正在兜售一些商品,正在加载商品列表',command_ids['活动商品']), '活动规则':(1,'斥候已打听到一些关键情报,正在加载活动信息',command_ids['活动规则']), '兑换商品':(1,'正在检测活动积分,将启动商品对话服务',command_ids['兑换商品']), '搜索敌人':(0,'你当前在商城中,不能直接搜索敌人,请进入星云或者星区',command_ids['搜索敌人']), '帮助':(1,'正在为你展开帮助菜单',command_ids['帮助']) }}
state_actions = actions.get(arg1, {})response = state_actions.get(arg2, (None, None, None))a, text, b = response
return {"a": a,"text": text,"arg1": arg1,"arg2": arg2,"b": b}




最后就是为b写一个条件判断就OK了,是不是很简单,并且B的取值范围是指令集ID,指令集有多少个ID,你就写多少个分支就行。

是不是豁然开朗了?


说点个人感悟吧:


dify很好用,基础能力其实已经很强大了,开箱即用,我反正是无脑吹捧的,因为我从去年就开始玩这个。

虽然自己之前用dify做了两个简单点的文字游戏,随着dify版本更新,推出了更多的能力,dify逐渐满足去开发一个复杂项目的基础条件,只是好像很多人对dify的初印象还停留在用来写提示词的。

光鼓吹是没用的,我还是有一些不满意的地方,我给大家举两个例子:

就拿我上述的案例来说吧,dify官方版本如果某一天能延长工作流执行深度和单支节点数量,我这个游戏项目,我就敢大肆扩充我的指令库,从而不用担心系统限制而不敢玩的太激进,否则我就得自己动手去修改dify的源码了。

dify目前要是能直接支持远程,mysql数据库就好了,因为我后续确实有计划:只要本地文字版游戏工作流能跑通,就改造成网游版本,将玩家数据云端存储,实现网游化。


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询