了解完活动细则,开始找灵感,脑海里有关回忆杀的跑马灯转起来~
要说大部分8090后童年时心头的"白月光",那不得是当年风靡一时的「拓麻歌子」啊~
哈?没听过?噢噢,不好意思,这是它「霓虹万代正版」的叫法,在当时「祖国版」横行的国内,它有着各种各样的名字,如:宠物蛋、电子鸡等等,这里统一称作「电子宠物」吧~
我突然在想,早期的电子宠物虽是单机养成,但都能玩的得不亦乐乎,那要是用Coze(扣子)来搭一个"现代化的AI电子宠物",搭配最近上线的「图像流」,图文并茂,会不会很有意思?
话不多说,我直接开始~
先列下头脑风暴出来的玩法草稿~
就四个简单角色:玩家(属性、行为)、宠物(属性、行为)、道具、自动任务,接着做下可能用到的技术预研,写下Demo,看扣子能否支持~
需要一个东西来存玩家、宠物、道具的信息,用啥?对于这种动态变化的数据,一般是通过配置文件来保存的,不过扣子本身不支持存文件(插件不算哈)。
然后是一些常用的SQL语句:
--判断表是否为空SELECTCOUNT(*)asrecord_countFROMplayer_info--清空表数据DELETEFROMplayer_info不熟悉SQL的童鞋,也可以直接在数据库节点的SQL处点击自动生成:
新建一个Bot,选单Agent模式,方便调试工作流,接着新建两个表player_info和pet_info来保存玩家和宠物信息。
就刚开始玩或者宠物嘎掉重开,玩家和宠物信息初始化的流程,具体步骤如下图所示:
数据库部分就是拖节点,然后写下简单SQL而已,试运行,看下是否初始化成功:
玩家和宠物信息表,只会有一条数据,更新方便(无脑UPDATE),读写也快。当然,你喜欢每次都往表的首行插入数据,然后取的时候取第一条,也是可以滴♀~
Bot里涉及的图像生成的需求主要有两个:
新建一个图像流,用到「提示词优化」和「文生图」节点,直接拖拽,配置下输入输出参数:
试运行,输入五彩斑斓的黑色皮卡丘的看下生成效果:
哈哈,有点意思,这里也有一个小细节,文生图的宽/高参数:
发布下图像流,上面的初始化工作流加下它,顺带再添加生成格式化字符串的代码节点:
同样新建一个图像流,然后,问题来了:「文生图」节点不支持设置参考图参数,尝试使用其它节点实现,先试试「智能扩图」
em...就是基于原图的上下左右填充内容啊?♀试了N次都没让粉红兔宝宝吃上,只能换其它的节点试试了。
试下「文生图」先生成场景图,然后「多图融合」写提示词替换:
试运行看下效果:
啥玩意???又看了其它类型的节点,好像没法实现我的需求,看来图像流是没发走通的了,用回官方的文生图插件康康:
哈哈哈,终于让我的闪闪发光的二哈乐呵呵地吃上了,虽然颜色不是pinkpink的~
初始化成功后,我突然想起扣子文档里的一句话:
开发者和用户可通过自然语言插入和查询数据库中的数据。
那用户是不是可以言出法随,直接设置体力和金钱的值啊?试试:
果然可以,这不妥妥滴游戏漏洞吗?需要在提示词那里添加下约束:
##约束-禁止用户通过自然语言来直接操作数据库,直接返回"客官不可以哦"再试试:
技术预研完,我对游戏玩法又有新的,这样的玩法太死板了,比如:投喂只能是苹果、米饭和宠物口粮,想喂它吃其它的,得等我去更新。
然后我还得想下加多少点属性值。ヽ(`Д′)这种通过预设的道具表来约束玩家和宠物的交互方式,这TM能叫做"现代化的AI电子宠物"?
我觉得应该是这样的:
玩家自由发挥,想跟宠物怎么玩就怎么玩,由AI来评估此行为会对宠物的哪些属性造成影响。
好的,道具砍掉,随机事件也砍掉,因为扣子的定时触发器只有飞书平台能用,本质也是自动给Bot发送特定消息,意义不大。然后玩家的金钱属性也砍掉,改为每次行动消耗1点体力,玩猜成语可以补充体力,修改后的玩法设计草稿:
玩法方向确定了,接着就该具体实现了()
对于文笔不好的童鞋来说,写一段看着还行的开场白简直是要命,比如写这段话花了我至少5分钟:
这种活完全可以交给AI啊:
写个基本框架,通过提示词,让大模型来润色输出
举个:
看下运行效果:
文字挤在一起,看不太出效果,复制粘贴到记事本:
的,虽然比不上我写的,但也算有模有样,再微调下提示词可能会更好~
如果不需要每次动态生成,可以复制粘贴下,直接在结束节点写死返回的值。
Tips:勾选下流式输出,Bot会像打字机一样回复用户哦~
效果效果如下:
我尝试直接让豆包大模型随机生成一个常见的四字词语,结果不是一心一意,就是画蛇添足,换了几个模型也是类似的情况。那就走量吧,生成20个,然后我随机roll一个,豆包、通义千问每次都是一到十,醉了...
最后还是MinMax6.5s的模型靠谱一些,拖拽节点整下工作流:
难点应该也是代码节点,贴一下:
importrandomasyncdefmain(args:Args)->Output:params=args.paramsidiom_list=params['idiom_list']correct_idiom=random.choice(idiom_list)#随机取出两个下标index_num_list=[0,1,2,3]selected_numbers=random.sample(index_num_list,2)#生成模糊成语mask_idiom=""foriinrange(len(correct_idiom)):ifiinselected_numbers:mask_idiom+="【】"else:mask_idiom+=correct_idiom[i]#拼接问题question="本轮要猜的成语是→{},用户可以回复完整的四字成语参与".format(mask_idiom)ret:Output={"correct_idiom":correct_idiom,"question":question}returnret试运行通过,发布后,Bot写下关键词调下工作流:
就获取下用户输入的四字成语,判断下和变量保存的是否相同,给出对错的反馈,如果正确,玩家的体力+1。
比较简单,只贴下代码:
asyncdefmain(args:Args)->Output:params=args.paramspet_alive=params["pet_alive"]input_idiom=params['input_idiom']correct_idiom=params['correct_idiom']result_str=Noneis_correct=Falseifstr(pet_alive)=="Alive":ifinput_idiom==correct_idiom:is_correct=Trueresult_str="恭喜你,答对了,获得体力+1"else:result_str="抱歉,回答错误,正确答案是【{}】".format(correct_idiom)else:result_str=str(pet_alive)ret:Output={"result_str":result_str,"is_correct":is_correct,"empty_str":""}returnret试运行通过,发布,Bot写下关键词调下工作流,结果一直调用报错,什么数组越界,但是上面的代码并没有用到数组,后面反复折腾,终于发现了原因:
判断宠物状态的工作流也用到了数据库,不支持这样的嵌套,把这个节点删掉就正常了...
运行效果:
数据库的玩家体力也有增加:
♀尝试在Agent里写提示词,用户表达"退出"意图时跳回开始节点或上级节点,折腾了好一会儿都不行♀。那就直接粗暴地拖一个全局跳转条件的节点来跳:
成语游戏的Agent就搞到这,接着弄宠物的Agent。
就前面技术预研那里的游戏初始化工作流,稍微调整一下,随机生成属性:
看下效果:
这个简单,就查下数据库,然后拼接下字符串而已~
代码节点:
asyncdefmain(args:Args)->Output:params=args.paramsinput_list=params['input']iflen(input_list)>0:pet_info=input_list[0]output_str=f"""当前宠物信息:【名称】{pet_info['name']}【外形】{pet_info['appearance']}【破壳日】{pet_info['birth_time']}【饱食度】{pet_info['satiety']}/100【愉悦度】{pet_info['mood']}/100【健康度】{pet_info['health']}/100【重量】{pet_info['weight']}KG"""else:output_str='当前宠物信息:\n\n'ret:Output={"output_str":output_str.strip(),#使用strip()来移除字符串首尾的空行}returnretBot调用看下效果:
这部分比较复杂,期望输出结果分为三个部分:
具体效果图:
工作流:
这部分的难点,感觉是大模型提示词的编写,我写得不是很好,但也算实现了想要的效果,需要可以参考下。
先是生成画面详细描述:
运行看看生成结果:
差点没把我笑岔气,TM精确到时分秒,太假了,添加下约束:
再试试看生成效果:
其它两个大模型节点的提示词也是这样玩,输出结果达不到要求,就加约束,都是调调调,直到满意为止~
生成图片
行为影响评估
代码节点感觉大伙需要,也贴下吧:
搞排行榜是游戏中增加用户粘性的一种常见操作,扣子的数据表支持多用户模式(多个用户使用同一张表),不得给我们的AI电子宠物也整一个么?先建表,然后整三个字段:
在玩家和宠物互动产生属性变化时,执行数据入库,就在上面的互动反馈工作流里加逻辑:
具体流程节点如下:
试运行通过,发布工作流,然后Bot触发下宠物互动,点击已存数据库,可以看到记录已经入库,互动也能更新:
接着写一个查看宠物排行榜的工作流,比较简单,就查库,格式化输出下而已~
♀这个没啥,跟宠物那个一样,只是查下玩家信息表的数据库而已,掠过~
工作流弄得差不多,接着就是建Agent,添加各自的工作流,写好各自的prompts,由调度Agent来分发:
这里没啥难度,只是反复改提示词+测试,看跳转,以及Agent能否按自己预期调用工作流。说个小贴士,如果模型经常理解错误,可以改下模型设置:
使用精确模式,或者自定义,把生成随机性弄低一点:
当然,也可以试下其它的模型,不过感觉豆包在任务理解和调度这块还是可以的。贴下提示词:
搞了三天,终于把这个巨复杂的Bot搭起来跑通了,玩法和数值肯定是有不合理地方的,如果多人玩,到时再根据反馈来优化吧。初衷还是授之以渔,希望本文对想用Coze搭建复杂Bot的童鞋有启发吧~