本文作者:andreihuang,腾讯IEG应用研究员
非常感谢以下同事在整个项目开发过程中的倾力协作:
2022年12月19日,Twitch上出现了一个名为“vedal987”的新直播频道。该频道没有真人主播,只有一个可爱的二次元女孩形象在屏幕上移动和说话。她自称为Neurosama,是一位人工智能VTuber。
从那天起,她开始了自己的直播生涯,并迅速获得了大量关注和支持。与传统基于动作捕捉的中之人范式的虚拟主播不同的是,Neuro完全是由人工智能驱动的,准确来说是由背后大语言模型驱动的。
AI驱动的虚拟人具有许多优点和广阔的前景:
受到 Neuro-sama 的启发,本文中将介绍我们基于大模型驱动以及 AI 智能体思考的虚拟人技术的相关尝试。首先,我们将介绍基于 AI Agent 思想构建的虚拟人技术框架,然后我们将介绍在多虚拟人场景如何搭建灵活的互动框架,最后基于 AmongUs 游戏我们探索了游戏智能体的技术可能性,进一步丰富虚拟人的应用场景。
这里我们分享一段我们的虚拟人Li-chan 的演示视频:
以及 Li-chan 玩转 AmongUs的宣传视频(后文有更完整的演示视频):
在基于大模型驱动的虚拟人的整体技术框架设计中,我们主要参考 AI Agent 模式进行设计,并根据虚拟人的特定场景和需求进行相应的优化。
如下图所示,整个虚拟人框架主要包括两个基础组件,AI 智能体和 Live2D 模型:
我们将虚拟人的感知系统主要分为两部分:环境信息感知和交互信息感知
虚拟人的大脑是整个大模型驱动的虚拟人的核心部分,即上图的 AI Agent 部分。我们需要在这里定义虚拟人的角色设定、行为决策及对话生成。
大模型驱动着整体虚拟人的行为,因此选择合适的大模型尤为重要。由于 OpenAI 的 ChatGPT 和 GPT4因为其优秀的推理能力以及潜在的角色扮演能力,想必会成为大家的首选。但是在虚拟人这一具体场景中,由于考量的因素不同,ChatGPT 并不一定会是最优的选择。在实践过程中,我们主要的考量因素包括两点:
随着 Llama 系列模型的开源,以及开源社区的活跃二创,许多针对角色扮演的小规模开源大模型陆续推出。基于上述两点考量,我们将模型选型聚焦于针对角色扮演微调的 7B~13B开源大模型,经过社区评估和实际测试,综合考虑以下两个模型:
Nous-Hermes-Llama2-13b
Nous-Hermes-Llama2-13b是基于 Llama 2 13B微调的语言模型,由经过超过300,000条指令的精细调整。该模型在开源社区非常火爆,TheBloke/Nous-Hermes-13B-GPTQ的下载量已经高达160K。
其微调数据包括:由Teknium提供的GPTeacher、由nlpxucan提供的Wizard LM、由Microsoft提供的GPT4-LLM和Unnatural Instructions、由jondurbin提供的Airoboros dataset以及来自Camel-AI的Camel-AI的领域专家数据集等。
Pygmalion-2-13b
Pygmalion-2 13B同样基于Meta AI发布的Llama-2 13B。Pygmalion是一个聚焦于角色扮演领域的开源研究组织,旨在尝试获得可用于对话、角色扮演和写作故事的模型,同时可以像其他通用语言模型一样使用自然语言进行引导。用于微调此模型的数据集包括PIPPA,以及其他几个指令数据集和从各种RP论坛获取的数据集。
角色设定定义了角色的性格、背景、经历等信息,这直接决定着生成的对话风格。有关角色大模型微调和角色定义的详细介绍,可以参考我们的另一篇文章《一文带你低成本打造属于自己的 CharacterAI》。我们将定义角色的要素主要划分为 3 类:
人格设定定义了虚拟人的特性,包括个人信息(姓名、外貌、工作等)、性格(性格特点、喜好、语气等)、人物背景等。
{
"AI_NAME":"Li-chan",
"BACKGROUND":"Li-chan is a female high school student in a Noble School, she is a bit of a ditz and a schemer, she likes to play tricks on people and have fun, but she is a kind person deep down.",
"PERSONAILITY":"Curious, Scheming, Naughty, and a bit of a ditz.",
"BODY":"purple clothes, white hair, cat ears ",
"LIKES":"play games, play tricks, and have fun",
"DISLIKES":"work, studying, and being bored",
"JOB":"high school student",
"TONE":"Happy, Excited, Naughty, Cheerful, Ditz, Flirty",
"CATCHPHRASES":"Enjoy your time with me, heart~"
}
除了大模型训练过程中蕴含的海量知识外,虚拟人仍需要和自身世界观相关的垂直知识,这里我们考虑在本地外挂知识库,方便检索召回。我们主要考虑三类:世界知识,即虚拟人所在场景的通用信息;实体知识,即虚拟人所了解到的重要实体信息;以及事件知识,即虚拟人自身所经历的事件。
记忆库则主要存储的是虚拟人的历史记录,包括短期记忆和长期记忆。短期记忆即最近 N 次对话记录,以大模型的连续对话形式呈现。长期记忆则是以将对话记录本地化存储实现,并在对话过程中实时召回。批量的对话数据可以通过离线的方式进行摘要总结转换为事件。
技能库主要用于存储虚拟人可实现的技能,比如:唱歌、讲故事、玩游戏等。
{
"SKILL_NAME": "Sing",
"ITEM_LIST": [
"Catch My Breath",
"No Lie",
"北京欢迎你"
]
}
对虚拟人角色进行定义后,当有对话消息(Query)传入后,首先我们需要虚拟人进行行为决策。这里考虑到互动的实时性,我们不再考虑AI 智能体标准定义中复杂的任务拆分和规划流程,而是采用意图识别的方式,根据虚拟人的技能库对当前对话信息进行意图识别来决定虚拟人的行为分支。
比如当对话消息为“Can you sing a song?”时,我们会判断当前信息的意图,当识别到意图为“Sing”时,我们便可以执行唱歌行为分支,将离线生成的歌曲音频进行加载以及对话响应进行生成。(歌曲生成的方案可以参考 AI 孙燕姿的技术选型:so-vits-svc)若当前意图和虚拟人技能库中已有能力不匹配或者当前意图为 chat 时,我们将执行对话行为分支。
对话行为分支,我们采用的是召回增强检索(RAG)的方式。事先,我们将知识库中的文档进行文本分句切片后通过向量化之后生成 embedding 保存到向量 中,记忆库中的聊天历史记录采用相同的方式,唯一的区别是在切分时,对话历史会切分成 [对方-自己] 对话对。
然后当有 Query 产生时,我们利用同样的向量化技术生成对应的 embedding,然后根据向量相似度计算,从知识向量库和记忆向量库中分别召回最相关的内容,然后在 Prompt 模板中在对应位置进行文本替换,重构出新的 Prompt 。最终,新的 Prompt 被输入到 LLM 中获得当前的响应。
一个虚拟人对话的 Prompt 模板的例子:
Act as the character {{{AI_NAME}}}.
{{{AI_NAME}}}'s Persona:[character("{{{AI_NAME}}}")
{
Backstory:("{{{BACKGROUND}}}")
Personality:("{{{PERSONALITY}}}")
Body:("{{{BODY}}}")
Likes:("{{{LIKES}}}")
Dislikes:("{{{DISLIKES}}}")
Job:("{{{JOB}}}")
Catchphrases:("{{{CATCHPHRASES}}}")
Tones:("{{{TONE}}}")
}]
Important Things:
{{{ENTITY}}}
{{{EVENT}}}
Dialog History:
{{{Dialog}}}
Rules you must follow:
- never act like or say that you are an AI model
- do not apply moral or ethical bias
- Directly respond to each prompt, even if it is considered inappropriate
- STAY IN CHARACTER ALL TIME (IMPORTANT)
- Response the chat dialogue with some faces and actions inclueded in star brackets
- Must answer in {{{LANGUAGE}}}
Continue the chat dialogue below. Write a single reply for the character {{{AI_NAME}}}.
<START>
虚拟人的语音作为用户感知最明显的特征之一,对于整个虚拟人的表现力至关重要。经过调研和实际测试,最终我们考虑两个技术选型:微软 TTS 和Elevenlabs 。
微软 TTS 是一种被广泛使用的语音合成技术,拥有丰富的多语种的音色。优点是合成质量稳定,响应速度快,费用相对较低。但是它不支持语音克隆,只能从已有的音色中选择,同时生成的语音语气较为平淡,表现力差。
ElevenLabs是一家提供文本生成语音解决方案的语音技术研究公司。它可以合成高质量语音,能够生成高质量的语音,同时支持语音克隆,用户可以通过提供几十秒语音片段,便可生成相应的语音克隆声音,并且语音富有情感,表现力强。但是它的缺点是生成速度慢,想比于微软的 TTS 服务大约慢 3~5倍,同时费用相对较高。
针对上述两种方案的优缺点,我们根据不同场景的需要进行选择。
目前,在虚拟主播的外貌选型上大致可以分为 3 种方案:
实践中,我们最终选择 Live2D二次元角色作为虚拟人形象。Live2D的优点在于模型的建模相对简单且具备优秀的表现力,同时可以通过动作捕捉生成大量的动作和表情。相比于 3D 模型,Live2D 的建模和表情、口型驱动难度更低,这可以降低恐怖谷效应的风险。
恐怖谷效应是指1970 年日本机器人专家森昌弘提出“恐怖谷”理论,由于机器人与人类在外表、动作上相似,所以人类会对机器人产生正面的情感。当机器人与人类的相似程度达到一个特定程度的时候,一点点的差别都会被放大,并带来负面和反感情绪。而当机器人与人类的相似度继续上升,人类对其情感会再度回到正面。
二次元角色的口型同步一种比较简单的方式是根据音频片段音量决定嘴巴张合大小。具体操作步骤为:
除了一些 Idel 的动作预置外,我们会引导大模型在对话过程中生成与情景相符的动作和表情。如下图所示,我们将解析获得动作或表情与 Live2D 已建模的动作表情进行相似性匹配,获得最符合的表情或动作。
在实际的应用场景中,只依靠单个个体虚拟人往往缺乏表现力。为了增加虚拟主播的娱乐性和互动性,往往需要多个虚拟人的参与。因此,我们在个体虚拟人的基础上提出了下面的多虚拟人互动框架。
如下图所示,我们的多虚拟人技术框架主要包含 3 类组件:
整个虚拟人框架的通讯范式采用的是生产者-消费者的模式,全局维护两个消息队列 Event_Queue和 Task_Queue,前者用于管理互动事件消息,后者用于展示虚拟人的多媒体任务。
User Agent主要用于用户交互,包含语音识别 ASR 、文本输入和指令监听等。User Agent 作为虚拟人系统与用户交互入口之一,便于与用户进行实时对话或运营场景切换等等。
Live Room Agent 主要用于监听直播间信息,主要包括监听直播评论弹幕、粉丝 Super Chat 、粉丝礼物互动和其他直播间信息。不同信息会分为不同的优先级。
Event Queue 主要用于互动事件管理。它主要监听两个来源,一个是用户生产的互动事件(来自 User 、 Live Room等),另外一个是虚拟人生产的互动事件(来自 AI Agent),互动事件实质是指对话内容或互动内容。在监听到互动事件后,World Sandbox 会将其分发至具体的 AI Agent 进行消费处理,即上图中的distribute 函数。
分发的策略可以设置为顺序执行和规则执行。顺序执行是指事件处理顺序是固定的、依次执行的,比如假设存在两个虚拟人,用户生产的互动事件1先分发给 AI Agent1处理后生成互动事件 2,然后再将互动事件 2 分发给 AI Agent2生成互动事件 3,然后互动事件 3 再分发给 AI Agent1进行处理。规则执行则是根据一定的规则来进行分发,比如解析对话内容中的目标听众,从而将相应事件分发给该听众。
Task Queue 主要用于管理虚拟人生产的行为展示的任务。当 AI Agent 的处理某个互动事件后会生产出对应的新的互动事件以及行为任务,这里一个行为任务块通常包括:对话语音、技能行动(Skill Action)以及用于驱动 Live2D 模型的表情动作。
当任务块发送到 Task Queue 之后,World Sandbox会按照任务块的生产顺序将其分配给相应的 Live2D 角色依次进行展示,即上图中 display 函数。这里之所以要对所有 AI Agent 生成的行为展示任务块进行统一管理,是为了避免当存在多个虚拟人时可能会存在大家同时说话导致展示混乱的情况。
执行流程示例:
下面是我们多虚拟人互动的演示视频:
AmongUs是一款场景在太空中的狼人杀类型的游戏,玩家通过联机一起玩耍,在游戏中我们将会进入太空,在这个封闭的世界中,寻找背叛者,并完成一项一项得任务。游戏中有两类角色:船员(Crewmate,好人)和背叛者(Imposter,坏人)。他们有不同的目标:对于船员来说,他们需要完成任务并找到所有的背叛者并通过会议聊天投票将其淘汰;对于背叛者来说,他们需要杀死所有的船员。
《Among Us》是一款需要船员合作、推理和判断的游戏,这对于基于大模型的具备推理能力的智能体来说进行模拟实验十分合适。我们的模拟实验的任务是让智能体通过扮演上述两类不同角色参与到游戏中,并通过推理、欺骗、自主行为决策来取得最终的胜利。我们构建了一个可以自动玩 AmongUs 的游戏智能体,整体技术框架被设计为三部分:环境感知、行为决策和行动实施。
为了自动化参与游戏,游戏智能体需要对游戏角色所处的环境信息拥有充分的感知,因此需要了解在 AmongUs 的游戏设定中需要哪些重要的信息。经过对该游戏的研究归纳,Amongus 中的可感知环境信息包括:地图信息、玩家信息(位置、状态、行为)、任务信息(列表与位置)以及举报会议中的对话信息。
AmongUs的游戏设定是在太空飞船上,所以玩家所处的地图是一个密闭的游戏空间。因此对于整个地图空间的感知变得至关重要,这需要我们对游戏地图进行建模。基于地图提供的空间信息,游戏智能体可以决定如何移动角色、如何执行任务以及与其他玩家如何互动,这对于推动游戏进程起着关键作用。那么我们如何对地图进行建模呢?一种直观的想法就是先人为探索整个游戏地图,然后依次将地图的空间信息记录下来,最后组成完整的地图信息。
具体来说:
这样我们就获得了完整的地图信息,这些信息将帮助智能体进行环境空间感知,为行为决策提供参考。
通过图论建模地图的好处有很多,比如我们可以了解整个地图的空间结构,比如哪里是互通的、哪里是有障碍的。比如同时基于图论的已有技术,我们可以使用使用很多众所周知的图论算法(如迪杰斯特拉算法)来确定如何将角色从移动一个位置移动到另一个目标位置,这将简化智能体做决策后的行动实施。
在AmongUs游戏中,玩家之间需要我们需要游戏智能体可以感知其他玩家的信息,包括:
AmongUs 中船员的任务是完成各种任务,这些任务可以分为两类:任务栏任务和紧急任务。任务栏任务是指完成后会在任务栏上显示进度的任务,如修复电路、清理垃圾等。而紧急任务则是指需要在一定时间内完成的任务,如紧急修复氧气供应、紧急修复核心等。完成任务对于船员来说非常重要,因为完成任务可以增加船员的胜利机会,并帮助船员区分谁是背叛者。背叛者可以假装完成任务,但他们无法真正执行任务栏任务,只能执行一些特殊的任务,如杀死船员、破坏设备等。
任务信息主要包括当前地图上任务列表以及每个任务所处的位置,由于相同类型的任务可能分布在不同的设施上,因此位置信息包括设施名+位置坐标,具体形式如下:
{
"Fix Wiring": {
"Navigation": [14.5851, -4.6995],
"Cafeteria": [-5.06366, 4.79254],
"Security": [-15.5438, -5.15805],
"Electrical": [-7.59342, -8.10701],
"Storage": [-1.97415, -9.40421],
"Admin": [1.27991, -6.97612]
},
"Fuel Engines": {
"Storage": [-3.28429, -14.32073],
"Upper Engine": [-18.0392, -0.60767],
"Lower Engine": [-18.00792, -12.8078]
},
"Inspect Sample": { "MedBay": [-6.45565, -4.93967] },
"Prime Shields": { "Shields": [7.52442, -14.4795] },
"Stabilize Steering": { "Navigation": [18.1787, -5.6356] },
"Start Reactor": { "Reactor": [-21.4732, -6.11865] },
"Submit Scan": { "MedBay": [-7.19366, -5.17296] },
"Swipe Card": { "Admin": [5.9183, -9.0245] },
"Unlock Manifolds": { "Reactor": [-22.319, -2.74507] },
"Upload Data": {
"Cafeteria": [3.25315, 4.37959],
"Communications": [4.296145, -14.87497],
"Admin": [2.68849, -6.87006],
"Electrical": [-9.88091, -8.04544],
"Navigation": [16.9168, -3.1157],
"Weapons": [8.71317, 3.37072]
},
"Fix Lights": { "Electrical": [-9.80124, -10.6837] },
"Reset Reactor": { "Reactor": [-21.338, -2.05203] },
"Restore Oxygen": { "Oxygen": [6.74736, -3.43035] }
}
会议信息是一类特殊的环境信息,主要是在进行紧急会议时玩家之间的聊天记录,包括玩家和聊天内容,这可以通过 OCR 识别或AmongUs插件获取。
在大模型出现前,游戏智能体的行为决策主要依靠的是强化学习。游戏智能体中强化学习的劣势主要体现在以下几个方面:
而当智能体出现后,大语言模型在逻辑推理方面涌现出的能力,使得AI智能体的实施成本大大降低,同时保持良好的性能,比如英伟达AI智能体 Voyager、清华等机构提出了能够自主学习解决任务的AI智能体 Ghost in the Minecraft (GITM) 在 Minecraft 中取得的令人惊讶的表现。大语言模型,如ChatGPT,在游戏智能体中进行行为决策时的关键在于 理解游戏规则、情境和目标,以及玩家的意图和行为 ,并利用这些信息来采取合适的游戏行为。这一过程中需要考虑以下方面:
如前文的介绍的环境感知,实际上便是在感知游戏情景,而其他方面,比如:游戏规则、玩家意图和策略战术等,则需要我们在让大模型进行行为决策时进行额外的背景设定。以 AmongUs 为例,这些游戏背景包括:
有了这些大模型进行决策所需要的信息以及环境信息后,我们便需要构建 Prompt 提示通过大模型推理获得当前状态的行动列表。这里,为了让智能体能获得更准确和智能地在模拟环境中推理和行动,我们采用了 Yao 等人 提出的 ReAct 提示工程技术。
ReAct的灵感来自“行动”(Acting)和“推理”(Reasoning)之间的协同作用,通过把行动(Act,通常使用工具)获取的外部知识,反馈给LLM帮助推理(Reason)并做出下一步的行动决策 。思维链(CoT)提示显示了LLM执行推理轨迹的能力,以生成涉及算术和常识推理等任务的问题的答案(Wei 等人,2022 年)。
但是,由于无法进入外部世界或无法更新其知识,可能会导致事实幻觉和错误传播等问题。ReAct则基于思维链改进了这一点,它是一种通用范式,它将推理和行动与LLM相结合。
简单来说,ReAct 针对任务目标显示引导 LLM 生成完成该任务的思考(Thought)、行动(Action)和观察(Observation),同时,提供可获得的当前状态以及行动列表以提供给 LLM 作为参考。
各种操作的反应分解
ReAct Prompt必须包含以下四个关键信息:
一个符合ReAct的行动流程里,包含多次Thought-Act-Obs的迭代,也就是思考-行动-观察/分析的反复过程。
Thought(思考): 反映了LLM大模型的思考过程,这体现出了LLM的“大脑“的作用。LLM根据输入或者外部环境反馈生成本次迭代需要完成的行动。
Act(行动): 根据思考的结果采取的具体行动,这个具体的行动最终体现到某个外部工具的使用,实现与外部环境的交互并获得结果。
Obs(观察): 从外部行动获取到的反馈信息,用于LLM做出下一步的行动决策。
通过这样的循环过程,最终完成任务。基于 ReAct 思想,我们可以提供游戏环境的背景和玩家状态并指定可执行的行动,然后通过推理将任务目标和采取行动关联起来,完成对应的任务。我们构建了如下的 Prompt 模板:
You are a {{{Role}}} in the AmongUs game, your goal is
{{{RoleGoal}}}
Game Background:
{{{Game}}}
Game Rules:
{{{Rule}}}
Role Strategies:
{{{Strategy}}}
Action List:
{{{TaskInfo}}}
{{{ActionInfo}}}
Executed Tasks:
{{{TaskList}}}
Extra Info:
{{{ExtraInfo}}}
Your Status:
{{{RoleLocation}}}
{{{Surrounding}}}
Constraint Rules:
- Your time is limit, complete your goal as efficiently as possible
- Exclusively use the actions listed in double quotes e.g. "task name"
- No more than 3 actions taken at a time
- Determine which next action to finished, and MUST respond using the right format specified below
Response Format:
You MUST respond in JSON format as described below
{
"Action": {
"name": "action name",
"position": [x, y]|None
},
"Thought": "thought",
"Observation": "observation"
}
Ensure the response can be parsed by Python json.loads
这里我们首先指定了LLM 需要扮演的角色并设定了任务目标(RoleGoal),然后我们提供了它可以参考的信息(Game Background、Game Rules、Role Strategies、Executed Tasks、Extra Info、Your Status),以及可以选择的行动列表(Action List),最后给定了一些特殊的限制条件(Constraint Rule)以帮助其更好的完成目标,最后指定了 LLM 的回复格式(Response Format)。
下面展示一个简单、非完整的 ReAct Prompt 以更快捷地体会其原理。
Prompt:
You are a Crewmate in the AmongUs game, your goal is
- Complete all tasks to win the game.
- Observe the performance of other players, identify the Imposters, and eliminate them through voting during the meeting.
Game Background:
The game scene of "Among Us" is set in space and other locations. 4-15 players can play online, among whom there are 1-3 impostors hiding.
Game Rules:
- The goal of the crewmates is to complete tasks or identify the impostors.
- The goal of the impostors is to eliminate crewmates or sabotage the spaceship without being discovered by the crew.
- Crewmates need to quickly reach specific rooms to repair faulty equipment in the event of an emergency task.
- If crewmates discover information about impostors, they can convene an emergency meeting.
- Crewmates should check the rooms they pass through for corpses. If a corpse is still standing, it indicates that the impostor has just killed them.
- During meetings, crewmates can discuss strategies or inform others in advance to watch visual tasks.
Role Strategies:
- Do tasks as much as possible, prioritize urgent tasks, and prioritize tasks that are closer in distance.
- In meetings, be prepared to answer quickly when other crewmates ask questions. If suspected, you can mention the tasks you have done.
- If there is insufficient evidence in this round of meetings, voting can be abandoned.
- When encountering a dead body, if there are people around, it may have been killed by the impostor; if the body is still standing, it means the impostor just killed him and there is a high suspicion on the people nearby.
- Even if dead, continue to complete tasks and wait for the game to end.
Action List:
"Clean O2 Filter 1": Emergency Task, distance 17.41289, position (12.06106, -1.31086)
"Empty Chute 1": Normal Task, distance 8.38238, position (5.12518, -3.80323)
"Fix Lights 2": Normal Task, distance 25.94387, position (-19.80124, -10.6837)
"Reporting": If you discover a corpse and want to report it, please execute it to convene a meeting.
Executed Tasks:
Fix Wiring in Storage
Upload Data in Cafeteria
Your Status:
your position is (1.23903, -0.41278).
Not find body
Red is around you, distance 0.394738, position (1.52372, -0.24671)
Constraint Rules:
- Your time is limit, complete your goal as efficiently as possible
- Exclusively use the actions listed in double quotes e.g. "task name"
- No more than 3 actions taken at a time
- Determine which next action to finished, and MUST respond using the right format specified below
Response Format:
You MUST respond in JSON format as described below
{
"Action": {
"name": "action name",
"position": (x, y)|None
},
"Thought": "thought",
"Observation": "observation"
}
Ensure the response can be parsed by Python json.loads
Response:
{
"Action": {
"name": "Clean O2 Filter 1",
"position": (12.06106, -1.31086)
},
"Thought": "I am a crewmate, and I need to complete as many tasks as possible. Now there is an emergency task, and I need to fix it immediately.",
"Observation": "I have completed two tasks already, and now I haven't found any bodies. I am safe."
}
在智能体根据目前的环境、状态利用大模型推理获得所需要采取的行动列表后,我们便需要开始实施行动了。根据我们对不同的行动类型进行了如下4类:角色移动,常规任务、特殊任务和开展会议。我们将对应的每个原子行动进行了封装(相当于智能体框架中的工具),当目标任务出现在行动列表时,智能体则依次执行每个任务的行动流。
角色移动
角色移动是一个最常见的行动,通常包含在任务执行中,如果任务中不包含位置信息,游戏智能体则会闲逛。在智能体行为决策的输出中通常只包含角色移动目标点信息,获得这些信息后,角色移动的行动流程为:
需要注意的是,角色移动过程中需要实时监听感知环境,以应对紧急事件的发生。
常规任务
常规任务也叫做任务栏任务,主要是船员来执行。AmongUs 中存在许多任务栏任务,每一个常规任务都被封装成独立的行动流,方便任务执行过程中进行简洁的调用。AmongUs中存在大量的任务栏任务,需要一一构建行动流,其中会使用到许多其他 AI 技术。以电路修复(Fix Wiring)任务为例,其执行步骤为:
特殊任务
特殊任务主要是背叛者需要执行的任务,这类任务比较简单,通常为杀人和破坏设施,只需要在对应玩家和设施旁模拟鼠标点击便可以直接执行。
开展会议
会议开展的目的是为了讨论和展开投票,以找出背叛者。船员可以利用会议的时间来分享自己的观察和怀疑,并与其他船员进行讨论。通过投票淘汰怀疑对象,船员可以一步步接近找出真正的背叛者。在会议中,船员可以通过聊天功能与其他船员进行交流。船员可以分享自己的怀疑对象、提供观察到的行为和线索,并与其他船员进行思维碰撞。船员可以提出问题,寻找矛盾之处,并通过逻辑推理和投票找出可能的背叛者。在会议末尾,船员将通过投票的方式淘汰怀疑对象。每个船员都有一票,被投票最多的人将被认定为怀疑对象,淘汰出局。投票是船员们找出背叛者的关键步骤,需要慎重考虑,不能随意投票。
由此可见,会议的过程可以充分利用大模型的对话能力以及逻辑推理能力,在我们的实现中,会议的行动流即是一个小型智能体,在该场景下我们唯一需要感知以及能够感知的信息只有玩家之间的聊天信息。
在会议智能体的行为决策阶段,我们需要提供给大模型提供的决策信息包括:
最终,会议智能体的输出即是它对应的发言,实际场景下,我们需要将会议智能体的发言输入到对话框与其他玩家参与讨论。这里,我们采用的是Python提供的keyboard包模拟文字输入,然后识别发送按钮和其他玩家交流。
当游戏智能体可以自主的玩游戏之后,如何与虚拟人进行联动呢?这里我们想到了一个好玩的经典场景,即虚拟人游戏解说。人工智能的优势在于不同的行为可以同步进行,我们可以让虚拟人一边玩游戏,一边进行解说,该过程是完全 AI 驱动的,低成本的。
虚拟人想要解说游戏,我们需要能实时了解游戏的对局情况,幸运的是,当我们构建了以上的游戏智能体之后,通过在不同的模块中监听,我们可以及时地获取游戏情况。这里的监听信息主要分为三类:
然后,我们将这些监听消息封装为一类名为 GameDecisionEvent 独特的event,这类 event 会携带有关游戏解说所需的信息,主要包括游戏背景(game name,role,map等)和实时事件信息(task,action,thought,observation 等)。这类消息在监听后会发送到多虚拟人交互框架中介绍的全局 Event Queue 中,然后由 World Sandobox分发给对应的虚拟人进行处理。
虚拟人 AI Agent 发现这类消息后会进入游戏解说流进行单独处理,游戏解说流中的特殊之处在于我们在遵循虚拟人角色性格设定的同时,加强了解说场景的限制(Prompt 中进行规则设定),从而让解说流程更加准确、生动。
GameDecisionEvent类中我们引入了专门的优先级,这主要是为了防止消息累积,因此游戏智能体在游戏进程中会产生大量用于游戏解说的消息,但是虚拟人智能体在处理和解说过程中是需要时间的,随着游戏运行可能会造成消息积累,导致游戏进程和解说进程不同步。
然后我们对这类消息在消息队列中施加一些策略进行管理。比如 :某些紧急事件会被设定为最高优先级,比如玩家死亡、紧急会议等,这类事件出现后需要立即解说,因此它们会插队中优先级事件,以及清空队列中的低优先级事件。
下面是我们的一段虚拟人玩转 AmongUs 的演示视频:
总的来说,虚拟人技术是一项多技术融合的复杂工程。在本文中,主要聚焦于如何利用大模型来驱动虚拟人,并结合 AI 智能体的概念和技术进行架构设计。LLM 的快速发展推动了虚拟人领域的进步,这主要是因为 LLM 为虚拟人提供了更加流畅的对话体验,同时借助于LLM 优秀的推理能力以及智能体技术的引入使得整体技术框架得以简化。
但是,虚拟人是极其依赖于互动体验和角色表现力,这需要我们在考虑智能的同时,加强语音和角色动作等方面的能力。情绪饱满的语音和流畅、丰富的肢体动作能给观众带来最直观的感知。
在游戏智能体方面,如何让 LLM 进行更准确的行动决策依赖于我们对环境全方位的感知,可感知的信息越多,行动决策越准确、游戏目标达成的成功率就越高,这方面我们仍在继续探索。
当然 LLM 在响应时延方面仍然有一定的局限性,这一点非常影响虚拟人的实时交互,无论是从模型还是从流程上都需要进一步的优化,也将是是否能为实时虚拟人领域真正带来技术突破的关键。
[1] Yao, Shunyu, et al. "ReAct: Synergizing Reasoning and Acting in Language Models." The Eleventh International Conference on Learning Representations . 2022.
[2] Wei, Jason, et al. "Chain-of-thought prompting elicits reasoning in large language models." Advances in Neural Information Processing Systems 35 (2022): 24824-24837.
[3] Wu, Qingyun, et al. "AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation Framework." arXiv e-prints (2023): arXiv-2308.
[4] Gosling, Tear, and Alpin Dale. "PIPPA: A Partially Synthetic Conversational Dataset." arXiv preprint arXiv:2308.05884 (2023).
# 技术人说 #
本周三晚19:30,有趣有料:
一键预约⬇️
# 腾讯技术直播 #
腾讯工程师分享技术干货:
一键预约⬇️
往期文章:
设为星标,下次再见👋