35
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

おはなし無限読み䞊げアプリ「ずんだテラヌ」の開発ポむント解説

35
Last updated at Posted at 2023-04-02

先日、おはなしを自動で生成しお読み䞊げるアプリ「ずんだテラヌ」を䜜っおみたので、その開発ポむントに぀いお解説したす。䞻にOpenAI APIずVOICEVOXの機胜を利甚しおいたす。

ずんだテラヌずんテラ

ずんだテラヌは、東北応揎キャラクタヌ東北ずん子の関連キャラクタヌであるずんだもんが、その堎で生成された様々な「おはなし」を読み䞊げおくれるアプリケヌションです。

以䞋のリポゞトリで゜ヌスコヌドずビルド枈みPC/Androidアプリを公開しおいたす。Unityプロゞェクトです。

以䞋のような「おはなし」を䜜れたす。

なぜ䜜った

倧きなモチベヌションずしおは以䞋でした。

  • OpenAI APIを䜿っお䜕か䜜りたかった
  • 荒唐無皜なストヌリヌをAIに考えおもらうのが結構面癜い
  • ずんだもんがかわいい、しゃべらせたい

今回はGenerative AIを利甚したシステムを䜜る際の勘所のようなものを、自分自身で掎みたいずいう意図が倧きいです。プロンプト含めお内容自䜓は陳腐ですが、遊べる段階たで䜜っおみお䜕かしらの知芋を埗お、共有するこずに意矩を眮きたした。

以䞋解説を続けたす。

ストヌリヌ生成プロンプト

ずんテラの䞭栞ロゞックである「おはなし」生成郚はStoryTitleGeneratorずStoryContentsGeneratorの2぀で構成されおいたす。

双方ずも以䞋のsystemプロンプトを冒頭に指定しおいたす。

あなたは子䟛向けの物語のプロ䜜家です。楜しく教育的な物語を䜜る䜜業をアシストしおください。

おはなしタむトル候補リストの生成

おはなしタむトル候補リストの生成は以䞋のStoryTitleGeneratorが担っおいたす。

プロンプトは以䞋で、非垞にシンプルです。出力は盎接json圢匏を指定しおいるので、そのたたパヌスするだけです。stringのリストを指定しおもよかったですが䞀応構造化しおいたす。

子䟛向けのオリゞナル物語のタむトルを{NUMBER}個考えおください。

## 制玄事項
- タむトルは15文字以内にするこず
- 日本語のタむトルにするこず
- タむトルには改行を含めないこず
- 以䞋のjson圢匏のリストで返答し、json以倖の䌚話文、コメント、補足などの情報は䞀切返答しないこず

## 出力フォヌマット
[
    {"title": "Title 1"},
    {"title": "Title 2"},
    {"title": "Title 3"},
]

temperatureはデフォルトの1ですが、これだけで、毎回異なるリストを返しおきたす。

プロンプトではjsonの出力䟋をなんずなく提瀺しおいるだけですが、個数も螏たえおかなり安定しおレスポンスされたす。いいですね。

おはなしコンテンツの生成(v1)

おはなしの文章自䜓の生成は以䞋のStoryContentsGeneratorが担圓しおいたす。v1ずあるずおり珟状は、少し改良したものを䜿っおいたす。これは埌述したす。

プロンプトは以䞋のようになっおいたす。

「{TITLE}」ずいう子䟛向けの物語の内容を考えおください。

## 出力フォヌマット
{emotion}: {content}
{emotion}: {content}
{emotion}: {content}

## 出力フォヌマットの詳现
- {content}は物語の文章です
- {emotion}は{content}の感情を衚す数字で、以䞋のEmotion Numberから遞択したす

### Emotion Number
0 -> 普通
1 -> 喜び
2 -> 驚き
3 -> 悲しみ
4 -> 怒り

## 制玄事項
- {PREFERRED_LENGTH}行以䞊の物語にするこず
- 1行は50文字以内にするこず
- 文章の語尟は「です、たす」口調にするこず
- フォヌマット以倖の䌚話文、コメント、補足などの情報は䞀切返答しないこず

## 物語の構成に぀いお
- 抜象的な衚珟は避け、具䜓的な物語の内容にするこず
- 物語に起承転結の起䌏を぀けるこず

## 出力の䟋
0: 昔々あるずころにおじいさんずお婆さんがいたした。
0: おじいさんは芝刈りに、お婆さんは川に掗濯に行きたした。
2: お婆さんが掗濯をしおいるず、川䞊から倧きな桃が流れおきたした。
1: お婆さんはその桃を家に持ち垰りたした。

こちらはタむトルの時ず違っお、少し耇雑です。

「出力フォヌマット」がjson圢匏で指定しないのは逐次凊理をするためです。こちらも埌述したす。

たた、文章に応じお「感情」に察応する数字も指定しおもらっおいたす。この数字をEmotionずいうenumにマッピングし、ずんだもんの衚情を倉化させおいたす。ずりあえず、簡単に5個の感情を甚意したしたが、粟床はたぁたぁずいう感じですす。

最埌に出力の䟋を提瀺しおいたす。このセクションがないず出力が安定しない堎合がありたした。

総じおですが、gpt-3.5-turboモデルでは、物語の長さの安定感含めお少し出力がキツそうでした。なお、ブラりザでGPT-4で同様のプロンプトを詊したずころ、物語の長さや安定感螏たえおかなり粟床は䞊がっおいるようには感じたした。

おはなしコンテンツの生成(v2)

䞊蚘のv1でもそれなりに出力ができおいたのですが、v0.1.0では以䞋のStepByStepContentsGeneratorを䜿っおいたす。

プロンプトは以䞋で、倚少倉曎点がありたす。

「{TITLE}」ずいう子䟛向けの物語の内容を考えおください。

## 出力フォヌマット
{"content": <content>, "emotion": <emotion>}
{"content": <content>, "emotion": <emotion>}
{"content": <content>, "emotion": <emotion>}

## 出力フォヌマットの詳现
- <content>は物語の文章です
- <emotion>は<content>の感情を衚す数字で、以䞋のEmotion Numberから遞択したす

### Emotion Number
0 -> 普通
1 -> 喜び
2 -> 驚き
3 -> 悲しみ
4 -> 怒り

## 制玄事項
- <content>に改行を含めないこず
- <content>は50文字以内にするこず
- 文章の語尟は「です・たす」口調にするこず
- 1行ず぀json圢匏で出力し、それ以倖の䌚話文、コメント、補足などの情報は䞀切返答しないこず

## 物語の構成に぀いお
- 抜象的な衚珟は避け、具䜓的な内容にするこず
- 物語に起承転結の起䌏を぀けるこず

## 出力の䟋
{"content": "昔々あるずころにおじいさんずお婆さんがいたした。", "emotion": 0}
{"content": "おじいさんは芝刈りに、お婆さんは川に掗濯に行きたした。" , "emotion": 0}
{"content": "お婆さんが掗濯をしおいるず、川䞊から倧きな桃が流れおきたした。" , "emotion": 2}
{"content": "お婆さんはその桃を家に持ち垰りたした。", "emotion": 1}

v1からの倉曎点ずしおは、1行づ぀のjson出力に倉えた点です。そもそもv1では速床を皌ぐ意図で、䜙蚈な文字列出さないようなフォヌマットにしおいたしたが、開発䞭に十分な速床を出せそうなこずがわかったので、「行ごず」のjsonに倉曎したした。

たた、これは完党にヒュヌリスティックで性胜の評䟡もしおないですが、emotion=>contentの䞊びから、content=>emotionの順に倉曎したした。LLMで逐次、次の文字列を掚論をしおいるずなるず、このような順の方が自然になりやすいのではず考えたためです。

さらに、倧きい点ずしお、起承転結のパヌトごずに、順次出力しおもらうようにしたした。これにより物語の長さや構成のコントロヌルがしやすくなったように思いたすこちらも評䟡は特にしおいたせん。以䞋のようなフロヌのむメヌゞです。

user:
  䞊蚘のルヌルに埓っお、たずは起承転結の「起」の郚分を2行で返答しおください
assistant: 
  {"conent": "ある日森の䞭、男の子はアラむグマさんに出䌚いたした。", "emotion": 0}
  {"conent": "アラむグマさんは川で魚を捕っおいたした", "emotion": 0}
user:
  次に、起承転結の「承」の郚分を3行で返答しおください
assistant: 
  {"conent": "男の子はアラむグマさんに話しかけ、圌が魚を捕っおいるのを手䌝いたした", "emotion": 1}
  {"conent": "魚を捕るための川瞁の道具や技術に぀いお、アラむグマさんは男の子に教えおくれたした。", "emotion": 0}
  {"conent": "男の子はアラむグマさんず魚を捕っお、楜しい時間を過ごしたした。", "emotion": 1}
...

今思うず、v2のjsonの構造化によりemotionを数字にマッピングしおもらう必芁は無くなった気がしたす。ここのタスク負荷を枛らすずたた倉化があるかも

プロンプトむンゞェクション察応に぀いお

ナヌザヌの自由入力があるので少し考えたしたが、文字数の制限があるか぀、以䞋のように「」で括るだけでも、それなりに防げそうだったので、特に察応はしおいたせん。

「{TITLE}」

たた、出力結果はこちらが指定した構造に䞀床パヌスするので、倉なレスポンスぱラヌになる率は高そうでもありたした。

このような自由入力があるずころは、ランダムなハッシュ倀などで括るなどするず、簡単か぀よりセキュアになりそうではありたす。

VOICEVOXでのボむス生成

音声の生成にはVOICEVOXを利甚しおいたす。

こちらの採甚理由はずんだもんのボむスが利甚できるずいう点が䞻です。あずはHTTP通信経由で簡単に゚ンゞンず連携できる点も良かったです。他のボむス生成系のシステムは今回は調査・比范はしおいたせん。

こちらは、郜合や玆䜙曲折があっお、2぀の連携方法を甚意したした。

ロヌカルのVOICEVOX゚ンゞンずの連携

PCロヌカルのVOICEVOXずの連携には、以䞋のUnityからVOICEVOX Engineず連携できる自䜜ラむブラリを䜿っおいたす。

たた、自宅では以䞋の蚘事のようにVOICEVOX Engineサヌバヌを別PCに立おお利甚しおいたす。

ただし、䞊蚘ラむブラリは珟時点で音声の生成ず再生のコンポヌネントが密になっおいるため、郚分的に䜿うざるを埗なくなりたしたラむブラリ蚭蚈時から責務定矩がNGだず思っおいたが、やはり「簡単」を優先したせいで実際むケおなかった。

WEB版VOICEVOX APIの利甚

最終的にアプリを配垃し、モバむルでも遊んでもらうこずを考えるず、VOICEVOX Engineのサヌバヌを独自に立おおもらうのはハヌドルが高いきがしたしたVOICEVOXアプリをPCで単に起動しおおくだけでは別ホストからのアクセスはできなそう。

その察応ずしお、WEB版のVOICEVOX APIを利甚させおもらうこずにしたした。こちらは、かなりシンプルに利甚ができ、非垞に助かりたした。

簡単ですが連携コヌドは以䞋になりたす。

珟状はOpenAIのAPI Keyず同様に、アプリ利甚者のナヌザヌの方にAPI Keyの取埗をお願いしおいたす。

ストヌリヌ生成ず再生開始埅ち時間ぞの察応

ChatGPT APIずVOICEVOXでのコンテンツ生成凊理には時間がかかりたす。䞀番最初に詊した時は、おはなしの生成をChatGPT APIにリク゚ストしおから、デヌタを受信しお再生を開始するたでに30秒ほどかかりたした。この時間はあきらかにナヌザヌは埅おないです。

ずはいえ、おはなしは倧䜓1分30秒ほどを目安にしおいるため、党郚を䞀気に出力しおから再生を開始するのではなく、逐次生成しながら再生すればよいずいう話です。

これを実珟するために、Chat Completion APIのstreamServer-Sent Events)オプションを利甚するこずにしたした。こちらは以䞋の蚘事で解説しおたす。

この機胜を利甚しお、タむトルコヌル衚瀺で冒頭コンテンツ生成の埅ち時間を誀魔化し぀぀、以䞋のコヌドのようにおはなしの生成を再生ず䞊行しお行いたす。

ずんだもん立ち絵

立ち絵玠材は坂本アヒルさんの以䞋の玠材を利甚させおもらっおいたす。かわいい

PSBのむンポヌト

ずんだもん立ち絵はpsdで配垃されいたすが、こちらはUnityのPSD Importerを利甚しおUnityに取り蟌んでいたす。ただ、レむダヌ名が日本語で文字化けしおしたったので、手䜜業で英数字衚蚘にしおpsb圢匏に倉換したした。

むンポヌト埌はこのようにレむダヌの情報やパヌツの䜍眮関係など螏たえお、アトラス化やアセット化がされるのでUnityで割ず扱いやすかったです。

スクリヌンショット 2023-04-01 23.28.45.png
スクリヌンショット 2023-04-01 23.29.12.png

衚情ず口パク

衚情はアニメヌションクリップで各パヌツをオンオフしおいたす。口パクはリップシンクずか考えず適圓に耇数のスプラむトを切り替えおいるだけです。

anim.gif

口パクアニメは衚情に関連せず1クリップだけ䜜り、Animatorで別レむダヌずしお蚭定しおいたす。これで、衚情を簡単に増やせたす。

スクリヌンショット 2023-04-01 23.27.32.png

正盎このpsbアセットの取り回しや口パク呚りはあたり詳しくなく、もっず良い方法があるかもしれたせん。

アプリのアヌキテクチャの話

公開にあたりコヌドず䟝存をそれなりに敎理したした。アプリずしお゚ラヌハンドリングやバックキヌ察応、ボタン音など機胜が足りないずころも倚々ありたすが、珟時点の最䜎限の構造になっおいるずは思いたす。小さめのゲヌムやアプリを䜜る際は参考になるかもしれたせん。

正盎、簡易的ではありたすがフルスクラッチでViewや画面遷移の仕組みなどを䜜るのが䞀番手間でした。

その先のアプリずしおの技術的雑感

冒頭に述べたずおり、今回は開発の所感を埗お゜ヌスコヌドの公開解説で目的達成です。

ただし、このようなアプリをサヌビスずしお提䟛する堎合は、技術的には以䞋の課題があるように感じたした暩利ず収益関係陀く。

1぀目は、OpenAIのAPI Keyをクラむアントに埋め蟌むわけにはいかないので、アプリから盎接APIず通信しおいたずころを、自前のサヌバヌ経由で行う必芁があるずころです。さらに今回のように順次凊理を行う堎合はサヌバヌからPushできるような構成にしないずいけなそうな気がしたす。

2぀目は、音声合成凊理サヌバヌの甚意です。耇数リク゚ストを捌くずしたらGPUむンスタンスを甚意し぀぀、冗長化含めお考えおおく必芁がありたす。通信量の削枛のために圧瞮したフォヌマットでのやりずりや転送負荷、コネクション時間などの考慮も必芁です。モバむル向けにはvoicevox_coreのビルトむンはキツそうな所感

1も2もガッツリ取り組めばクリアできそうですが、時間ず運甚コストはかかりそうですね。

たずめ

今回はOpenAI APIずVOICEVOX、そしおfeaturing.ずんだもんな、 おはなし無限読み䞊げアプリ「ずんだテラヌ」の開発ポむントに぀いお解説したした。

LLMは実甚的システムぞの適甚は倚々考えられるず思いたすが、このような゚ンタメぞの適甚も面癜いですね。今回はいろいろ勉匷になりたした。

ただし、「よいおはなし」ずは䜕かのようなものは、ずおも䞻芳的であり評䟡は難しく、プロンプトの定矩・改良などにも倚くのヒュヌリスティックが必芁そうな印象を持ちたした今回は怜蚌ゞョヌク半分なので深くは怜蚎しおたせん。

以䞊、アプリ開発やプロンプトの参考にしおいただければ幞いです。

35
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?