📖

AI物語作成ツール: Narrative Conversationを作った

に公開

はじめに

AIを使って、物語を作ったり、なりきって会話したり、指示出したり編集したり、ゲームブックやTRPGのように遊んだりできるアプリケーションを作りました。

既存の物語ツールは、日本語非対応だったり、超パワーユーザー向けで難解だったりするので、極力簡単に使えることを目指しました。

通常のチャットAIでは難しい、物語の途中編集や分岐、差し替えなども簡単に行えます。
初心者でも使いやすく、一方で上級者向けの細かいカスタマイズもできるように設計されています。

生成ボタンを連打して紡ぎ出される物語を楽しんでも良し、ナレーションをぶち込んでキャラクターを翻弄しても良し、キャラクターの一人になりきって参加しても良し、ダイスロールを回しても良し。

https://github.com/gpsnmeajp/NarrativeConversation

何ができるの

OpenAI互換のAPIを使って、AIに物語を作成させることができます。
(推奨はOpenRouterです)

  • 世界観設定やキャラクターを個別に定義できる他、発言や文ごとに、分離して管理されており遡っての1エントリごとの修正ができます。
  • 任意の地点で物語を分岐させることもできます。
  • 無駄にアニメーション機能とか、Webhook連携機能もあるので、外部ツールや機器と連動したインタラクティブな体験にすることもできます。

コアコンセプト

AIに直接的にキャラクターとかをやらせると、依存防止とか倫理配慮の影響で、制約が強い。

一方で、AIに小説の執筆者とかをやらせると、提案やらなんやら余計なものがついてくる。
しかも、書き換えたり修正したりとかもやりづらい。

そこで、以下のようなXMLをAIに吐かせることを考えました。

<narration>夕焼けが空を赤く染めていた。</narration>
<narration>アリスはボブから「キャロルが裏切り者である」ということを知らされたところだった。</narration>
<action name="アリス">アリスは驚いて後ずさりした。</action>
<dialogue name="アリス">(そ、そんな...キャロルが...!?)  そんなこと、信じられないわ!</dialogue>
<dialogue name="ボブ">ああ、僕も信じたくない。でも、これが現実なんだ。</dialogue>

これをパースすれば、グラフィカルな画面で扱えます。

XMLはAI(言語モデル)にとって理解しやすい形式のひとつなので、精度よく処理されることが期待できますし、これを追記しながらシステムプロンプトに入れることで、マルチターン会話ではなく生成として処理できるので、柔軟になることが期待できました。

せっかくグラフィカルにやるなら、アニメーションもつけたいとか、ダイスロールできるようにしたいとか、欲張って色々搭載。

AIコーディング

今回、肩を骨折したこともあり、AIコーディングで作成することを目指し、99%のコード、95%のドキュメントがgithub copilotによる生成物です。
ひたすら音声指示によるコードレビューとディレクションをやりました。
コーディングでは、GPT-5とClaude Sonnet 4を中心に使っています。

約1週間でアイディアからリリースまでこぎつけました。

技術スタック

Pythonをバックエンド、HTML+Vanilla JSをフロントエンドとしています。

バックエンドに処理を起きたくない、という思いが今回あり、バックエンドは、フロントエンドでセキュリティ上できないファイルアクセスによる永続化や、通信の中継などをメインに実施。

フロントエンドに、AI生成~パース~データ管理のほとんどの処理を寄せました。

そのため、スマートフォンアプリなどに移植するときもバックエンドに作り込む処理はそこまで多くなくできるだろうと推測しています(予定はないですが)

一方で、ブラウザが起動してないと一切の処理ができないとか、複数ブラウザを開くと壊れるので排他制御が必要になったりとか、イケてないところも色々とあります。

内部構造とか

DeepWiki見てください。最近は下手にドキュメント作るよりわかりやすくてすごいですね...

https://deepwiki.com/gpsnmeajp/NarrativeConversation

苦労した点

  • 言語モデル(特にオープンウェイトのモデル)は、XMLを中途半端に欠損させるので、それを事前に修正する処理をいくつも入れたり、どうにもならないときに再生成する処理を入れたりしました。
  • スマホからも使いたいので、Tailscale経由でアクセスさせましたが、電車内とかでスマホがスリープに入ると、通信が切れて生成がやり直しになるので、バックエンドで再開できる仕組みを入れたりとか、ちょっと苦労しました。
  • few-shotが強すぎるとか、最初ユーザーに知らせるためのnoticeタグを用意したらそれを使いまくるとか、言語モデルを(しかも複数のモデルで)ちょうどよく誘導するプロンプトチューニングには結構苦労しました。
  • 画面デザインは、とりあえず作らせる分には素晴らしいものが出てくるのですが、細部がズレていたり、崩れたり、機能しないボタンが出てきたりと、細かい修正にかなりの時間を使いました。
  • リファクタリングさせたり、機能追加させるときに、既存のコードを異常な壊し方していく症状に結構困りました。AIコーディング、まだまだ気が抜けないですね。
  • 存在しない機能やコードのハルシネーションを、コードでもドキュメントでも起こすことに結構苦労しました。

結局ちゃんと動くものを責任をもって作りたいなら、一行一行を自分でレビューして行くのは必須ですね。 AIが事前にレビューしてくれないかなぁ。なんかそういう仕組みもある気がします。

便利なツール

CSSやJSの動きが壊れてるとき、GPT-5にdevtools mcpを渡すと、勝手にデバッグして勝手に直してくれます。CSSの知識があまりないので、これにはかなり助けられました。

https://developer.chrome.com/blog/chrome-devtools-mcp?hl=ja

Discussion