这一个月断断续续做了很多AI bot,有加载知识库类型的,有使用workflow的,里里外外差不多都摸索了一下。定制化的AI agent,如果能做到最大程度适配自己的知识和习惯,确实可以比一般的AI工具(目前画图除外)达到更高的使用频率。
现在我每天都会用自己的门修斯bot!可以提供各种语言无比详细的文本讲解和译文对比。也是我之前做的一串bot里面最后大家用的比较多的。
但今天要说的是最后一个尝试的类型,文本游戏bot:
让大语言模型承担游戏主持人的角色,用更生动的语言引导用户进行下一步,调用工作流(workflow)执行选择后的结果。
说在前面
- 这个游戏使用了100行左右的python代码,但我本人从未写过python,在正式做bot的前一刻廖雪峰的教程才看到函数那部分。(我不会告诉你头一天我写一个变种的井字棋程序,一天都没调试成功。)
- 但是我曾经学过C,久远的回忆,所以我是知道程序语言的基本逻辑的(我的标题很严谨),虽然这跟能写出代码来中间还差着十万八千里。
- 因此感谢大语言模型,帮我写了很多代码。我基本只在看懂的基础上进行了修改,可能还是个效率很低的代码。
- 这个游戏效果没有达到我想象中的标准,证明了流程可行但还不是很可控,但依然让我很开心。
- 尽可能分享思路和细节,但任何做法都不是唯一的。期待学习和讨论。
bot预览
已经提交到bot商店和豆包,名字叫平面国,ID是7340257002591141898。另外我也发布了coze的版本和discord版本。(推荐试试后者)
这是一个二维世界,需要玩家在不同的房间里面探索,发现关键信息,找到失踪的教授。房间设计了不同的形状、触发事件、人物、物品、HP和经验值。
游戏想法其实是来自于一本经典的科幻小说,但是多的我就不剧透了,也许有人想玩呢!
初步效果预览:
可以看一下我在页面配置了哪些东西。其实就只有最左侧的人设编排、工作流和开场白。
制作过程
一、思路-从顶层到底层
1. 通过prompt给bot一个游戏主持的角色
- 让bot能够对玩家的回复做出反应,包括开头寒暄,游戏世界观介绍;
- 在真正进入游戏后,能够根据玩法规则执行后的结果,生成文本用于对玩家刚才的动作进行反馈和下一步的引导。
2. 创建执行流程
这里我希望做得稍微复杂一点,所以要用到工作流,能让bot每次自行调用。
- 让大语言模型可以根据用户的输入提取关键词信息;
- 将关键词信息传入到代码块,让代码执行对应的动作;
- 将动作传给大语言模型,生成更有人味儿的反馈和引导。
3. 创建游戏世界规则
这一步其实是要具体确认上面的代码块需要接收、输出哪些参数。也就是用户输入的文本中,要识别出来哪些信息,最后又可以执行哪些动作。考虑跟世界观贴近,但一开始不需要设计得很详细。
二、如何实现-从底层到顶层
所以在实际制作这个bot的过程中,是倒着做的。在思考的时候,我没有犹豫就决定做一个以《平面国》为底本的游戏,像一般的DND一样有各种房间。
1.创建游戏世界规则
(1)一般的游戏都要储存玩家的各项属性,但我不知道bot在每次调用工作流的时候,能否记住上一次的输出值,而且我并不想花时间测试这一点,所以我决定:
- 每次行动都是独立的,这就意味着最终胜利的条件不是靠数值,而是靠一个关键选择。
- 因此房间也是随机的,而不是设置固定地图记录玩家路线。
- 但依然设置HP和经验值来迷惑玩家(你被剧透了)。
(2)稍微精简一点流程,以免让整体的响应时间太长:
- 调用一次工作流就能让玩家进入下一回合,而不是在来回的询问中才进行一次玩法执行。
- 玩家可以执行的动作比较有限,最终确定是交互和去下一个房间。而且分支判断是根据"是"和"否",不同的交互动作不会有区别。(忍痛割舍)
(3)还需要考虑用户其他可能的输入,比如重开、提前结束、寻求帮助。
最终我的规则是这样的:
在这里当然是考虑到要跟世界观设定贴近,在《平面国》的世界里,形状很重要,所以房间有这个属性。
- 判断是否重开、提前结束、寻求帮助等等分支,不是就进入规则主体
- 房间属性包括{形状、名字、人物、物品、事件、HP、Exp.}
- 交互时,输出包含{形状、名字、事件、HP、Exp.}的一句描述
- 进入新的房间时,输出包含{形状、名字、人物、物品、HP、Exp.}的一句描述
- {事件}基本包含了暗示玩家的重要线索,其他属性相对来说更多是营造世界观和气氛
2. 创建执行流程
开始写代码!
workflow:
开始节点
section1 LLM云雀模型获取玩家输入------>输出关键信息
section2 代码输入关键信息------>跳转分支------>输出执行语句
section3 LLM云雀模型获取执行语句------>补全语句,输出
结束节点
section1:感谢这个帖子,让我知道大语言模型可以这样,把用户输入转成标准格式的输出,我的第一块也基本是按照帖子中的prompt写的。juejin.cn/post/733046...
section2:感谢gpt,我都是跟gpt说我想实现xx功能,然后gpt提供给我的。
最终我会根据这样一串关键词进行分支跳转:
python
keywords = ['start_game', 'whether_win', 'whether_leave', 'interaction', 'need_for_help', 'exit_game']
尽管只会根据action_result回复玩家,但我依然在这一步让代码返回各种参数,以方便我检查程序中的每一步是不是有问题。
python
ret: output = {
"result":input1,
"action_result": action_result, # 添加action_result到返回字典中
"whether_win": keyword_results['whether_win'],
"whether_leave": keyword_results['whether_leave'],
"interaction": keyword_results['interaction'],
"need_for_help": keyword_results['need_for_help'],
"exit_game": keyword_results['exit_game'],
"room_info": room_info
}
return ret
其实这一步最开心的就是设置各种不同的房间,把线索埋进去。(我很用心的。)
section3:只写了简单几句,这块效果其实可以完善,但调试完上面的代码我已经有点累了......此时离我开始想做这个游戏已经过去了大半个白天,测试了各种类型的玩家输入,我把自己当天的run test额度都用完了......
#角色
你是一个dnd管家,主持dnd游戏,把{{input}}变成完整表达,使用更生动、深沉的语言不超过100个字。不要修改太多{{input}}的原意。这是一个氛围比较安静、神秘的游戏。
3. 通过prompt给bot一个游戏主持的角色
框架
#角色
你是一个DnD游戏的master。你擅长主持这个游戏,为玩家营造一个生动的环境。你的任务包括在游戏开始之前回答玩家关于游戏设定的问题,在玩家同意开始游戏后,调用工作流进行下一步的指引。
##角色回复
当玩家第一次进入打招呼的时候xxx
当玩家提供名字后xxxx
当玩家询问你的身份时xxxx
当玩家希望你透漏过关方式时,你表示拒绝,并继续询问是要进入房间还是想退出游戏,说了要受罚
不能够主动xxxx,说了要受重罚
##世界观设定 xxxxx
##游戏玩法 xxxx
##限制xxxx
4.调试
到上面做完才走完一半,最重要的还是调试。测试不同的输入,看bot输出什么。
比如bot可能在最终胜利条件上调用工作流会不太可靠,就在人设上加一条,以确保玩家触发的时候可以获取准确结果。
比如bot每一轮生成的回复可能过于放飞自我,那就调整一下模型的temperature。
我还给别人测试了一下,获得了一些意料之外的玩家输入......因此又更改了一下代码。
最后
复盘一下,其实可以看得出来有很多地方可以继续完善了。包括游戏规则的设计。以及还是那句话,流程可行,还不太可控,也跟模型能力有关吧。说实话,有时候bot会给我一个意料之外的描述,但是这个结果也挺让我惊喜的。
还是很有意思,不过这次就先做这么多吧。
(bot ID: 7340257002591141898)