記憶を持つキャラクターとストーリーを生成するアプリをつくる

公開 更新

開発環境:Claude Code (Opus 5.5)

ゲームっぽいアプローチでローカルLLMとストーリーを作るアプリを作ってみました。

アプリの画面です。

きっかけ

今年4月にリリースされたGoogleのGemma 4 31Bの日本語能力が高かったため、文章やストーリーを作成するプログラムを作ったら面白いかもしれないと考えたのがきっかけです。

自己紹介になりますが、自分は文章を書くことがあまり上手くないし、大学生の頃から徐々に小説を読まなくなりストーリーものにも興味がなくなっていましたが、作る側の立場に立ってみると案外面白いのだとLLMの力を借りてあらためて気づきました。

ストーリーをつくることは自分には難しいが、ストーリーをつくる仕組みを作るのは楽しそうと以前から思っていたことを、ようやくLLMとエージェントの力で実現できるようになりました。

とりあえず最初はシンプルなものから始めようと思い、昔のテキストアドベンチャーゲームのようなものを題材に作らせてみることにしました。まずはストーリーのフローチャートをつくるところから始めてみました。想像力がないので、LLMの力を借りて「犬神家の一族のような遺産相続で殺人が起こるどろどろしたプロットをつくって!」と草案を作らせたところから始めました。

ストーリーのフローチャート。シーンがつながって構成されています。

各シーンの台本をノードとしてつなげ、ひとつの、あるいは分岐したストーリーを作っていきます。登場人物や場所を要素としてつくり、登場人物には記憶のアトリビュートを持たせて、ストーリーが進むごとに記憶や経験を蓄積し、人間関係もアップデートしていくようにします。この辺りはゲームプログラミングと同じですね。

エディタの流れ

キャラクターを作る

資料庫という場所をつくり、キャラクターや場所、設定資料などをまとめるページを作成します。

キャラクターを作成して保存します。
場所も設定する。

これらを使ってシーンを組み立てていきます。誰がどこで何をしたかを積み重ねることで、ひとつのストーリーになるという構造です。

シーンをつくる

シーンはノードとして作成し、その中で登場するキャラクターや場所を選び、出来事のテキスト(台本形式が望ましい)を記述します。すると、ローカルLLMがテキストを読み、出来事を細かく要素分けしたイベントを自動で作成してくれます。

シーンに台本のテキストを入れます。テキストからデータを抽出するのはLLMの仕事。

各キャラクターの記憶を追加していく

LLMがその時点での登場人物の視点で何が起きたかを理解し、各キャラクターに記憶を記録します。印象に残ったことは記憶に残りやすく、寝ていたり気絶していたりすれば記憶に残らないため、その人物は出来事を知らない状態になります。これにより、知らないことを語るような矛盾がなくなります。

各場面でどのような記憶が蓄積されたかを可視化しています。

この仕組みはその後のストーリー作りにも活かされます。たとえば「このシーンの後に続くシーンはどんなのがいいかな?」とLLMに聞けば、キャラクターの状態をもとに提案してくれます。この場面にキャラクターを集めてイベントを起こしたらどのような反応が起こるかという展開を楽しめるため、シミュレーターのように機能します。キャラクター同士の会話も面白いです。

関係図

シーンごとに、そのシーンまでのキャラクター同士の関係性を図にできます。

小説の文章をつくる

シーンを小説のように文章化する機能もつくりました。ここでGemma 4 31Bの力が発揮されます。

主人公視点で書かせた文章。

各シーンの出来事は小説調ではなく台本形式にしているのはこのためです。面白いのは、三人称で書かせることもできれば、特定の人物の一人称視点で同じ現象を書かせることもできるところです。文章にそのキャラクターの個性や背景が伝わっているのが面白い。ストーリーの文章は、台本を違うカメラから見たレンダリングなんだな、という感覚がありました。

エージェント機能をつくる

最初はエディタだけで満足していたのですが、使っているとやはり自分の才能のなさがボトルネックになることに気が付きます。文章作成のアシスト機能は手に入れたけれど、肝心のストーリーを思いつく才能がない。どちらかというと、パッとは思いつくものの即座に上手く文章化できず、まとめられない。この作業を補助してもらう機能(たとえば提案させてユーザーが選ぶなど)も必要だと思い、コーディングエージェントのような仕組みを作りました。VS Code拡張機能版のCodexやClaude Codeのようなインターフェイスで、中身をローカルLLMにしただけで、挙動はそっくりそのままにしています。エディタを触ることなく、エージェントとの会話でほとんどのことをできるようにしようという発想です。

Claude Codeと同じような挙動にしました。

必要なツールはエディタを作成したことでそろったため、それをLLMに使わせる仕組み(ハーネス)をつくっていきます。これにより、キャラクターや場面、シーンの新規作成・編集・削除などを相談しながら、LLMがユーザーの考えをまとめて管理してくれるようになりました。

ストーリーの矛盾を見つけたり、全体を調整したりする

ストーリーを読ませ、LLMにどの場面が全体や前後のシーンから見て矛盾しているかを指摘させる。修正箇所を決めたら、その部分だけでなく影響する前後関係も調整してくれる。

たとえば、あるキャラクターの性格を変えたら、その影響範囲をLLMが探し、逐一修正してくれる。イベントを入れ替えるレベルの変更をするとかなり広範囲に及ぶが、LLMが矛盾しそうな場所を探してはどんどん修正してくれる。これを繰り返してストーリーがバタフライエフェクトのように変わっていく様を眺めるのは結構楽しい。これはLLMならではで、手作業だとつらくてできない。

続きのシーンの作成や、間を補完するシーンの作成ももちろん可能です。ストーリー構築のシミュレーターですね。

登場人物と会話できる

これは最初、各キャラクターの記憶をチェックするデバッグ目的で作成しましたが、つくってみたらまあまあ面白かった。ストーリーが進むにつれてキャラクターに記憶が追加されていくので、あらかじめ決めておいたバックグラウンドや性格と、追加された記憶を元に会話ができる。「犯人は誰だと思う?」とか「最近気がかりなことは?」といった質問にわりと自然に答えてくれる。

人間関係の感情も値として調整する仕組みにしたので、複数のキャラクターを同時に配置すると、それぞれの個性と記憶をベースに会話してくれるし、仲が悪い人同士をチャットルームで会話させると険悪な空気になる。

とてもゲームっぽい。決められた台詞ではなく、その場で生成されているのがよいです。

その他

キャラクターや挿絵の画像

これはComfyUI経由で画像生成AIに作成させています。キャラクターやシーンの情報がすでにあるので、それらを元に適切なプロンプトをLLMに作成させています。モデルはKrea2に自作のイラスト画風のLoRAを組み合わせています。あまりAI臭さを消せておらず結果には満足していませんが、このあたりの話も今後書いていけたらいいですね。

まとめ

LLMとアプリの連携の方向性

今回の制作を通じて感じたのは、LLMを単なる「文章生成ツール」ではなく、アプリの内部構造を操作する「コントローラー」として組み込む可能性です。今回のようにLLMにAPIやツールを通じて直接エディタを操作させるエージェント形式にすると、ユーザーはUIの細かい操作から解放され、「何をしたいか」という意図に集中できるようになります。

今後のアプリは、複雑なメニューやボタンをユーザーに操作させるのではなく、LLMがユーザーの意図を汲み取って最適なデータ操作を行い、人間がそれをレビューして承認する共創的なインターフェースへとシフトしていくのではないかと感じています。

最後に

エージェント機能はかなり便利ですね。アプリのレベルが一段上がったように感じます。最近つくるアプリにはかならず入れるようになりました。なんでも自力でやってしまいがちな性格をしていますが、今年からはそのような気持ちを抑えて、どんな仕事でもまずはLLMに任せられるかを考える方向にシフトしています。(AIがすごくて頑張る気力がなくなった、というほうが正しいかもしれない・・)

今回も興味本位で作りました。物を書く仕事をしているわけではないので、これを何かに使って効率化することもないのですが、仕組み自体はいろんなことに応用できそうですね。

← 記事一覧へ