当前位置:   article > 正文

agentsim流程分析

agentsim

agentsim

前言

这里是类斯坦福小镇项目agentsim的一个调研。主要目的是寻找行为树模式的氛围npc不够智能的解决方案。下面会先简单介绍下一些关键的类,然后再讲解流程。该项目有段时间没维护了,没法直接运行,有兴趣的可以修修,主要是openai接口版本的问题。

重点类与作用

这里我们简单阐述几个和llm相关的核心类

Prompts

prompt类作用是获取提示词,提示词目录如下
在这里插入图片描述

Actor

actor类代表每个npc,这里涉及了所有对llm回复的处理。react函数:是一个状态机,根据不同状态选择不同的提示词ask llm。

Agent

agent类是actor的基类,负责填充提示词

Tick

tick类,消息处理的第一环,负责状态转移 。parse_react函数:解析所有的react得到的llm回复,进行状态转移

主流程

主流程其实很简单register tick到来,走初始化逻辑。后续由common tick消息驱动状态转移,每个tick会依次 处理movings,chat, using, initted中uid对应的任务逻辑。
在这里插入图片描述

React system

React system比较复杂,核心函数为为**react **和 parse_react构成。后面,流程图比较难画且不方便理解。下面我们将通过描述过程的方式来帮助理解。主流程中我们可以清楚的看到,处理逻辑的核心是 movings,inited,chatted,using 这几个数组,下面留心下是什么时候添加进来的。

第一个tick

第一个tick往往是register tick,表示一个客户端的连接。这里初始化了一些游戏系统的资源,如npc模型,alan和ph这两个npc。然后将这两个npc的uid添加到inited数组中。
在这里插入图片描述
随后就是持续的common tick,开始驱动后续的状态转移。

第二个tick

上一个tick已经将alan和ph 这两个npc的uid注册到了inited数组中。在该tick中使用solve_init处理alan和ph。这里首先是** _qa_framework**,该函数获取提示词 qa_framework_question ,首先让llm根据用户的目标以及已有知识提出问题,再使用qa_framework_answer解决问题(目的是延迟模型的思考时间,提高模型处理问题的质量),最后获取提示词plan,让llm给出下一个plan作为result的newPlan字段存入,plan 的结构如下:

{
“building”: “…”, 需要我前往的建筑
“purpose” : “…” 目的是什么
}

接着调用parse_react,根据result进行状态转移,因为result中存在newPlan字段,则走newPlan分支。该分支下,如果当前位置和building不一样,这说明需要前往下一个building,所以这里需要通过navigate寻路,调用move将结果发送给客户端。注意无论,curlocation 和targetlocation是否相同都会添加该npc uid到movings队列中。

第三次tick

这里补充下,navigate寻路成功,会将path保存在对应npc model的path中。当send 客户端时,会将path清空。只要调用了move,就会将uid添加到movings数组中。

此时只有movings中有任务需要处理。slove_moving调用move,这时由于path为null,则走move的另外一个分支,即则设置result timetick-finishMoving,进行react,该状态时去llm获取行为act(使用提示词为act),npc能够进行的行为有三个 :(1)use:使用工具 (模拟工具使用)(2)chat:聊天 (3)expierence : 尝试经验中的行为action,下面是result的返回结果:

{
“action”: “use”,
“equipment” : “…”, 使用什么设备,如desk
“operation” : “…” 做什么?
}
{
“action”: “chat”,
“person” : “…”, 和谁聊天
“topic” : “…” 聊天的主题
}
{
“action”:“experience”,
“experienceID”:“…” 使用哪一次的经验
}

由于该tick是第一个行为,没有experience,所以,目前只会出现use 和chat这两种情况。和上一个tick相同

下面是react分支

use

如果是use,则调用use函数使用use提示词,模拟使用物品
{“continue_time” : “…”,
“result” : “…”,使用原因
“bought_thing” : “…”,
“amount” : “…”
}

{“continue_time” : “…”,
“result” : “…”, 使用原因
“earn” : “…”
}

Chat

如果是chat,则调用chat 让llm根据提示词开始一个话题

进行parse_react

use

如果是use,则使用navigate对该equipment进行寻路,如果找到path,则再次进行move,和上个tick一样,send客户端,清空model上的path。并将uid添加到using

chat

如果是chat,则调用_execute_chat对当前两个npc,进行5轮chat (使用提示词为chat),将结果存放在npc的chats上,并将uid添加到chatted

所以这一轮 movings中必定会有值。

第四次tick

这是和之前一样先处理movings中的任务,不同的是这里还要处理chatted/using中任务

上一轮为use

调用finish_using,设置状态为 timetick-finishUse,该状态调用_critic,进行评价(使用critic提示词),这里将根据上一轮中的act判断plan是否完成,llm返回结果如下:

{“result”: “success”/“fail”/“not_finished_yet”}

Success or failed

认为该plan已经有结果了,则调用_store_memory更新对people和building的impression。

{
“people”:{“person_name”:{“impression”:“xxx”,“newEpisodicMemory”:“xxx”}}
“buildings”:{“building_name”:{“impression”:“xxx”,“newEpisodicMemory”:“xxx”}}
}

如果为success,则需要将上一轮的所有act作为experience存储下来,将上一轮的acts和plan作为一个experience存储到 npc的experience map中。并将plan添加到plan_cache中表示以及完成的plans

not_finished_yet

清空所有act,然后调用_plan开始一个新的plan

上一轮为chat

则直接store_memory

Experience

最后我们看下当act 返回结果为experience的情况,如果act选择的是使用experience,我们根据id找到对应的experience中,再从experience中pop出一个act,并且设置flag为使用experience,注意这种情况和use走同一个逻辑,即走parse_react的use分支,不同的在use完毕后不会走critic流程,因为之前以及判断过了,执行完experience的所有act后,会开始一个新的plan

在这里插入图片描述

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号