はじめに
物語を読む → ユーザーが次の行動を指示する → 新しい物語が生成される
みたいなゲームブック的なアプリをChatGPTで作れないかなと思って
ちょろっとしたアプリを作ったので、今後似たようなものを作りたい人の参考になればと思ってここに残します。
なお、この記事はベストプラクティス的なものではなく「こうやりました」という結果を中心に記載したものになります。また、APIの使い方には触れず、プロンプトの作り方を中心に紹介しています。
どんなものを作ったのか
こんな感じで、1日の出来事をChatGPTに作らせて、次の日の行動をユーザーに入力させる
ということを5日間繰り返して1つの物語を作ることができるアプリです。
↓
アプリの場所
コストの問題がある+文章生成に時間がかかるのでアプリとしては公開してません。
ソースコードだけあるのでそれぞれでやってもらえれば。
https://github.com/TASKIH/five_days_to_mars
技術
OpenAI APIを使います。
接続のために以下のパッケージも使用しました。
https://github.com/openai/openai-node
APIの使い方等は特にこの記事では触れません。
工夫した点
生成した文章をすべてChatGPTに送ると、APIのトークンの上限に引っかかってしまうので、日ごとに「要約」させながら文章を圧縮しています。
簡単に言うと、
初日の文章を書かせる
↓
初日の文章を要約させる
↓
文章の要約とユーザーの行動を使って2日目の文章を書かせる
↓
要約と2日目の文章を使って要約させる
↓
文章の要約とユーザーの行動を使って3日目の文章を書かせる
というのを繰り返す感じになってます。
(もっと良い方法があるかもしれませんが検証していません)
要約の内容
「要約」がメモリの役割を果たしているので、ここから情報が抜けると後続の物語との連続性が喪われてしまうので、特に「登場人物」の情報(名前)を抜かさないように指示しています。
`【200文字以内の要約】以下の物語を要約せよ。それとは別にキャラクターの名前と行動を合計100字で記載せよ。\n過去のまとめ:${
novel.stories[day - 1].summaryOfWholeStory
}\n今日の出来事:${novel.stories[day].description}
以下の形式で記載せよ。
【過去のまとめ】:
【今日のまとめ】:
【登場人物の情報】:`
(これをやっても抜けることがたまにあります)
文章作成用のプロンプト
文字数がトークンの上限に抵触しないように、制約をかけながら欲しい文章を要求します。
制約は割と守られないので、少しずつ変更しながら良さそうなものを模索します。
今回はやっていませんが、ランダムで「宇宙人」「隕石」「故障」のようなお題を与えると、もっと良い物語が作られるかもしれません。
`【300文字以内の小説】地球から火星への5日間の航海の物語を作れ。まずは1日目のストーリーを書け。登場人物は4人でその中には${heroName}を含めよ。私「${heroName}」は
主人公であり物語の主役である。朝起きてから夜寝るまでの出来事を書け、その中でちょっとした事件を起こせ。
制約:ストーリーは主人公の一人称視点で「ですます」ではなく「である調」+「過去形」で書け。小説なので文中に文字数は書いてはならない。
推奨:乗組員の名前や行動は文中に積極的に書け。
1日目:`
物語に起伏をつけたいので、日ごとに少しずつ指示を変えます。
1日目:ちょっとした事件を起こせ
2日目:奇抜でかつやや大きな事件を起こせ
3日目:重大な事件を起こせ
4日目:問題を解決してはいけない。主人公に大きな決断を促せ
5日目:ミッションの成功または失敗のいずれかの結果を記載し、物語を完結させよ
2日目以降は、このプロンプトに過去の要約を渡します。
`ヒント:前日までの出来事のまとめは以下である。\n
${prevSummary}\n
5日目:`;
感じている課題
これで遊んでいるとすごい勢いでトークンが消費されていくので、(開発者的には)気軽に楽しめないというところが一番大きな課題ですね。。。
またResponseが返ってくるまでの時間が1分ぐらいかかるので、この辺も実運用するとなるとネックになりそうです。
まとめ
プロンプトを工夫することによって、ある程度望んでいたアプリをつくることができました。
他の多くのChatGPTを使ったアプリと同様にコストが課題になりますが、この辺も今後技術の進歩とともに解消されていくと思うので、もっと実用的なゲームアプリを作ることができそうです。
最後に上の方でも貼った物語の続きを貼って終わりにしたいと思います。
コーヒーをこぼしただけなのに