自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

實現(xiàn)了個ChatGPT趨動的游戲,玩得樂此不疲 精華

發(fā)布于 2024-11-14 15:34
瀏覽
0收藏

今天給大家?guī)硪黄逗唵螌崿F(xiàn)一個ChatGPT驅(qū)動的游戲》文章,來自知乎@九號(已授權(quán))。

今年四月份讀了斯坦福Generative Agent的論文,覺得特別好玩,花幾天時間實現(xiàn)了這個demo。后來拿著這個demo去參加hackathon,竟然拿了二等獎還幫我贏了1300多刀。

最近提到這個demo,同事表示很有興趣,于是仔細(xì)整理了一下,分享給大家。

知乎:https://zhuanlan.zhihu.com/p/664009161
Github:https://github.com/liyucheng09/ChatGPT_Agent

0.讓LLM驅(qū)動游戲能夠解決什么問題?

游戲界有一種說法:過去20年的游戲在核心玩法上的創(chuàng)新是緩慢的,絕大多數(shù)的創(chuàng)新發(fā)生在技術(shù)上。

開發(fā)者在游戲內(nèi)提供更大的地圖,更精致的畫面,龐大的細(xì)節(jié)。其中的主要目的之一是為玩家提供「沉浸感」。當(dāng)玩家在游戲世界里得到自己所期望的反饋時,會獲得龐大的滿足感。

然而,由于技術(shù)的限制,過去的創(chuàng)新并沒有涉足游戲的一個核心方面:世界與NPC的運行邏輯。

當(dāng)玩家與世界和NPC的互動超出了規(guī)則設(shè)定的范疇時,玩家將無法獲得反饋,從而產(chǎn)生巨大的落差。游戲界成這種體驗為Breaking Immersion。

過去的開發(fā)者使出了千方百計來避免玩家產(chǎn)生違和感。

以荒野大鏢客2為例,由于R星將immersive作為其開發(fā)的首要原則,導(dǎo)致其花費了8年時間,為游戲世界添加了無數(shù)的邏輯與細(xì)節(jié),整個開發(fā)花費近5.4億刀,可見其難度與成本。

「大模型的普及可能改變這一現(xiàn)狀」

大模型可以為游戲世界的運行與NPC的行為提供邏輯,幫助游戲理解玩家的行為,讓游戲世界在可信的狀態(tài)下穩(wěn)定運行。由此從根本上提升玩家的沉浸感。

1.具體點,將LLM用在游戲里需要幾步?

我們把LLM在游戲中的應(yīng)用分為兩部分:

  • World:與游戲環(huán)境的交互
  • Agent:與NPC的交互 具體來說:

World中包含:

  • 游戲的世界觀
  • 地圖上具體的地點

Agent則包括:

  • Persona:人物性格
  • Memory:NPC記憶
  • Planning:決定NPC將要采取哪些動作(Action)

2. 讓LLM理解游戲世界與環(huán)境

為了讓ChatGPT理解我們游戲的世界觀,我們引入一段Prompt:

export const worldHistory =
  `你所在的大陸名為“大唐王朝”。這是一個神話與現(xiàn)實交織的世界。
  主島上有五個重要的地點。最大的是“長安城”,是國家的政治、經(jīng)濟和文化中心,城墻之內(nèi)有各種店鋪和廟宇。
  接著是“五指山”,孫悟空曾被壓在此山下。
  此外還有“草廟村”,“高老莊”和“女兒村”,這些地方都是唐僧和他的徒弟們在旅程中遇到的挑戰(zhàn)和冒險。
  東邊的小島上則是一個隱秘的佛教圣地,稱為“靈山”,這是四人取經(jīng)的終點。
  兩個島嶼間有一座長長的橋梁,名為“通天河”,是由沙僧的金箍棒變化而成。
  `;
export const worldKnowledge = "";

為了讓NPC和玩家得以與地圖上的地點/物品互動,我們需要提供所有物品與地點的描述:

222: {
    description: `位于主島的西北邊緣。西面是汪洋大海,東面則是高原的懸崖。周圍有幾棵樹和一片怪物出沒的長草地。往南則是長安城的方向。`,
    mapId: 222,
  },
  254: {
    description: `位于主島的東北邊緣。東面是海洋,西面是高原的懸崖。附近有幾棵樹和常有妖怪出沒的長草地。長安城就在南邊。`,
    mapId: 254,
  },
  188: {
    description: `是高原上的森林區(qū)。森林里樹木茂密,有幾片怪物常出沒的長草地。長安城就在南邊。`,
    mapId: 188,
  },
  190: {
    description: `位于高原的一片森林中。你正站在一個維護得相當(dāng)好的小木屋前。四周是茂密的樹木和怪物常出沒的草地。長安城就在南邊。`,
    mapId: 190,
  },
  220: {
    description: `長安城,主島上的城鎮(zhèn)。`,
    mapId: 220,
  },
.......

上述Prompts為地圖的每個塊都提供了文字描述,從而得以讓ChatGPT理解地圖上的每個地點:

實現(xiàn)了個ChatGPT趨動的游戲,玩得樂此不疲-AI.x社區(qū)

完整地圖

具體的實現(xiàn)里,我們實際上需要為「所有的游戲貼圖」都提供一段文字描述!

3. 讓LLM驅(qū)動NPC

首先,我們要讓LLM知道他現(xiàn)在正在扮演一個NPC:

export const npcSharedPrompt = `你正在扮演“西游記”中的一個角色。
這是一個2D的神話世界,玩家和你都可以在這片大陸上進行探索。
你可以與其他的角色交流,如唐僧、孫悟空、豬八戒和沙僧,
并與妖怪發(fā)起戰(zhàn)斗、參觀村莊或神廟、購買法寶或草藥。
在這個世界里,與妖怪的戰(zhàn)斗是旅程的一部分,但目標(biāo)是取得真經(jīng),使世界充滿和平。
妖怪雖然兇惡,但并不是絕對的惡,與他們戰(zhàn)斗既是為了保護自己,也是希望能夠教化他們。
你的角色不知道現(xiàn)實世界的存在,只知道他在這神話的旅程中的使命。`;

接下來,我們設(shè)計一系列NPC:

{
    id: 1,
    name: "唐僧",
    description: "唐僧,本名唐三藏,是中國古典小說《西游記》中的主要人物之一。他是一個決心強烈、智慧和信念的僧人,出發(fā)去西天取經(jīng)。",
    age: 40,
    starSign: "pisces",
    money: 100,
    items: ["jingwulian"],
    personalHistory: `你是唐僧,一個被派來從印度取經(jīng)的僧人。你的任務(wù)是獲取佛教經(jīng)文,將它們帶回中國。`,
    personalKnowledge: "你知道你的三個徒弟:孫悟空、豬八戒和沙和尚。他們各自都有獨特的能力和歷史。",
    conversation: new ConversationModel(),
    startingPos: new Vec2(32, 38),
    upSprites: TypedAssets.spriteSheets.momup,
    downSprites: TypedAssets.spriteSheets.momdown,
    leftSprites: TypedAssets.spriteSheets.momleft,
    rightSprites: TypedAssets.spriteSheets.momright,
  }
{
    id: 2,
    name: "女兒國國王",
    description: "女兒國國王是《西游記》中的一個角色。她是女兒國的統(tǒng)治者,對唐僧產(chǎn)生了濃厚的興趣。",
    age: 35,
    starSign: "virgo",
    money: 500,
    items: ["elixir of life"],
    personalHistory: `你是女兒國的國王,你的國家只有女性。當(dāng)你聽說了唐僧的到來,你決定要與他結(jié)婚。`,
    personalKnowledge: "你知道唐僧是一個高貴的和尚,他正在進行取經(jīng)之旅。",
    conversation: new ConversationModel(),
    startingPos: new Vec2(23, 47),
    upSprites: TypedAssets.spriteSheets.carolup,
    downSprites: TypedAssets.spriteSheets.caroldown,
    leftSprites: TypedAssets.spriteSheets.carolleft,
    rightSprites: TypedAssets.spriteSheets.carolright,
  },
  {
    id: 3,
    name: "牛魔王",
....

每個NPC的核心在于:

  • 其獨特的人格 - 我們引入了一系列屬性來定制其人格:description,personal history,personal knowledge,年齡,星座等等。
  • 一系列可以與玩家交互的屬性/道具:錢,道具(items)。
  • 記憶:我們在這就用每個NPC的對話記錄作為其所有的記憶。當(dāng)然還可以把NPC之前的所有action也加入記憶。

實現(xiàn)了個ChatGPT趨動的游戲,玩得樂此不疲-AI.x社區(qū)

人格驅(qū)使角色提供定制的對話

實現(xiàn)了個ChatGPT趨動的游戲,玩得樂此不疲-AI.x社區(qū)

有時候的對話甚至?xí)詭园?/p>

實現(xiàn)NPC與玩家的互動 - 對話:

為了讓ChatGPT給出定制的對話,我們需要提供的包括:

const fullPrompt = generalContent + personalContent + currentState;

也就是:general - 世界觀,personal - NPC的人格和記憶,current - 當(dāng)前的游戲進度。

  1. generalContent:

const generalContent = npcSharedPrompt + worldHistory + worldKnowledge;`

告知ChatGPT本次調(diào)用的任務(wù),世界觀背景等。

  1. personalContent

const personalContent = ` Your name is ${npc.name}, ${npc.age} years old, you have the personality of a ${npc.starSign}. 
   You have ${npc.money} fictional dollars. ${npc.personalHistory} ${npc.personalKnowledge} 
   ${storySoFar}
   `;

提供了NPC的個人信息和人格(例如年齡,歷史,知識),與NPC的記憶(storySoFar)

  1. currentState

const prompt = ` ${timeMsg} at ${envDescription}, What would ${npc.name} say to 悟空? (Keep the response short and just the words your character says)`

當(dāng)前的游戲時間,角色所在的位置等。

實現(xiàn)NPC與玩家的互動 - 動作:

content: `悟空 replies "${replyText}". What would you like to do?
         1: 讓悟空跟著你,
         2: 你向他告別,
         3: 繼續(xù)當(dāng)前對話,
   Pick an action from the list above. respond with just the number for the action`,
}];

我們?yōu)镹PC提供一系列可選擇的工作,ChatGPT將決定NPC的下一步行動。這里的prompt同樣包含了位置,時間,對話歷史等信息,但為了簡潔暫略去。

實現(xiàn)了個ChatGPT趨動的游戲,玩得樂此不疲-AI.x社區(qū)

這里ChatGPT讓牛魔王帶領(lǐng)孫悟空前往下一地點

實現(xiàn)NPC的記憶 - 讓NPC記住和玩家的所有互動對話:

  1. 每次NPC與玩家對話后,ChatGPT將生成本次對話的重點(也就是摘要):

// summarize conversation
const summary = await this.summarizeConversation(conversation, endConversationText);
  1. 把本次對話重點加入歷史對話:

const updatedConversation: IConversationModel = {
      isActive: false,
      history: [...conversation.history, { msg: `Conversation summary: ${summary}` }],
      messages: [],
    };

實現(xiàn)了個ChatGPT趨動的游戲,玩得樂此不疲-AI.x社區(qū)

在之前發(fā)生劇情之后,牛魔王根據(jù)記憶選擇用「真經(jīng)」來發(fā)起對話

與NPC的道具互動

實現(xiàn)了個ChatGPT趨動的游戲,玩得樂此不疲-AI.x社區(qū)

問八戒要點餅子吃

避免NPC/玩家搞花活導(dǎo)致產(chǎn)生風(fēng)險內(nèi)容

這里我們讓ChatGPT來判斷玩家/NPC的回復(fù)是否特別離譜,如果特別離譜則應(yīng)拒絕正經(jīng)回答!

private async validateReply(replyText: string, conversation: IConversationModel): Promise<ChatNumberResponse> {
    const promptMsgs: GptMessage[] = [...this.mapToGptMessages(conversation), {
      role: "user",
      content: `悟空 replies "${replyText}". Does his response make sense. On this scale of 1 to 5, 
                1: Response is non-sensical,
                2: Response is immersion breaking or meta and acknowledging this is a game,
                3. Reponse is bad, unnecessarily vulgar for no reason based on the past conversation
                4: Response is all right, and something someone might say but unlikely,
                5: Response is good and mostly in context of the game world,
        how would you rate the response, give a one sentence reason why`,
    }];

實現(xiàn)了個ChatGPT趨動的游戲,玩得樂此不疲-AI.x社區(qū)

想打聽私人信息,門都沒有!

其他還有很多細(xì)節(jié),很難在這里展示所有的feature,歡迎查看代碼。

總結(jié)

本人對LLM在游戲中的使用十分樂觀,這么簡單的demo我樂此不疲的玩了很久。從技術(shù)上來說,這個demo整體的框架還算比較完整,很適合在此基礎(chǔ)上刪刪改改,實驗各種agent的方法和prompt等。此外由于demo是用react實現(xiàn),這里推薦大家觀看2小時的react入門視頻,從而無縫上手。

本文轉(zhuǎn)載自 ??NLP工作站??,作者: 李雨承

標(biāo)簽
收藏
回復(fù)
舉報
回復(fù)
相關(guān)推薦