ダンジョンズ&ドラゴンズ: ビッグモデルへの道 テキストゲーム

ダンジョンズ&ドラゴンズ: ビッグモデルへの道 テキストゲーム

著者 | 崔昊

レビュー | Chonglou

まとめ

この記事の著者は、海外のブロガーに触発され、大規模な言語モデルを使用してダンジョンテキストゲームを作成してみることにしました。大規模な言語モデルを通じて、創造的で一貫性のあるゲーム コンテンツを生成します。彼のゲームのインスピレーションは、主に古典的なテーブルトップ ロールプレイング ゲーム「ダンジョンズ & ドラゴンズ」(D&D) から来ています。このゲームは会話中心で、ナレーターと主人公の 2 人のメインキャラクターで構成されています。ストーリーテラーはタスクを割り当ててストーリーを進める責任があり、主人公はタスクを完了する責任があります。著者らは、キャラクター間のやり取りとゲームの進行を処理するための対話シミュレーターを設計しました。さらに、著者はゲームデザインにおける 2 つの重要な問題、つまり記憶メカニズムと発話規範についても考慮しました。

導入

ショートビデオプラットフォームで、外国人ブロガーがAIによるシミュレーションビジネスゲームを作成しているのを見て以来、深く魅了されてきました。彼の仮想都市では、AI の力により多数の NPC キャラクターがユニークな個性を持ち、キャラクター間のやりとりは楽しさと驚きに満ちています。ちょっとうずうずしてきました。私は昔からゲームが大好きなので、AI の力を使って自分だけのダンジョン テキスト ゲームを作ってみるのはいかがでしょうか。しかし、ゲーム開発の経験不足が私にとって障害となりました。しかし、よく考えてみると、私は現在、それ自体がテキストを生成する機能を持つ大規模な言語モデルの開発に取り組んでいます。 ヒントや大きなモデルを使ってテキストアドベンチャーゲームをプレイしている人も見かけました。このアイデアを念頭に置いて、いくつかの情報を調べたところ、プロンプトを通じて大きなモデルを実際に「催眠術」にかけ、ゲームの世界を作成するのに役立てることができることがわかりました。

探索して試す

上記のアイデアが浮かんだら、それを実行に移し、言ったらすぐに実行する必要があります。ただし、始める前に、ゲームを構想し、その実装の実現可能性を評価する必要があります。私の探求は ChatGPT から始まりました。私は ChatGPT で手動入力して単語ゲームをしました私はすぐに、それが人気ゲーム「ダンジョンズ&ドラゴンズ」と類似していることに気付きました。ダンジョンズ&ドラゴンズは、プレイヤーが難解な問題の解決、大胆なクエスト、激しい戦闘を通じてストーリーを進めていくロールプレイング ファンタジーの世界です。

ダンジョンズ&ドラゴンズ(D&D)は、1974 年に誕生したテーブルトップ ロール プレイング ゲームで、プレイヤーは中世のファンタジー世界を探索したり戦ったりすることができます。プレイヤーは戦士、魔法使い、泥棒などのさまざまなキャラクターを選択し、サイコロを振って行動の結果を決定します。ゲームは、ストーリーを導き、ゲームのルールを管理するダンジョン マスター (DM) によって主導されます。 D&D はテーブルトップ ロールプレイング ゲームの標準を作成しただけでなく、その後のビデオ ゲームやファンタジー文学の発展にも影響を与えました。集団的なストーリーテリング、問題解決、ロールプレイングを中核とし、豊かで想像力を駆使したゲーム体験をプレイヤーに提供します。

Dungeons & Dragons のゲームプレイ テンプレートに基づいてテキスト ゲームを設計できます私はゲームデザインの経験がないので、初心者の参入障壁を下げるために、ゲームのルールをシンプルで明確にし、キャラクター同士の会話を中心にゲームを進めていくように設計しました。ここでは、物語の語り手と主人公の 2 つの対話役割があります。対話の相互作用を通じて、プレイヤーは徐々にゲームの核心を掘り下げ、さまざまなタスクに挑戦して完了すると同時に、仮想キャラクターとのコミュニケーションの楽しさを楽しむことができます。

鉄は熱いうちに、テキスト ゲームが達成する具体的なタスクを設計しましょう。下の図に示すように、ワードゲームを初期化するときに、主人公(メインキャラクター)とストーリーのナレーターを含む参加者を定義する必要があります。ストーリーのナレーターはタスクを発行する責任があり、主人公はタスクを完了する責任があります。もちろん、タスクを完了するためにテキストを通じて相互に対話するため、ここでスピーキング ルールを定義する必要があります。語り手が課題を与えた後、主人公は話し続けて物語を進め、交代で話すことですべての課題を完了します。

準備中

アイデアが決まったら、開発に必要なモデルとツールを準備する必要があります。モデルにはOpenAIを選択しました 私はGPT -3.5- Turboバージョンを使用しました。また、Baidu Qianfanモデルライブラリで提供されているChatGLM2-6B-32Kモデルの使用も検討しました。しかし、前者は入力文字の長さに有利であるため、GPTを選択しました。ただし、次のコードセクションでは ChatGLM 2バージョンのコードをコメントの形で紹介します。ご興味があれば、自分で試してみてください。

ゲームの背景を念頭に置いて、すべてのテキスト ゲームが遭遇する 2 つの問題を考慮する必要があります。

記憶のメカニズム

ダンジョンクローラーでは、会話の一貫性を保ち、キャラクターのアイデンティティに一貫性を持たせることが重要です。この問題を解決するために、参加者の身元、話し方、すべきこと、すべきでないことなどの背景情報を保存できるメッセージ システムを設計しました。大きなモデルにヒントが提供されるたびに、このシステムを使用してモデルのメモリが強化され、スムーズなゲームプレイが保証されます。 LangChainシステムを使用するだけです メッセージ 機構は完成しました。

LangChain の `SystemMessage` は、大規模な言語モデルとの対話でコンテキストや指示を提供するために使用される特別なメッセージ タイプです。 `SystemMessage` を使用すると、ゲームに関する背景情報やその他の重要な指示をモデルに伝えることができ、モデルがシナリオに適した応答を生成するのに役立ちます。これは、インタラクティブなアプリケーションを構築するときにコンテキストとガイダンスを提供するための効果的な方法です。

スピーチ基準

ゲームを秩序正しく進行させるためには、明確な発言順序を設定する必要があります。この単純なシナリオでは、順番に話すというルールを選択しました。将来的に、より多くのプレイヤーやより複雑なインタラクション ルールに簡単に拡張できるように、スピーキング ルールを別のモジュールに分離し、ゲームの柔軟性を高めました。実装する場合はモジュロ関数を通じて簡単に行うことができます。複数の人が関与している場合、またはクロストークがある場合、またはプレイヤーが互いに質問する場合は、より責任ある発言ルールを設計することもできます。つまり、高い凝集性と低い結合性を実現するには、ルールを分離する必要があります。

プログラミング

ゲームデザインのアイデアを念頭に置いて、基本的なプログラムを設計しました。下の図に示すように、エントランスのメイン関数では、基本的なキャラクター情報や背景情報の定義など、ダイアログ パラメータを初期化します。次にDialogueSimulatorを呼び出します プレーヤーを追加し、発言ルールを設定し、タスクを開始します。次のステップはDialogueAgentを使うことです このクラスはテキスト メッセージを処理します。ここでは、メッセージの送受信のみを処理する必要があります。この場合、参加者は語り手と主人公の 2 人だけなので、メッセージの送信と紹介は 2 人の間で交互に行われます。

コーディング練習

基本的な設計作業が完了したら、コードを記述します。ここでは、IDE ツールとして Colab を使用し、この環境で Langchain と GPT-3.5 Turbo を設定して使用する方法について説明します。

Colab、または Google Colaboratory は、セットアップなしでブラウザで使用できる無料の Jupyter ノートブック環境です。信頼性の高いコンピューティング リソースを提供するだけでなく、機械学習やディープラーニング プロジェクトを加速するための GPU と TPU も搭載されています。 Colab の機能には、リアルタイムの複数人コラボレーション、無料の GPU リソース、簡単な共有、Google Drive との統合などがあります。 Colab を使用する主な理由は、その利便性と効率性です。環境設定の手間が省けます。

まず次のコードを使用して、パッケージと関連する依存関係を colab にインストールします。

 !pip install openai langchain

このコマンドは、後続の開発作業をサポートするために Python パッケージをインストールするために使用されます。

1. `openai`: OpenAI の Python クライアント ライブラリ。

2. `langchain`: おそらく、大規模な言語モデルとのやり取りをサポートする LangChain 関連のライブラリです。

DialogueAgent クラス

ChatOpenAI モデルのシンプルなラッパーで、メッセージを文字列として連結するだけで、dialog_agent が確認したメッセージの履歴を保存します。

次の 2 つの方法を提供します。

  • send(): チャットモデルをメッセージ履歴に適用し、メッセージ文字列を返します。
  • 受信(name, message): 名前で送信されたメッセージをメッセージ履歴に追加します。
 # 定义DialogueAgent类,用于表示对话中的一个代理(或参与者) class DialogueAgent: # 初始化方法,用于设置代理的基础属性def __init__( self, name: str, # 代理名称:参与者,故事描述者,主人公system_message: SystemMessage, # 系统消息对象model: ChatOpenAI, # 聊天模型) -> None: self.name = name # 设置代理名称self.system_message = system_message # 设置系统消息self.model = model # 设置聊天模型self.prefix = f"{self.name}: " # 设置消息前缀,用于标识消息来源self.reset() # 调用reset方法初始化消息历史# reset方法,用于重置或初始化消息历史def reset(self): self.message_history = ["Here is the conversation so far."] # 初始化消息历史# send方法,用于生成并发送消息def send(self) -> str: """ Applies the chat model to the message history and returns the message string """ # 调用模型生成消息message = self.model( [ self.system_message, # 系统消息:背景HumanMessage(content="\n".join(self.message_history + [self.prefix])), # 人类消息(包含历史和前缀) ] ) #message = self.model( # "\n".join([ # str(self.system_message), # str(HumanMessage(content="\n".join(self.message_history + [self.prefix]))) # ]) #) #return message.content return message # 返回生成的消息# receive方法,用于接收并记录消息def receive(self, name: str, message: str) -> None: """ Concatenates message spoken by {name} into message history """ # 将接收的消息加入到消息历史中self.message_history.append(f"{name}: {message}")

DialogueSimulator クラス

DialogueSimulator クラスはデリゲートのリストを受け入れます。各ステップで、次の操作を実行します。

次のスピーカーを選択してください。次の発言者にメッセージを送信するよう呼びかけます。メッセージを他のすべてのブローカーにブロードキャストします。歩数カウンターを更新します。次のスピーカーの選択は任意の関数で実装できますが、この場合はエージェントを単純に反復処理します。

コードは次のとおりです。

 # 定义一个DialogueSimulator类来模拟对话class DialogueSimulator: # 初始化方法,用于设置类的基本属性def __init__( self, agents: List[DialogueAgent], # 代理列表,包含所有对话的参与者selection_function: Callable[[int, List[DialogueAgent]], int], # 选择下一个说话者的函数) -> None: self.agents = agents # 将传入的代理列表保存为实例变量self._step = 0 # 初始化步数为0 self.select_next_speaker = selection_function # 设置选择下一个说话者的函数# 重置方法,用于重置所有代理的状态def reset(self): for agent in self.agents: # 遍历每个代理agent.reset() # 调用每个代理的reset方法进行重置# 初始化对话的方法def inject(self, name: str, message: str): """ Initiates the conversation with a message from a specific agent """ for agent in self.agents: # 遍历每个代理agent.receive(name, message) # 让每个代理接收初始消息self._step += 1 # 增加步数计数# 进行一步对话的方法def step(self) -> tuple[str, str]: # 1. 选择下一个说话的代理speaker_idx = self.select_next_speaker(self._step, self.agents) # 使用选择函数选择代理speaker = self.agents[speaker_idx] # 获取选中的代理# 2. 让选中的代理发送消息message = speaker.send() # 获取代理发送的消息# 3. 让所有代理接收这条消息for receiver in self.agents: # 遍历所有代理receiver.receive(speaker.name, message) # 让每个代理接收消息# 4. 增加步数计数self._step += 1 # 更新步数# 返回说话代理的名字和消息内容return speaker.name, message

役割の定義

このコードでは、ストーリーまたはタスクに関する重要な情報を格納するための 4 つの変数が定義されています。

これら 4 つの変数は、ストーリーをさらに書き進めたり生成したりする際に基本的な情報を提供します。

 protagonist_name = "马小虎" storyteller_name = "神秘老人" quest = "找到传说中的七件神器。" word_limit = 50

1. `protagonist_name = "马小虎"`: この行は、主人公 (物語の主人公) の名前を「马小虎」と定義します。

2. `storyteller_name = "Mysterious Old Man"`: この行は、ストーリーテラー (物語の語り手) の名前を「Mysterious Old Man」と定義します。

3. `quest = "7 つの伝説の遺物を見つける。"`: この行は、主人公が完了する必要のあるタスクまたは冒険の目標を定義します。

4. `word_limit = 50`: この行は、タスクの単語制限を 50 語に定義します。課題に取り組むときは、焦点と簡潔さを維持するために単語数制限を設定します。

ストーリー背景説明

次のコードは主に、ダンジョン アドベンチャー ゲームの説明とプロンプトを生成するために使用されます。主人公 (変数 `protagonist_name` で定義) とストーリーテラー (変数 `storyteller_name` で定義) という 2 人の主要登場人物が存在します。コードの目的は、自然言語モデル (この場合は GPT-3.5 Turbo または「QianfanLLMEndpoint」と呼ばれるモデル) を通じて 2 つのロールの詳細な説明を生成することです。

 game_description = f"""这是一场地下城冒险游戏: {quest}.游戏中存在一名玩家: 主人公, {protagonist_name}.故事由故事的讲述者来描述, {storyteller_name}.""" player_descriptor_system_message = SystemMessage( content="你可以为这场地下城冒险游戏添加细节." ) #主人公提示词protagonist_specifier_prompt = [ player_descriptor_system_message, HumanMessage( content=f"""{game_description}请用创意的方式来描述主人公, {protagonist_name}, 描述字数不超过{word_limit} 个.并且说出主人公的名字, {protagonist_name}.除此之外不要添加其他信息.""" ), ] #llm 生成对主人公的描述protagonist_description = ChatOpenAI(model_name="gpt-3.5-turbo",temperature=1.0)( protagonist_specifier_prompt ).content #llm = QianfanLLMEndpoint( model="ChatGLM2-6B-32K", temperature = 1.0) #protagonist_description= llm.generate([str(protagonist_specifier_prompt)]) #故事讲述者提示词storyteller_specifier_prompt = [ player_descriptor_system_message, HumanMessage( content=f"""{game_description}请用创意的方式来描述故事讲述者, {storyteller_name}, 描述字数不超过{word_limit} 个.并且说出故事讲述者的名字, {storyteller_name}.除此之外不要添加其他信息.""" ), ] #llm 生成对故事描述者的描述storyteller_description = ChatOpenAI(model_name="gpt-3.5-turbo",temperature=1.0)( storyteller_specifier_prompt ).content #storyteller_description = llm.generate([str(storyteller_specifier_prompt)])

1. ゲームの説明を生成します。以前に定義した `quest`、`protagonist_name`、および `storyteller_name` 変数を使用して、完全なゲームの説明 (`game_description`) を作成します。

2. システム メッセージを作成する: `SystemMessage` というクラスを使用して、プレーヤーにゲームの詳細を追加するように促すプロンプト メッセージを生成します。

3. 主人公の説明を生成する:自然言語モデルと特定のプロンプト (`protagonist_specifier_prompt`) を使用して、主人公の説明 (`protagonist_description`) を生成します。

4. ストーリーテラーの説明を生成する:同様に、自然言語モデルと特定のプロンプト (`storyteller_specifier_prompt`) を使用して、ストーリーテラーの説明 (`storyteller_description`) を生成します。

確認のため、上記の情報を印刷します。

 print("Protagonist Description:") print(protagonist_description) print("Storyteller Description:") print(storyteller_description)

印刷内容:

 Protagonist Description:马小虎,一个年轻而勇敢的剑士,有着黑色的蓬松头发和剑刃一样锐利的眼神。 Storyteller Description:故事讲述者: 神秘老人,耄耋仙人。

主人公とダンジョンマスターへのシステムメッセージ

このコードは、ダンジョン クローラー ゲームの主人公 (`protagonist_name`) のより具体的で詳細なクエストの説明 (`specified_quest`) を生成します。

 # 定义一个名为quest_specifier_prompt 的列表,包含SystemMessage 和HumanMessage 对象quest_specifier_prompt = [ # 系统消息,提示可以使任务更具体SystemMessage(content="你可以使任务更具体。"), # 人类消息,要求故事讲述者更具体地描述任务HumanMessage( content=f"""{game_description}你是故事讲述者,{storyteller_name}。请使任务更具体化。请富有创意和想象力。请用{word_limit}个词或更少回复指定的任务。直接对主角{protagonist_name}说话。不要添加其他任何内容。""" ), ] specified_quest = ChatOpenAI(model_name='gpt-3.5-turbo',temperature=1.0)(quest_specifier_prompt).content #specified_quest = llm.generate([str(quest_specifier_prompt)]) print(f"原始任务描述:\n{quest}\n") print(f"详细任务描述:\n{specified_quest}\n")

1. タスク指定プロンプト (`quest_specifier_prompt`) を定義します** :このリストには、`SystemMessage` と `HumanMessage` の 2 種類のメッセージ オブジェクトが含まれています。 `SystemMessage` は、タスクをより具体的にできることを知らせる簡単なリマインダーを提供します。 `HumanMessage` は、現在のゲームの説明、ストーリーテラーの名前、タスクを具体的にする方法に関する要件など、詳細な指示を提供します。

2. 特定のタスク (`specified_quest`) を生成します以前に定義した `quest_specifier_prompt` と自然言語モデル (ここでは GPT-3.5 Turbo) を使用して、より具体的で詳細なタスクの説明を生成します。

3.*出力結果:最後に、コードは元のタスクの説明と、新しく生成されたより具体的なタスクの説明を出力します。

印刷結果は次のとおりです

 output原始任务描述:找到传说中的七件神器。详细任务描述:马小虎,你需要穿越一条幻想之河,进入寒冰之洞穴。在那里,你将遇到一只被诅咒的巨龙。唤醒它的心灵,获取神器第一件:冰霜之剑。完成任务,勇士。

ハハハ、この時点ですでに参加者(物語の語り手と主人公)がいて、それぞれの背景が用意され、タスクが生成されています。次はゲームの実行です。

メイン関数のエントリ

このコードの主な目的は、主人公とストーリーテラーの 2 つのキャラクターを含むインタラクティブなストーリーをシミュレートすることです。キャラクターは、事前に定義されたダイアログ シミュレーター (`DialogueSimulator`) 内で交互に対話します。

 #主人公protagonist = DialogueAgent( name=protagonist_name, system_message=protagonist_system_message, model=ChatOpenAI(model_name='gpt-3.5-turbo',temperature=0.2), #model = llm, ) #故事描述者storyteller = DialogueAgent( name=storyteller_name, system_message=storyteller_system_message, model=ChatOpenAI(model_name='gpt-3.5-turbo',temperature=0.2), #model = llm, ) #发言顺序:轮流发言def select_next_speaker(step: int, agents: List[DialogueAgent]) -> int: idx = step % len(agents) return idx max_iters = 12 n = 0 simulator = DialogueSimulator( agents=[storyteller, protagonist], selection_function=select_next_speaker ) simulator.reset() #故事描述者, 任务的描述simulator.inject(storyteller_name, specified_quest) print(f"({storyteller_name}): {specified_quest}") print("\n") while n < max_iters: name, message = simulator.step() print(f"({name}): {message}") print("\n") n += 1

1. キャラクターを初期化する: `DialogueAgent` クラスを使用して、名前、システム メッセージ、使用するモデル (ここでは GPT-3.5 Turbo) を含む 2 つの異なるキャラクターを作成します。

2. 話者選択機能: `select_next_speaker` 関数は、会話の中で次にどのキャラクターが話すかを決定するために使用されます。ここでは単純な順番交代メカニズムが使用されています。

3. 対話シミュレーション:役割のリストと話者を選択する関数を受け入れる `DialogueSimulator` クラスを使用して対話シミュレーターを作成します。

4. 初期タスクを挿入する: `simulator.inject()` メソッドを使用して、特定のタスクの説明 (`specified_quest`) をストーリーテラーの最初のスピーチとして挿入します。

5. ダイアログ ループ:ループでは、最大反復回数 (`max_iters`) に達するまで、キャラクターが交互に話します。

コードを実行すると、次の結果が表示されます。下の図に示すように、Ma Xiaohuと謎の老人の間のテキストゲームは順調に進んでいるようです。彼らの会話により、ファンタジーゲームの世界が明らかになります。

要約する

この記事では、大規模な言語モデルを適用する試みとして、AI テクノロジーを使用して簡単な単語ゲームを作成する方法を説明します。大規模な言語モデルを使用することで、著者は非常に複雑なゲーム コンテンツを生成し、想像力豊かなゲーム体験を提供することができます。この記事では、特にメモリや音声仕様などの側面を扱う場合の、ゲーム設計におけるモジュール性の重要性についても強調しています。これは、ゲーム開発における大規模言語モデルの応用を示すだけでなく、AI やゲームに興味のある人々にインスピレーションと経験を提供する、非常に興味深いプロジェクトです。

著者について

51CTO コミュニティ エディター兼シニア アーキテクトの Cui Hao 氏は、ソフトウェア開発とアーキテクチャで 18 年の経験があり、分散アーキテクチャでは 10 年の経験があります。


<<:  AIが人間の知能を超えるかどうかという疑問の答えがついに明らかに!李菲菲の弟子の新作は輪を破り、5万の合成データが人間の例を粉砕し、コーヒーを淹れる動作は超スムーズ

>>:  G7、先進的なAIシステムを開発する企業の行動規範に合意へ

ブログ    
ブログ    

推薦する

...

Daguan Data が自社開発の OCR と NLP 技術を統合し、インテリジェント RPA をリリース<

2019年7月26日、人工知能企業Daguan Dataは北京で「大道知建」をテーマにした製品発表...

国防総省は、今後数日間の出来事を予測するために人工知能を活用している。

海外メディアCNETによると、米軍はビッグデータと人工知能を活用して近い将来の出来事を予測しようとし...

...

人工知能を活用して機密情報を保護する 5 つの方法

研究者たちは、人工知能技術が機密情報のセキュリティを確保するための非常に優れたツールであることを発見...

MITは、ニューラルネットワークトレーニングのブラックボックスを自動的に覗くネットワーク解剖フレームワークを提案

MIT の新しいテクノロジーは、視覚データでトレーニングされたニューラル ネットワークの内部の仕組み...

シンプルで効果的な新しい敵対的攻撃手法により、人気の Android アプリの DL モデルが破られることに成功

現在、多くのディープラーニング モデルがモバイル アプリに組み込まれています。デバイス上で機械学習を...

...

人工知能による大量失業の懸念は根拠がない

[[256558]] AIが大量失業を引き起こすという懸念は根拠がない世界的な研究機関である羅漢研究...

...

深層強化学習入門: TensorFlow で初めてのゲーム AI を構築する

[[210667]]昨年、DeepMindのAlphaGoは世界囲碁チャンピオンのイ・セドルを4対1...

AIファースト戦略はどこから始まるのでしょうか?

[[393200]] [51CTO.com クイック翻訳]人工知能は企業に競争上の優位性をもたらし...

AlphaGo の最初のバグ: 囲碁アルゴリズムの最大の弱点は何でしょうか?

[[163852]]どれほど恐ろしいモンスターにも弱点はあります。なぜAlphaGoは皆を驚かせる...

「5つの一般的なアルゴリズム」分岐アルゴリズムとアイデアを図解で紹介

[[355166]]この記事はWeChatの公開アカウント「bigsai」から転載したもので、著者は...